@@ -7978,6 +7978,14 @@ bool swift::diagnoseNonSendableFromDeinit(
79787978 refLoc, diag::non_sendable_from_deinit, var);
79797979}
79807980
7981+ std::optional<ActorIsolation> ProtocolConformance::getRawIsolation () const {
7982+ ASTContext &ctx = getDeclContext ()->getASTContext ();
7983+ auto conformance = const_cast <ProtocolConformance *>(this );
7984+ return evaluateOrDefault (
7985+ ctx.evaluator , RawConformanceIsolationRequest{conformance},
7986+ ActorIsolation ());
7987+ }
7988+
79817989ActorIsolation ProtocolConformance::getIsolation () const {
79827990 ASTContext &ctx = getDeclContext ()->getASTContext ();
79837991 auto conformance = const_cast <ProtocolConformance *>(this );
@@ -7986,16 +7994,18 @@ ActorIsolation ProtocolConformance::getIsolation() const {
79867994 ActorIsolation ());
79877995}
79887996
7989- ActorIsolation
7990- ConformanceIsolationRequest::evaluate (Evaluator &evaluator, ProtocolConformance *conformance) const {
7997+ std::optional<ActorIsolation>
7998+ RawConformanceIsolationRequest::evaluate (
7999+ Evaluator &evaluator, ProtocolConformance *conformance
8000+ ) const {
79918001 // Only normal protocol conformances can be isolated.
79928002 auto rootNormal =
79938003 dyn_cast<NormalProtocolConformance>(conformance->getRootConformance ());
79948004 if (!rootNormal)
79958005 return ActorIsolation::forNonisolated (false );
79968006
79978007 if (conformance != rootNormal)
7998- return rootNormal->getIsolation ();
8008+ return rootNormal->getRawIsolation ();
79998009
80008010 // If the conformance is explicitly non-isolated, report that.
80018011 if (rootNormal->getOptions ().contains (ProtocolConformanceFlags::Nonisolated))
@@ -8045,9 +8055,15 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
80458055 if (rootNormal->isPreconcurrency ())
80468056 return ActorIsolation::forNonisolated (false );
80478057
8058+ return std::nullopt ;
8059+ }
80488060
8049- // Isolation inference rules follow. If we aren't inferring isolated conformances,
8050- // we're done.
8061+ ActorIsolation swift::inferConformanceIsolation (
8062+ NormalProtocolConformance *conformance, bool hasKnownIsolatedWitness) {
8063+ auto dc = conformance->getDeclContext ();
8064+ ASTContext &ctx = dc->getASTContext ();
8065+
8066+ // If we aren't inferring isolated conformances, we're done.
80518067 if (!ctx.LangOpts .hasFeature (Feature::InferIsolatedConformances))
80528068 return ActorIsolation::forNonisolated (false );
80538069
@@ -8065,6 +8081,12 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
80658081
80668082 // If all of the value witnesses are nonisolated, then we should not infer
80678083 // global actor isolation.
8084+ if (hasKnownIsolatedWitness) {
8085+ // The caller told us we have an isolated value witness, so infer
8086+ // the nominal isolation.
8087+ return nominalIsolation;
8088+ }
8089+
80688090 bool anyIsolatedWitness = false ;
80698091 auto protocol = conformance->getProtocol ();
80708092 for (auto requirement : protocol->getMembers ()) {
@@ -8093,6 +8115,29 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
80938115 return nominalIsolation;
80948116}
80958117
8118+ ActorIsolation
8119+ ConformanceIsolationRequest::evaluate (
8120+ Evaluator &evaluator, ProtocolConformance *conformance
8121+ ) const {
8122+ // If there is raw isolation, use that.
8123+ if (auto rawIsolation = conformance->getRawIsolation ())
8124+ return *rawIsolation;
8125+
8126+ // Otherwise, we may infer isolation.
8127+
8128+ // Only normal protocol conformances can be isolated.
8129+ auto rootNormal =
8130+ dyn_cast<NormalProtocolConformance>(conformance->getRootConformance ());
8131+ if (!rootNormal)
8132+ return ActorIsolation::forNonisolated (false );
8133+
8134+ if (conformance != rootNormal)
8135+ return rootNormal->getIsolation ();
8136+
8137+ return inferConformanceIsolation (
8138+ rootNormal, /* hasKnownIsolatedWitness=*/ false );
8139+ }
8140+
80968141namespace {
80978142 // / Identifies isolated conformances whose isolation differs from the
80988143 // / context's isolation.
0 commit comments