@@ -10278,6 +10278,55 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
10278
10278
// have already been excluded.
10279
10279
llvm::SmallPtrSet<ValueDecl *, 2> excludedDynamicMembers;
10280
10280
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
+
10281
10330
// Local function that adds the given declaration if it is a
10282
10331
// reasonable choice.
10283
10332
auto addChoice = [&](OverloadChoice candidate) {
@@ -10304,6 +10353,12 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
10304
10353
auto baseTy = candidate.getBaseType();
10305
10354
const auto baseObjTy = baseTy->getRValueType();
10306
10355
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
+
10307
10362
bool hasInstanceMembers = false;
10308
10363
bool hasInstanceMethods = false;
10309
10364
bool hasStaticMembers = false;
@@ -10645,58 +10700,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
10645
10700
return OverloadChoice(baseTy, cand, functionRefInfo);
10646
10701
};
10647
10702
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
-
10700
10703
// Add all results from this lookup.
10701
10704
for (auto result : lookup)
10702
10705
addChoice(getOverloadChoice(result.getValueDecl(),
0 commit comments