@@ -7989,6 +7989,14 @@ bool swift::diagnoseNonSendableFromDeinit(
7989
7989
refLoc, diag::non_sendable_from_deinit, var);
7990
7990
}
7991
7991
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
+
7992
8000
ActorIsolation ProtocolConformance::getIsolation () const {
7993
8001
ASTContext &ctx = getDeclContext ()->getASTContext ();
7994
8002
auto conformance = const_cast <ProtocolConformance *>(this );
@@ -7997,16 +8005,18 @@ ActorIsolation ProtocolConformance::getIsolation() const {
7997
8005
ActorIsolation ());
7998
8006
}
7999
8007
8000
- ActorIsolation
8001
- ConformanceIsolationRequest::evaluate (Evaluator &evaluator, ProtocolConformance *conformance) const {
8008
+ std::optional<ActorIsolation>
8009
+ RawConformanceIsolationRequest::evaluate (
8010
+ Evaluator &evaluator, ProtocolConformance *conformance
8011
+ ) const {
8002
8012
// Only normal protocol conformances can be isolated.
8003
8013
auto rootNormal =
8004
8014
dyn_cast<NormalProtocolConformance>(conformance->getRootConformance ());
8005
8015
if (!rootNormal)
8006
8016
return ActorIsolation::forNonisolated (false );
8007
8017
8008
8018
if (conformance != rootNormal)
8009
- return rootNormal->getIsolation ();
8019
+ return rootNormal->getRawIsolation ();
8010
8020
8011
8021
// If the conformance is explicitly non-isolated, report that.
8012
8022
if (rootNormal->getOptions ().contains (ProtocolConformanceFlags::Nonisolated))
@@ -8056,9 +8066,15 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
8056
8066
if (rootNormal->isPreconcurrency ())
8057
8067
return ActorIsolation::forNonisolated (false );
8058
8068
8069
+ return std::nullopt ;
8070
+ }
8059
8071
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.
8062
8078
if (!ctx.LangOpts .hasFeature (Feature::InferIsolatedConformances))
8063
8079
return ActorIsolation::forNonisolated (false );
8064
8080
@@ -8076,6 +8092,12 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
8076
8092
8077
8093
// If all of the value witnesses are nonisolated, then we should not infer
8078
8094
// 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
+
8079
8101
bool anyIsolatedWitness = false ;
8080
8102
auto protocol = conformance->getProtocol ();
8081
8103
for (auto requirement : protocol->getMembers ()) {
@@ -8104,6 +8126,29 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
8104
8126
return nominalIsolation;
8105
8127
}
8106
8128
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
+
8107
8152
namespace {
8108
8153
// / Identifies isolated conformances whose isolation differs from the
8109
8154
// / context's isolation.
0 commit comments