From d586ffe2842e8910804e7aaa0bb779bba614c0e2 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Wed, 29 Nov 2023 17:01:38 -0800 Subject: [PATCH] [CSSimplify] InferSendableFromCaptures: Narrow member lookup delaying Avoid delaying if: - Base is a metatype because static methods are always Sendable (because metatype is Sendable) - Lookup doesn't have any methods (properties are un-affected by the inference changes). --- lib/Sema/CSSimplify.cpp | 68 ++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index e0768225fa5..04cd5c4c130 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -9532,34 +9532,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, } } - // Delay solving member constraint for unapplied methods - // where the base type has a conditional Sendable conformance - if (Context.LangOpts.hasFeature(Feature::InferSendableFromCaptures)) { - if (isPartialApplication(memberLocator)) { - auto sendableProtocol = Context.getProtocol(KnownProtocolKind::Sendable); - auto baseConformance = DC->getParentModule()->lookupConformance( - instanceTy, sendableProtocol); - - if (llvm::any_of( - baseConformance.getConditionalRequirements(), - [&](const auto &req) { - if (req.getKind() != RequirementKind::Conformance) - return false; - - if (auto protocolTy = - req.getSecondType()->template getAs()) { - return req.getFirstType()->hasTypeVariable() && - protocolTy->getDecl()->isSpecificProtocol( - KnownProtocolKind::Sendable); - } - return false; - })) { - result.OverallResult = MemberLookupResult::Unsolved; - return result; - } - } - } - // Okay, start building up the result list. result.OverallResult = MemberLookupResult::HasResults; @@ -10078,6 +10050,46 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, return OverloadChoice(baseTy, cand, functionRefKind); }; + // Delay solving member constraint for unapplied methods + // where the base type has a conditional Sendable conformance + if (Context.LangOpts.hasFeature(Feature::InferSendableFromCaptures)) { + auto shouldCheckSendabilityOfBase = [&]() { + // Static members are always sendable because they only capture + // metatypes which are Sendable. + if (baseObjTy->is()) + return false; + + return isPartialApplication(memberLocator) && + llvm::any_of(lookup, [&](const auto &result) { + return isa_and_nonnull(result.getValueDecl()); + }); + }; + + if (shouldCheckSendabilityOfBase()) { + auto sendableProtocol = Context.getProtocol(KnownProtocolKind::Sendable); + auto baseConformance = DC->getParentModule()->lookupConformance( + instanceTy, sendableProtocol); + + if (llvm::any_of( + baseConformance.getConditionalRequirements(), + [&](const auto &req) { + if (req.getKind() != RequirementKind::Conformance) + return false; + + if (auto protocolTy = + req.getSecondType()->template getAs()) { + return req.getFirstType()->hasTypeVariable() && + protocolTy->getDecl()->isSpecificProtocol( + KnownProtocolKind::Sendable); + } + return false; + })) { + result.OverallResult = MemberLookupResult::Unsolved; + return result; + } + } + } + // Add all results from this lookup. for (auto result : lookup) addChoice(getOverloadChoice(result.getValueDecl(),