Skip to content

Commit 12f02fd

Browse files
authored
Merge pull request #70109 from xedin/fixes-for-member-sendability-inference
[ConstraintSystem] A couple of fixes to Sendable inference on functions
2 parents e76c2c5 + d586ffe commit 12f02fd

File tree

3 files changed

+66
-29
lines changed

3 files changed

+66
-29
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9532,34 +9532,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
95329532
}
95339533
}
95349534

9535-
// Delay solving member constraint for unapplied methods
9536-
// where the base type has a conditional Sendable conformance
9537-
if (Context.LangOpts.hasFeature(Feature::InferSendableFromCaptures)) {
9538-
if (isPartialApplication(memberLocator)) {
9539-
auto sendableProtocol = Context.getProtocol(KnownProtocolKind::Sendable);
9540-
auto baseConformance = DC->getParentModule()->lookupConformance(
9541-
instanceTy, sendableProtocol);
9542-
9543-
if (llvm::any_of(
9544-
baseConformance.getConditionalRequirements(),
9545-
[&](const auto &req) {
9546-
if (req.getKind() != RequirementKind::Conformance)
9547-
return false;
9548-
9549-
if (auto protocolTy =
9550-
req.getSecondType()->template getAs<ProtocolType>()) {
9551-
return req.getFirstType()->hasTypeVariable() &&
9552-
protocolTy->getDecl()->isSpecificProtocol(
9553-
KnownProtocolKind::Sendable);
9554-
}
9555-
return false;
9556-
})) {
9557-
result.OverallResult = MemberLookupResult::Unsolved;
9558-
return result;
9559-
}
9560-
}
9561-
}
9562-
95639535
// Okay, start building up the result list.
95649536
result.OverallResult = MemberLookupResult::HasResults;
95659537

@@ -10078,6 +10050,46 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1007810050
return OverloadChoice(baseTy, cand, functionRefKind);
1007910051
};
1008010052

10053+
// Delay solving member constraint for unapplied methods
10054+
// where the base type has a conditional Sendable conformance
10055+
if (Context.LangOpts.hasFeature(Feature::InferSendableFromCaptures)) {
10056+
auto shouldCheckSendabilityOfBase = [&]() {
10057+
// Static members are always sendable because they only capture
10058+
// metatypes which are Sendable.
10059+
if (baseObjTy->is<AnyMetatypeType>())
10060+
return false;
10061+
10062+
return isPartialApplication(memberLocator) &&
10063+
llvm::any_of(lookup, [&](const auto &result) {
10064+
return isa_and_nonnull<FuncDecl>(result.getValueDecl());
10065+
});
10066+
};
10067+
10068+
if (shouldCheckSendabilityOfBase()) {
10069+
auto sendableProtocol = Context.getProtocol(KnownProtocolKind::Sendable);
10070+
auto baseConformance = DC->getParentModule()->lookupConformance(
10071+
instanceTy, sendableProtocol);
10072+
10073+
if (llvm::any_of(
10074+
baseConformance.getConditionalRequirements(),
10075+
[&](const auto &req) {
10076+
if (req.getKind() != RequirementKind::Conformance)
10077+
return false;
10078+
10079+
if (auto protocolTy =
10080+
req.getSecondType()->template getAs<ProtocolType>()) {
10081+
return req.getFirstType()->hasTypeVariable() &&
10082+
protocolTy->getDecl()->isSpecificProtocol(
10083+
KnownProtocolKind::Sendable);
10084+
}
10085+
return false;
10086+
})) {
10087+
result.OverallResult = MemberLookupResult::Unsolved;
10088+
return result;
10089+
}
10090+
}
10091+
}
10092+
1008110093
// Add all results from this lookup.
1008210094
for (auto result : lookup)
1008310095
addChoice(getOverloadChoice(result.getValueDecl(),

lib/Sema/ConstraintSystem.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2470,7 +2470,10 @@ bool ConstraintSystem::isPartialApplication(ConstraintLocator *locator) {
24702470

24712471
auto baseTy =
24722472
simplifyType(getType(UDE->getBase()))->getWithoutSpecifierType();
2473-
return getApplicationLevel(*this, baseTy, UDE) < 2;
2473+
auto level = getApplicationLevel(*this, baseTy, UDE);
2474+
// Static members have base applied implicitly which means that their
2475+
// application level is lower.
2476+
return level < (baseTy->is<MetatypeType>() ? 1 : 2);
24742477
}
24752478

24762479
DeclReferenceType

test/Concurrency/sendable_methods.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,25 @@ func generic3<T>(_ x: T) async {
206206

207207
await generic3(GenericS<NonSendable>.f)
208208
}
209+
210+
// Make sure that static members are handled properly
211+
do {
212+
struct X<T> {
213+
init(_: T) {
214+
}
215+
216+
static func test(_: T) {}
217+
}
218+
219+
class Test<T> {
220+
init(_: T) {
221+
_ = X(self) // Ok
222+
_ = X.init(self) // Ok
223+
_ = Optional.some(self) // Ok
224+
225+
let _: @Sendable (Int) -> X<Int> = X.init // Ok
226+
let _: @Sendable (Test<Int>) -> Void = X.test // Ok
227+
let _ = X.test(self) // Ok
228+
}
229+
}
230+
}

0 commit comments

Comments
 (0)