[CS] Add a 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 in `getNumApplications`. We ought to be
setting the correct FunctionRefKind and properly
handling the label matching in the solver though.
We also ought to consider changing FunctionRefKind
such that "is compound" is a separate bit from the
application level.

rdar://139234188
This commit is contained in:
Hamish Knight
2024-11-22 13:28:45 +00:00
parent 29f6f01a46
commit 746135b4d7
4 changed files with 48 additions and 8 deletions

View File

@@ -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

View File

@@ -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();
});
};

View File

@@ -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<LocatorPathElt::PatternMatch>()) {
if (auto *EP = dyn_cast<EnumElementPattern>(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<FunctionType>(), /*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<AbstractFunctionDecl>(value) || isa<EnumElementDecl>(value)) {
unsigned numApplies = getNumApplications(
value, hasAppliedSelf, functionRefKind);
value, hasAppliedSelf, functionRefKind, locator);
openedType = adjustFunctionTypeForConcurrency(
origOpenedType->castTo<FunctionType>(), 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<FunctionType>(), overload.getBaseType(), decl,

View File

@@ -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
}
}
}