@@ -3396,34 +3396,79 @@ static bool checkClassGlobalActorIsolation(
33963396 return true ;
33973397}
33983398
3399+ namespace {
3400+ // / Describes the result of checking override isolation.
3401+ enum class OverrideIsolationResult {
3402+ // / The override is permitted.
3403+ Allowed,
3404+ // / The override is permitted, but requires a Sendable check.
3405+ Sendable,
3406+ // / The override is not permitted.
3407+ Disallowed,
3408+ };
3409+ }
3410+
3411+ // / Return the isolation of the declaration overridden by this declaration,
3412+ // / in the context of the
3413+ static ActorIsolation getOverriddenIsolationFor (ValueDecl *value) {
3414+ auto overridden = value->getOverriddenDecl ();
3415+ assert (overridden && " Doesn't have an overridden declaration" );
3416+
3417+ auto isolation = getActorIsolation (overridden);
3418+ if (!isolation.requiresSubstitution ())
3419+ return isolation;
3420+
3421+ SubstitutionMap subs;
3422+ if (Type selfType = value->getDeclContext ()->getSelfInterfaceType ()) {
3423+ subs = selfType->getMemberSubstitutionMap (
3424+ value->getModuleContext (), overridden);
3425+ }
3426+ return isolation.subst (subs);
3427+ }
3428+
33993429// / Generally speaking, the isolation of the decl that overrides
34003430// / must match the overridden decl. But there are a number of exceptions,
34013431// / e.g., the decl that overrides can be nonisolated.
3402- // / \param newIso the isolation of the overriding declaration.
3403- static bool validOverrideIsolation (ActorIsolation newIso,
3404- ValueDecl *overriddenDecl,
3405- ActorIsolation overriddenIso) {
3406- // If the isolation matches, we're done.
3407- if (newIso == overriddenIso)
3408- return true ;
3409-
3410- // If the overriding declaration is non-isolated, it's okay.
3411- if (newIso.isIndependent () || newIso.isUnspecified ())
3412- return true ;
3432+ // / \param isolation the isolation of the overriding declaration.
3433+ static OverrideIsolationResult validOverrideIsolation (
3434+ ValueDecl *value, ActorIsolation isolation,
3435+ ValueDecl *overridden, ActorIsolation overriddenIsolation) {
3436+ ConcreteDeclRef valueRef (value);
3437+ auto declContext = value->getInnermostDeclContext ();
3438+ if (auto genericEnv = declContext->getGenericEnvironmentOfContext ()) {
3439+ valueRef = ConcreteDeclRef (
3440+ value, genericEnv->getForwardingSubstitutionMap ());
3441+ }
34133442
3414- // If both are actor-instance isolated, we're done. This wasn't caught by
3415- // the equality case above because the nominal type describing the actor
3416- // will differ when we're overriding.
3417- if (newIso.getKind () == overriddenIso.getKind () &&
3418- newIso.getKind () == ActorIsolation::ActorInstance)
3419- return true ;
3443+ auto refResult = ActorReferenceResult::forReference (
3444+ valueRef, SourceLoc (), declContext, None, None,
3445+ isolation, overriddenIsolation);
3446+ switch (refResult) {
3447+ case ActorReferenceResult::SameConcurrencyDomain:
3448+ return OverrideIsolationResult::Allowed;
3449+
3450+ case ActorReferenceResult::ExitsActorToNonisolated:
3451+ return OverrideIsolationResult::Sendable;
3452+
3453+ case ActorReferenceResult::EntersActor:
3454+ // It's okay to enter the actor when the overridden declaration is
3455+ // asynchronous (because it will do the switch) or is accessible from
3456+ // anywhere.
3457+ if (isAsyncDecl (overridden) ||
3458+ isAccessibleAcrossActors (
3459+ overridden, refResult.isolation , declContext)) {
3460+ // FIXME: Perform Sendable checking here because we're entering an
3461+ // actor.
3462+ return OverrideIsolationResult::Allowed;
3463+ }
34203464
3421- // If the overridden declaration is from Objective-C with no actor annotation,
3422- // allow it.
3423- if (overriddenDecl ->hasClangNode () && !overriddenIso )
3424- return true ;
3465+ // If the overridden declaration is from Objective-C with no actor
3466+ // annotation, allow it.
3467+ if (overridden ->hasClangNode () && !overriddenIsolation )
3468+ return OverrideIsolationResult::Allowed ;
34253469
3426- return false ;
3470+ return OverrideIsolationResult::Disallowed;
3471+ }
34273472}
34283473
34293474ActorIsolation ActorIsolationRequest::evaluate (
@@ -3485,20 +3530,11 @@ ActorIsolation ActorIsolationRequest::evaluate(
34853530
34863531 // Look for and remember the overridden declaration's isolation.
34873532 Optional<ActorIsolation> overriddenIso;
3488- ValueDecl *overriddenValue = nullptr ;
3489- if ( (overriddenValue = value->getOverriddenDecl ()) ) {
3490- auto iso = getActorIsolation (overriddenValue);
3491- SubstitutionMap subs;
3492-
3493- if (Type selfType = value->getDeclContext ()->getSelfInterfaceType ()) {
3494- subs = selfType->getMemberSubstitutionMap (
3495- value->getModuleContext (), overriddenValue);
3496- }
3497- iso = iso.subst (subs);
3498-
3533+ ValueDecl *overriddenValue = value->getOverriddenDecl ();
3534+ if (overriddenValue) {
34993535 // use the overridden decl's iso as the default isolation for this decl.
3500- defaultIsolation = iso ;
3501- overriddenIso = iso ;
3536+ defaultIsolation = getOverriddenIsolationFor (value) ;
3537+ overriddenIso = defaultIsolation ;
35023538 }
35033539
35043540 // Function used when returning an inferred isolation.
@@ -3509,8 +3545,16 @@ ActorIsolation ActorIsolationRequest::evaluate(
35093545 if (overriddenValue) {
35103546 // if the inferred isolation is not valid, then carry-over the overridden
35113547 // declaration's isolation as this decl's inferred isolation.
3512- if (!validOverrideIsolation (inferred, overriddenValue, *overriddenIso))
3548+ switch (validOverrideIsolation (
3549+ value, inferred, overriddenValue, *overriddenIso)) {
3550+ case OverrideIsolationResult::Allowed:
3551+ case OverrideIsolationResult::Sendable:
3552+ break ;
3553+
3554+ case OverrideIsolationResult::Disallowed:
35133555 inferred = *overriddenIso;
3556+ break ;
3557+ }
35143558 }
35153559
35163560 // Add an implicit attribute to capture the actor isolation that was
@@ -3779,29 +3823,36 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
37793823 if (!overridden)
37803824 return ;
37813825
3782- // Determine the actor isolation of this declaration .
3826+ // Determine the actor isolation of the overriding function .
37833827 auto isolation = getActorIsolation (value);
3828+
3829+ // Determine the actor isolation of the overridden function.
3830+ auto overriddenIsolation = getOverriddenIsolationFor (value);
3831+ switch (validOverrideIsolation (
3832+ value, isolation, overridden, overriddenIsolation)) {
3833+ case OverrideIsolationResult::Allowed:
3834+ return ;
37843835
3785- // Determine the actor isolation of the overridden function.=
3786- auto overriddenIsolation = getActorIsolation (overridden);
3787-
3788- if (overriddenIsolation.requiresSubstitution ()) {
3789- SubstitutionMap subs;
3790- if (Type selfType = value->getDeclContext ()->getSelfInterfaceType ()) {
3791- subs = selfType->getMemberSubstitutionMap (
3792- value->getModuleContext (), overridden);
3793- }
3836+ case OverrideIsolationResult::Sendable:
3837+ // FIXME: Do the Sendable check.
3838+ return ;
37943839
3795- overriddenIsolation = overriddenIsolation.subst (subs);
3840+ case OverrideIsolationResult::Disallowed:
3841+ // Diagnose below.
3842+ break ;
37963843 }
37973844
3798- if (validOverrideIsolation (isolation, overridden, overriddenIsolation))
3799- return ;
3800-
38013845 // Isolation mismatch. Diagnose it.
3846+ DiagnosticBehavior behavior = DiagnosticBehavior::Unspecified;
3847+ if (overridden->hasClangNode () && !overriddenIsolation) {
3848+ behavior = SendableCheckContext (value->getInnermostDeclContext ())
3849+ .defaultDiagnosticBehavior ();
3850+ }
3851+
38023852 value->diagnose (
38033853 diag::actor_isolation_override_mismatch, isolation,
3804- value->getDescriptiveKind (), value->getName (), overriddenIsolation);
3854+ value->getDescriptiveKind (), value->getName (), overriddenIsolation)
3855+ .limitBehavior (behavior);
38053856 overridden->diagnose (diag::overridden_here);
38063857}
38073858
@@ -4796,14 +4847,6 @@ ActorReferenceResult ActorReferenceResult::forExitsActorToNonisolated(
47964847 return ActorReferenceResult{ExitsActorToNonisolated, None, isolation};
47974848}
47984849
4799- ActorReferenceResult ActorReferenceResult::forReference (
4800- ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
4801- Optional<VarRefUseEnv> useKind,
4802- Optional<ReferencedActor> actorInstance) {
4803- return forReference (declRef, declRefLoc, fromDC, useKind, actorInstance,
4804- getInnermostIsolatedContext (fromDC));
4805- }
4806-
48074850// Determine if two actor isolation contexts are considered to be equivalent.
48084851static bool equivalentIsolationContexts (
48094852 const ActorIsolation &lhs, const ActorIsolation &rhs) {
@@ -4822,11 +4865,26 @@ ActorReferenceResult ActorReferenceResult::forReference(
48224865 ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
48234866 Optional<VarRefUseEnv> useKind,
48244867 Optional<ReferencedActor> actorInstance,
4825- ActorIsolation contextIsolation) {
4826- // Compute the isolation of the declaration, adjusted for references.
4827- auto declIsolation = getActorIsolationForReference (declRef.getDecl (), fromDC);
4828- if (auto subs = declRef.getSubstitutions ())
4829- declIsolation = declIsolation.subst (subs);
4868+ Optional<ActorIsolation> knownDeclIsolation,
4869+ Optional<ActorIsolation> knownContextIsolation) {
4870+ // If not provided, compute the isolation of the declaration, adjusted
4871+ // for references.
4872+ ActorIsolation declIsolation = ActorIsolation::forUnspecified ();
4873+ if (knownDeclIsolation) {
4874+ declIsolation = *knownDeclIsolation;
4875+ } else {
4876+ declIsolation = getActorIsolationForReference (declRef.getDecl (), fromDC);
4877+ if (declIsolation.requiresSubstitution ())
4878+ declIsolation = declIsolation.subst (declRef.getSubstitutions ());
4879+ }
4880+
4881+ // Compute the isolation of the context, if not provided.
4882+ ActorIsolation contextIsolation = ActorIsolation::forUnspecified ();
4883+ if (knownContextIsolation) {
4884+ contextIsolation = *knownContextIsolation;
4885+ } else {
4886+ contextIsolation = getInnermostIsolatedContext (fromDC);
4887+ }
48304888
48314889 // When the declaration is not actor-isolated, it can always be accessed
48324890 // directly.
0 commit comments