@@ -7954,6 +7954,14 @@ bool swift::diagnoseNonSendableFromDeinit(
79547954 var->getDescriptiveKind (), var->getName ());
79557955}
79567956
7957+ std::optional<ActorIsolation> ProtocolConformance::getRawIsolation () const {
7958+ ASTContext &ctx = getDeclContext ()->getASTContext ();
7959+ auto conformance = const_cast <ProtocolConformance *>(this );
7960+ return evaluateOrDefault (
7961+ ctx.evaluator , RawConformanceIsolationRequest{conformance},
7962+ ActorIsolation ());
7963+ }
7964+
79577965ActorIsolation ProtocolConformance::getIsolation () const {
79587966 ASTContext &ctx = getDeclContext ()->getASTContext ();
79597967 auto conformance = const_cast <ProtocolConformance *>(this );
@@ -7962,16 +7970,18 @@ ActorIsolation ProtocolConformance::getIsolation() const {
79627970 ActorIsolation ());
79637971}
79647972
7965- ActorIsolation
7966- ConformanceIsolationRequest::evaluate (Evaluator &evaluator, ProtocolConformance *conformance) const {
7973+ std::optional<ActorIsolation>
7974+ RawConformanceIsolationRequest::evaluate (
7975+ Evaluator &evaluator, ProtocolConformance *conformance
7976+ ) const {
79677977 // Only normal protocol conformances can be isolated.
79687978 auto rootNormal =
79697979 dyn_cast<NormalProtocolConformance>(conformance->getRootConformance ());
79707980 if (!rootNormal)
79717981 return ActorIsolation::forNonisolated (false );
79727982
79737983 if (conformance != rootNormal)
7974- return rootNormal->getIsolation ();
7984+ return rootNormal->getRawIsolation ();
79757985
79767986 // If the conformance is explicitly non-isolated, report that.
79777987 if (rootNormal->getOptions ().contains (ProtocolConformanceFlags::Nonisolated))
@@ -8021,9 +8031,15 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
80218031 if (rootNormal->isPreconcurrency ())
80228032 return ActorIsolation::forNonisolated (false );
80238033
8034+ return std::nullopt ;
8035+ }
80248036
8025- // Isolation inference rules follow. If we aren't inferring isolated conformances,
8026- // we're done.
8037+ ActorIsolation swift::inferConformanceIsolation (
8038+ NormalProtocolConformance *conformance, bool hasKnownIsolatedWitness) {
8039+ auto dc = conformance->getDeclContext ();
8040+ ASTContext &ctx = dc->getASTContext ();
8041+
8042+ // If we aren't inferring isolated conformances, we're done.
80278043 if (!ctx.LangOpts .hasFeature (Feature::InferIsolatedConformances))
80288044 return ActorIsolation::forNonisolated (false );
80298045
@@ -8041,6 +8057,12 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
80418057
80428058 // If all of the value witnesses are nonisolated, then we should not infer
80438059 // global actor isolation.
8060+ if (hasKnownIsolatedWitness) {
8061+ // The caller told us we have an isolated value witness, so infer
8062+ // the nominal isolation.
8063+ return nominalIsolation;
8064+ }
8065+
80448066 bool anyIsolatedWitness = false ;
80458067 auto protocol = conformance->getProtocol ();
80468068 for (auto requirement : protocol->getMembers ()) {
@@ -8069,6 +8091,29 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
80698091 return nominalIsolation;
80708092}
80718093
8094+ ActorIsolation
8095+ ConformanceIsolationRequest::evaluate (
8096+ Evaluator &evaluator, ProtocolConformance *conformance
8097+ ) const {
8098+ // If there is raw isolation, use that.
8099+ if (auto rawIsolation = conformance->getRawIsolation ())
8100+ return *rawIsolation;
8101+
8102+ // Otherwise, we may infer isolation.
8103+
8104+ // Only normal protocol conformances can be isolated.
8105+ auto rootNormal =
8106+ dyn_cast<NormalProtocolConformance>(conformance->getRootConformance ());
8107+ if (!rootNormal)
8108+ return ActorIsolation::forNonisolated (false );
8109+
8110+ if (conformance != rootNormal)
8111+ return rootNormal->getIsolation ();
8112+
8113+ return inferConformanceIsolation (
8114+ rootNormal, /* hasKnownIsolatedWitness=*/ false );
8115+ }
8116+
80728117namespace {
80738118 // / Identifies isolated conformances whose isolation differs from the
80748119 // / context's isolation.
0 commit comments