@@ -7989,6 +7989,14 @@ bool swift::diagnoseNonSendableFromDeinit(
79897989 refLoc, diag::non_sendable_from_deinit, var);
79907990}
79917991
7992+ std::optional<ActorIsolation> ProtocolConformance::getRawIsolation () const {
7993+ ASTContext &ctx = getDeclContext ()->getASTContext ();
7994+ auto conformance = const_cast <ProtocolConformance *>(this );
7995+ return evaluateOrDefault (
7996+ ctx.evaluator , RawConformanceIsolationRequest{conformance},
7997+ ActorIsolation ());
7998+ }
7999+
79928000ActorIsolation ProtocolConformance::getIsolation () const {
79938001 ASTContext &ctx = getDeclContext ()->getASTContext ();
79948002 auto conformance = const_cast <ProtocolConformance *>(this );
@@ -7997,16 +8005,18 @@ ActorIsolation ProtocolConformance::getIsolation() const {
79978005 ActorIsolation ());
79988006}
79998007
8000- ActorIsolation
8001- ConformanceIsolationRequest::evaluate (Evaluator &evaluator, ProtocolConformance *conformance) const {
8008+ std::optional<ActorIsolation>
8009+ RawConformanceIsolationRequest::evaluate (
8010+ Evaluator &evaluator, ProtocolConformance *conformance
8011+ ) const {
80028012 // Only normal protocol conformances can be isolated.
80038013 auto rootNormal =
80048014 dyn_cast<NormalProtocolConformance>(conformance->getRootConformance ());
80058015 if (!rootNormal)
80068016 return ActorIsolation::forNonisolated (false );
80078017
80088018 if (conformance != rootNormal)
8009- return rootNormal->getIsolation ();
8019+ return rootNormal->getRawIsolation ();
80108020
80118021 // If the conformance is explicitly non-isolated, report that.
80128022 if (rootNormal->getOptions ().contains (ProtocolConformanceFlags::Nonisolated))
@@ -8056,9 +8066,15 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
80568066 if (rootNormal->isPreconcurrency ())
80578067 return ActorIsolation::forNonisolated (false );
80588068
8069+ return std::nullopt ;
8070+ }
80598071
8060- // Isolation inference rules follow. If we aren't inferring isolated conformances,
8061- // we're done.
8072+ ActorIsolation swift::inferConformanceIsolation (
8073+ NormalProtocolConformance *conformance, bool hasKnownIsolatedWitness) {
8074+ auto dc = conformance->getDeclContext ();
8075+ ASTContext &ctx = dc->getASTContext ();
8076+
8077+ // If we aren't inferring isolated conformances, we're done.
80628078 if (!ctx.LangOpts .hasFeature (Feature::InferIsolatedConformances))
80638079 return ActorIsolation::forNonisolated (false );
80648080
@@ -8076,6 +8092,12 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
80768092
80778093 // If all of the value witnesses are nonisolated, then we should not infer
80788094 // global actor isolation.
8095+ if (hasKnownIsolatedWitness) {
8096+ // The caller told us we have an isolated value witness, so infer
8097+ // the nominal isolation.
8098+ return nominalIsolation;
8099+ }
8100+
80798101 bool anyIsolatedWitness = false ;
80808102 auto protocol = conformance->getProtocol ();
80818103 for (auto requirement : protocol->getMembers ()) {
@@ -8104,6 +8126,29 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
81048126 return nominalIsolation;
81058127}
81068128
8129+ ActorIsolation
8130+ ConformanceIsolationRequest::evaluate (
8131+ Evaluator &evaluator, ProtocolConformance *conformance
8132+ ) const {
8133+ // If there is raw isolation, use that.
8134+ if (auto rawIsolation = conformance->getRawIsolation ())
8135+ return *rawIsolation;
8136+
8137+ // Otherwise, we may infer isolation.
8138+
8139+ // Only normal protocol conformances can be isolated.
8140+ auto rootNormal =
8141+ dyn_cast<NormalProtocolConformance>(conformance->getRootConformance ());
8142+ if (!rootNormal)
8143+ return ActorIsolation::forNonisolated (false );
8144+
8145+ if (conformance != rootNormal)
8146+ return rootNormal->getIsolation ();
8147+
8148+ return inferConformanceIsolation (
8149+ rootNormal, /* hasKnownIsolatedWitness=*/ false );
8150+ }
8151+
81078152namespace {
81088153 // / Identifies isolated conformances whose isolation differs from the
81098154 // / context's isolation.
0 commit comments