@@ -7978,6 +7978,14 @@ bool swift::diagnoseNonSendableFromDeinit(
7978
7978
refLoc, diag::non_sendable_from_deinit, var);
7979
7979
}
7980
7980
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
+
7981
7989
ActorIsolation ProtocolConformance::getIsolation () const {
7982
7990
ASTContext &ctx = getDeclContext ()->getASTContext ();
7983
7991
auto conformance = const_cast <ProtocolConformance *>(this );
@@ -7986,16 +7994,18 @@ ActorIsolation ProtocolConformance::getIsolation() const {
7986
7994
ActorIsolation ());
7987
7995
}
7988
7996
7989
- ActorIsolation
7990
- ConformanceIsolationRequest::evaluate (Evaluator &evaluator, ProtocolConformance *conformance) const {
7997
+ std::optional<ActorIsolation>
7998
+ RawConformanceIsolationRequest::evaluate (
7999
+ Evaluator &evaluator, ProtocolConformance *conformance
8000
+ ) const {
7991
8001
// Only normal protocol conformances can be isolated.
7992
8002
auto rootNormal =
7993
8003
dyn_cast<NormalProtocolConformance>(conformance->getRootConformance ());
7994
8004
if (!rootNormal)
7995
8005
return ActorIsolation::forNonisolated (false );
7996
8006
7997
8007
if (conformance != rootNormal)
7998
- return rootNormal->getIsolation ();
8008
+ return rootNormal->getRawIsolation ();
7999
8009
8000
8010
// If the conformance is explicitly non-isolated, report that.
8001
8011
if (rootNormal->getOptions ().contains (ProtocolConformanceFlags::Nonisolated))
@@ -8045,9 +8055,15 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
8045
8055
if (rootNormal->isPreconcurrency ())
8046
8056
return ActorIsolation::forNonisolated (false );
8047
8057
8058
+ return std::nullopt ;
8059
+ }
8048
8060
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.
8051
8067
if (!ctx.LangOpts .hasFeature (Feature::InferIsolatedConformances))
8052
8068
return ActorIsolation::forNonisolated (false );
8053
8069
@@ -8065,6 +8081,12 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
8065
8081
8066
8082
// If all of the value witnesses are nonisolated, then we should not infer
8067
8083
// 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
+
8068
8090
bool anyIsolatedWitness = false ;
8069
8091
auto protocol = conformance->getProtocol ();
8070
8092
for (auto requirement : protocol->getMembers ()) {
@@ -8093,6 +8115,29 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
8093
8115
return nominalIsolation;
8094
8116
}
8095
8117
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
+
8096
8141
namespace {
8097
8142
// / Identifies isolated conformances whose isolation differs from the
8098
8143
// / context's isolation.
0 commit comments