Skip to content

Commit 24210cf

Browse files
authored
Merge pull request #83210 from xedin/rdar-143586718
[Concurrency] InferSendableFromCaptures: Rework check to delay lookup
2 parents cd7aa20 + 94e28b6 commit 24210cf

File tree

2 files changed

+61
-52
lines changed

2 files changed

+61
-52
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -10278,6 +10278,55 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1027810278
// have already been excluded.
1027910279
llvm::SmallPtrSet<ValueDecl *, 2> excludedDynamicMembers;
1028010280

10281+
// Delay solving member constraint for unapplied methods
10282+
// where the base type has a conditional Sendable conformance
10283+
auto shouldDelayDueToPartiallyResolvedBaseType =
10284+
[&](Type baseTy, ValueDecl *decl,
10285+
FunctionRefInfo functionRefInfo) -> bool {
10286+
if (!Context.LangOpts.hasFeature(Feature::InferSendableFromCaptures))
10287+
return false;
10288+
10289+
if (!Context.getProtocol(KnownProtocolKind::Sendable))
10290+
return false;
10291+
10292+
auto shouldCheckSendabilityOfBase = [&]() {
10293+
if (!isa_and_nonnull<FuncDecl>(decl))
10294+
return Type();
10295+
10296+
if (!decl->isInstanceMember() &&
10297+
!decl->getDeclContext()->getSelfProtocolDecl())
10298+
return Type();
10299+
10300+
auto hasAppliedSelf =
10301+
decl->hasCurriedSelf() && doesMemberRefApplyCurriedSelf(baseTy, decl);
10302+
auto numApplies = getNumApplications(hasAppliedSelf, functionRefInfo);
10303+
if (numApplies >= decl->getNumCurryLevels())
10304+
return Type();
10305+
10306+
return decl->isInstanceMember() ? baseTy->getMetatypeInstanceType()
10307+
: baseTy;
10308+
};
10309+
10310+
Type baseTyToCheck = shouldCheckSendabilityOfBase();
10311+
if (!baseTyToCheck)
10312+
return false;
10313+
10314+
auto sendableProtocol = Context.getProtocol(KnownProtocolKind::Sendable);
10315+
auto baseConformance = lookupConformance(baseTyToCheck, sendableProtocol);
10316+
10317+
return llvm::any_of(baseConformance.getConditionalRequirements(),
10318+
[&](const auto &req) {
10319+
if (req.getKind() != RequirementKind::Conformance)
10320+
return false;
10321+
10322+
return (req.getFirstType()->hasTypeVariable() &&
10323+
(req.getProtocolDecl()->isSpecificProtocol(
10324+
KnownProtocolKind::Sendable) ||
10325+
req.getProtocolDecl()->isSpecificProtocol(
10326+
KnownProtocolKind::SendableMetatype)));
10327+
});
10328+
};
10329+
1028110330
// Local function that adds the given declaration if it is a
1028210331
// reasonable choice.
1028310332
auto addChoice = [&](OverloadChoice candidate) {
@@ -10304,6 +10353,12 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1030410353
auto baseTy = candidate.getBaseType();
1030510354
const auto baseObjTy = baseTy->getRValueType();
1030610355

10356+
// If we need to delay, update the status but record the member.
10357+
if (shouldDelayDueToPartiallyResolvedBaseType(
10358+
baseObjTy, decl, candidate.getFunctionRefInfo())) {
10359+
result.OverallResult = MemberLookupResult::Unsolved;
10360+
}
10361+
1030710362
bool hasInstanceMembers = false;
1030810363
bool hasInstanceMethods = false;
1030910364
bool hasStaticMembers = false;
@@ -10645,58 +10700,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
1064510700
return OverloadChoice(baseTy, cand, functionRefInfo);
1064610701
};
1064710702

10648-
// Delay solving member constraint for unapplied methods
10649-
// where the base type has a conditional Sendable conformance
10650-
if (Context.LangOpts.hasFeature(Feature::InferSendableFromCaptures)) {
10651-
auto shouldCheckSendabilityOfBase = [&]() {
10652-
if (!Context.getProtocol(KnownProtocolKind::Sendable))
10653-
return Type();
10654-
10655-
for (const auto &result : lookup) {
10656-
auto decl = result.getValueDecl();
10657-
if (!isa_and_nonnull<FuncDecl>(decl))
10658-
continue;
10659-
10660-
if (!decl->isInstanceMember() &&
10661-
!decl->getDeclContext()->getSelfProtocolDecl())
10662-
continue;
10663-
10664-
auto hasAppliedSelf = decl->hasCurriedSelf() &&
10665-
doesMemberRefApplyCurriedSelf(baseObjTy, decl);
10666-
auto numApplies = getNumApplications(hasAppliedSelf, functionRefInfo);
10667-
if (numApplies >= decl->getNumCurryLevels())
10668-
continue;
10669-
10670-
return decl->isInstanceMember()
10671-
? instanceTy
10672-
: MetatypeType::get(instanceTy);
10673-
}
10674-
10675-
return Type();
10676-
};
10677-
10678-
if (Type baseTyToCheck = shouldCheckSendabilityOfBase()) {
10679-
auto sendableProtocol = Context.getProtocol(KnownProtocolKind::Sendable);
10680-
auto baseConformance = lookupConformance(baseTyToCheck, sendableProtocol);
10681-
10682-
if (llvm::any_of(
10683-
baseConformance.getConditionalRequirements(),
10684-
[&](const auto &req) {
10685-
if (req.getKind() != RequirementKind::Conformance)
10686-
return false;
10687-
10688-
return (req.getFirstType()->hasTypeVariable() &&
10689-
(req.getProtocolDecl()->isSpecificProtocol(
10690-
KnownProtocolKind::Sendable) ||
10691-
req.getProtocolDecl()->isSpecificProtocol(
10692-
KnownProtocolKind::SendableMetatype)));
10693-
})) {
10694-
result.OverallResult = MemberLookupResult::Unsolved;
10695-
return result;
10696-
}
10697-
}
10698-
}
10699-
1070010703
// Add all results from this lookup.
1070110704
for (auto result : lookup)
1070210705
addChoice(getOverloadChoice(result.getValueDecl(),
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 6
2+
3+
// rdar://143586718 - crash due to lookup not delayed on partially resolved base with Sendable requirements
4+
5+
_ = { () -> Array? in .max }
6+
// expected-error@-1 {{unable to infer closure type without a type annotation}}

0 commit comments

Comments
 (0)