Skip to content

Commit 05b0ada

Browse files
committed
[ConstraintSystem] Use getNumApplications + ValueDecl::getNumCurryLevels to detect partial applications
We used to detect partial applications based on member locators and parent expressions, but using function reference kind + check to see if self is applied is such simpler and hits both uses of `isPartialApplication`.
1 parent be0bf46 commit 05b0ada

File tree

4 files changed

+31
-13
lines changed

4 files changed

+31
-13
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6558,6 +6558,11 @@ Type getPatternTypeOfSingleUnlabeledPackExpansionTuple(Type type);
65586558
/// Check whether this is a reference to one of the special result builder
65596559
/// methods prefixed with `build*` i.e. `buildBlock`, `buildExpression` etc.
65606560
bool isResultBuilderMethodReference(ASTContext &, UnresolvedDotExpr *);
6561+
6562+
/// Determine the number of applications applied to the given overload.
6563+
unsigned getNumApplications(ValueDecl *decl, bool hasAppliedSelf,
6564+
FunctionRefKind functionRefKind);
6565+
65616566
} // end namespace constraints
65626567

65636568
template<typename ...Args>

lib/Sema/CSSimplify.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10293,15 +10293,16 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1029310293
if (!Context.getProtocol(KnownProtocolKind::Sendable))
1029410294
return false;
1029510295

10296-
// Static members are always sendable because they only capture
10297-
// metatypes which are Sendable.
10298-
if (baseObjTy->is<AnyMetatypeType>())
10299-
return false;
10296+
return llvm::any_of(lookup, [&](const auto &result) {
10297+
auto decl = result.getValueDecl();
10298+
if (!isa_and_nonnull<FuncDecl>(decl))
10299+
return false;
1030010300

10301-
return isPartialApplication(memberLocator) &&
10302-
llvm::any_of(lookup, [&](const auto &result) {
10303-
return isa_and_nonnull<FuncDecl>(result.getValueDecl());
10304-
});
10301+
auto hasAppliedSelf = decl->hasCurriedSelf() &&
10302+
doesMemberRefApplyCurriedSelf(baseObjTy, decl);
10303+
return getNumApplications(decl, hasAppliedSelf, functionRefKind) <
10304+
decl->getNumCurryLevels();
10305+
});
1030510306
};
1030610307

1030710308
if (shouldCheckSendabilityOfBase()) {
@@ -10945,7 +10946,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
1094510946

1094610947
return simplifyValueWitnessConstraint(
1094710948
ConstraintKind::ValueWitness, baseTy, makeIterator, memberTy, useDC,
10948-
FunctionRefKind::Compound, flags, locator);
10949+
FunctionRefKind::SingleApply, flags, locator);
1094910950
}
1095010951

1095110952
// Handle `next` reference.
@@ -10963,7 +10964,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
1096310964

1096410965
return simplifyValueWitnessConstraint(
1096510966
ConstraintKind::ValueWitness, baseTy, next, memberTy, useDC,
10966-
FunctionRefKind::Compound, flags, locator);
10967+
FunctionRefKind::SingleApply, flags, locator);
1096710968
}
1096810969
}
1096910970
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,8 +1655,8 @@ static unsigned getNumRemovedArgumentLabels(ValueDecl *decl,
16551655
}
16561656

16571657
/// Determine the number of applications
1658-
static unsigned getNumApplications(
1659-
ValueDecl *decl, bool hasAppliedSelf, FunctionRefKind functionRefKind) {
1658+
unsigned constraints::getNumApplications(ValueDecl *decl, bool hasAppliedSelf,
1659+
FunctionRefKind functionRefKind) {
16601660
switch (functionRefKind) {
16611661
case FunctionRefKind::Unapplied:
16621662
case FunctionRefKind::Compound:
@@ -1774,7 +1774,7 @@ FunctionType *ConstraintSystem::adjustFunctionTypeForConcurrency(
17741774
adjustedTy =
17751775
adjustedTy->withExtInfo(adjustedTy->getExtInfo().withSendable());
17761776
}
1777-
} else if (isPartialApplication(getConstraintLocator(locator))) {
1777+
} else if (numApplies < decl->getNumCurryLevels()) {
17781778
// Operators on protocols could be found via unqualified lookup and
17791779
// won't have a base type.
17801780
if (decl->isOperator() ||

test/Concurrency/sendable_methods.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,3 +294,15 @@ do {
294294

295295
test(<) // Ok
296296
}
297+
298+
// Partially applied instance method
299+
do {
300+
struct S {
301+
func foo() {}
302+
}
303+
304+
func bar(_ x: @Sendable () -> Void) {}
305+
306+
let fn = S.foo(S())
307+
bar(fn) // Ok
308+
}

0 commit comments

Comments
 (0)