Skip to content

Commit 041e76b

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 041e76b

File tree

4 files changed

+30
-13
lines changed

4 files changed

+30
-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: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10293,15 +10293,15 @@ 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 = doesMemberRefApplyCurriedSelf(baseObjTy, decl);
10302+
return getNumApplications(decl, hasAppliedSelf, functionRefKind) <
10303+
decl->getNumCurryLevels();
10304+
});
1030510305
};
1030610306

1030710307
if (shouldCheckSendabilityOfBase()) {
@@ -10945,7 +10945,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
1094510945

1094610946
return simplifyValueWitnessConstraint(
1094710947
ConstraintKind::ValueWitness, baseTy, makeIterator, memberTy, useDC,
10948-
FunctionRefKind::Compound, flags, locator);
10948+
FunctionRefKind::SingleApply, flags, locator);
1094910949
}
1095010950

1095110951
// Handle `next` reference.
@@ -10963,7 +10963,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
1096310963

1096410964
return simplifyValueWitnessConstraint(
1096510965
ConstraintKind::ValueWitness, baseTy, next, memberTy, useDC,
10966-
FunctionRefKind::Compound, flags, locator);
10966+
FunctionRefKind::SingleApply, flags, locator);
1096710967
}
1096810968
}
1096910969
}

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)