@@ -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(),
0 commit comments