diff --git a/include/swift/Sema/ConstraintSystem.h b/include/swift/Sema/ConstraintSystem.h index 499d13266572e..6c8cd6b2b0fec 100644 --- a/include/swift/Sema/ConstraintSystem.h +++ b/include/swift/Sema/ConstraintSystem.h @@ -6434,7 +6434,8 @@ bool isResultBuilderMethodReference(ASTContext &, UnresolvedDotExpr *); /// Determine the number of applications applied to the given overload. unsigned getNumApplications(ValueDecl *decl, bool hasAppliedSelf, - FunctionRefKind functionRefKind); + FunctionRefKind functionRefKind, + ConstraintLocatorBuilder locator); } // end namespace constraints diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 689f9859665de..7c843ee81c888 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -10153,8 +10153,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, auto hasAppliedSelf = decl->hasCurriedSelf() && doesMemberRefApplyCurriedSelf(baseObjTy, decl); - return getNumApplications(decl, hasAppliedSelf, functionRefKind) < - decl->getNumCurryLevels(); + return getNumApplications(decl, hasAppliedSelf, functionRefKind, + memberLocator) < decl->getNumCurryLevels(); }); }; diff --git a/lib/Sema/TypeOfReference.cpp b/lib/Sema/TypeOfReference.cpp index c47ec57b19e55..c6d21bd9af877 100644 --- a/lib/Sema/TypeOfReference.cpp +++ b/lib/Sema/TypeOfReference.cpp @@ -661,7 +661,20 @@ static unsigned getNumRemovedArgumentLabels(ValueDecl *decl, /// Determine the number of applications unsigned constraints::getNumApplications(ValueDecl *decl, bool hasAppliedSelf, - FunctionRefKind functionRefKind) { + FunctionRefKind functionRefKind, + ConstraintLocatorBuilder locator) { + // FIXME: Narrow hack for rdar://139234188 - Currently we set + // FunctionRefKind::Compound for enum element patterns with tuple + // sub-patterns to ensure the member has argument labels stripped. As such, + // we need to account for the correct application level here. We ought to be + // setting the correct FunctionRefKind and properly handling the label + // matching in the solver though. + if (auto lastElt = locator.last()) { + if (auto matchElt = lastElt->getAs()) { + if (auto *EP = dyn_cast(matchElt->getPattern())) + return (EP->hasSubPattern() ? 1 : 0) + hasAppliedSelf; + } + } switch (functionRefKind) { case FunctionRefKind::Unapplied: case FunctionRefKind::Compound: @@ -885,7 +898,8 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value, auto origOpenedType = openedType; if (!isRequirementOrWitness(locator)) { - unsigned numApplies = getNumApplications(value, false, functionRefKind); + unsigned numApplies = getNumApplications(value, false, functionRefKind, + locator); openedType = adjustFunctionTypeForConcurrency( origOpenedType, /*baseType=*/Type(), func, useDC, numApplies, false, replacements, locator); @@ -914,7 +928,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value, auto origOpenedType = openedType; if (!isRequirementOrWitness(locator)) { unsigned numApplies = getNumApplications( - funcDecl, false, functionRefKind); + funcDecl, false, functionRefKind, locator); openedType = adjustFunctionTypeForConcurrency( origOpenedType->castTo(), /*baseType=*/Type(), funcDecl, useDC, numApplies, false, replacements, locator); @@ -1657,7 +1671,7 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference( // Don't adjust when doing witness matching, because that can cause cycles. } else if (isa(value) || isa(value)) { unsigned numApplies = getNumApplications( - value, hasAppliedSelf, functionRefKind); + value, hasAppliedSelf, functionRefKind, locator); openedType = adjustFunctionTypeForConcurrency( origOpenedType->castTo(), resolvedBaseTy, value, useDC, numApplies, isMainDispatchQueueMember(locator), replacements, locator); @@ -1841,7 +1855,7 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator, auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(overload.getBaseType(), decl); unsigned numApplies = getNumApplications( - decl, hasAppliedSelf, overload.getFunctionRefKind()); + decl, hasAppliedSelf, overload.getFunctionRefKind(), locator); type = adjustFunctionTypeForConcurrency( type->castTo(), overload.getBaseType(), decl, diff --git a/test/Constraints/rdar139234188.swift b/test/Constraints/rdar139234188.swift new file mode 100644 index 0000000000000..fed082625e8a4 --- /dev/null +++ b/test/Constraints/rdar139234188.swift @@ -0,0 +1,25 @@ +// RUN: %target-swift-emit-silgen %s -verify -swift-version 6 + +struct S: Equatable { + static func foo() -> Self { fatalError() } + static func bar(_ x: Int) -> Self { fatalError() } + static func baz(x: Int, y: Int) -> Self { fatalError() } + public static func == (_: Self, _: Self) -> Bool { false } +} + +// rdar://139234188 - Make sure we don't consider these members to be partially +// applied for concurrency adjustment. +func foo(_ x: S) { + _ = { + switch x { + case .foo(): + break + case .bar(0): + break + case .baz(x: 1, y: 2): + break + default: + break + } + } +}