@@ -3428,34 +3428,79 @@ static bool checkClassGlobalActorIsolation(
34283428 return true ;
34293429}
34303430
3431+ namespace {
3432+ // / Describes the result of checking override isolation.
3433+ enum class OverrideIsolationResult {
3434+ // / The override is permitted.
3435+ Allowed,
3436+ // / The override is permitted, but requires a Sendable check.
3437+ Sendable,
3438+ // / The override is not permitted.
3439+ Disallowed,
3440+ };
3441+ }
3442+
3443+ // / Return the isolation of the declaration overridden by this declaration,
3444+ // / in the context of the
3445+ static ActorIsolation getOverriddenIsolationFor (ValueDecl *value) {
3446+ auto overridden = value->getOverriddenDecl ();
3447+ assert (overridden && " Doesn't have an overridden declaration" );
3448+
3449+ auto isolation = getActorIsolation (overridden);
3450+ if (!isolation.requiresSubstitution ())
3451+ return isolation;
3452+
3453+ SubstitutionMap subs;
3454+ if (Type selfType = value->getDeclContext ()->getSelfInterfaceType ()) {
3455+ subs = selfType->getMemberSubstitutionMap (
3456+ value->getModuleContext (), overridden);
3457+ }
3458+ return isolation.subst (subs);
3459+ }
3460+
34313461// / Generally speaking, the isolation of the decl that overrides
34323462// / must match the overridden decl. But there are a number of exceptions,
34333463// / e.g., the decl that overrides can be nonisolated.
3434- // / \param newIso the isolation of the overriding declaration.
3435- static bool validOverrideIsolation (ActorIsolation newIso,
3436- ValueDecl *overriddenDecl,
3437- ActorIsolation overriddenIso) {
3438- // If the isolation matches, we're done.
3439- if (newIso == overriddenIso)
3440- return true ;
3441-
3442- // If the overriding declaration is non-isolated, it's okay.
3443- if (newIso.isIndependent () || newIso.isUnspecified ())
3444- return true ;
3464+ // / \param isolation the isolation of the overriding declaration.
3465+ static OverrideIsolationResult validOverrideIsolation (
3466+ ValueDecl *value, ActorIsolation isolation,
3467+ ValueDecl *overridden, ActorIsolation overriddenIsolation) {
3468+ ConcreteDeclRef valueRef (value);
3469+ auto declContext = value->getInnermostDeclContext ();
3470+ if (auto genericEnv = declContext->getGenericEnvironmentOfContext ()) {
3471+ valueRef = ConcreteDeclRef (
3472+ value, genericEnv->getForwardingSubstitutionMap ());
3473+ }
34453474
3446- // If both are actor-instance isolated, we're done. This wasn't caught by
3447- // the equality case above because the nominal type describing the actor
3448- // will differ when we're overriding.
3449- if (newIso.getKind () == overriddenIso.getKind () &&
3450- newIso.getKind () == ActorIsolation::ActorInstance)
3451- return true ;
3475+ auto refResult = ActorReferenceResult::forReference (
3476+ valueRef, SourceLoc (), declContext, None, None,
3477+ isolation, overriddenIsolation);
3478+ switch (refResult) {
3479+ case ActorReferenceResult::SameConcurrencyDomain:
3480+ return OverrideIsolationResult::Allowed;
3481+
3482+ case ActorReferenceResult::ExitsActorToNonisolated:
3483+ return OverrideIsolationResult::Sendable;
3484+
3485+ case ActorReferenceResult::EntersActor:
3486+ // It's okay to enter the actor when the overridden declaration is
3487+ // asynchronous (because it will do the switch) or is accessible from
3488+ // anywhere.
3489+ if (isAsyncDecl (overridden) ||
3490+ isAccessibleAcrossActors (
3491+ overridden, refResult.isolation , declContext)) {
3492+ // FIXME: Perform Sendable checking here because we're entering an
3493+ // actor.
3494+ return OverrideIsolationResult::Allowed;
3495+ }
34523496
3453- // If the overridden declaration is from Objective-C with no actor annotation,
3454- // allow it.
3455- if (overriddenDecl ->hasClangNode () && !overriddenIso )
3456- return true ;
3497+ // If the overridden declaration is from Objective-C with no actor
3498+ // annotation, allow it.
3499+ if (overridden ->hasClangNode () && !overriddenIsolation )
3500+ return OverrideIsolationResult::Allowed ;
34573501
3458- return false ;
3502+ return OverrideIsolationResult::Disallowed;
3503+ }
34593504}
34603505
34613506ActorIsolation ActorIsolationRequest::evaluate (
@@ -3517,20 +3562,11 @@ ActorIsolation ActorIsolationRequest::evaluate(
35173562
35183563 // Look for and remember the overridden declaration's isolation.
35193564 Optional<ActorIsolation> overriddenIso;
3520- ValueDecl *overriddenValue = nullptr ;
3521- if ( (overriddenValue = value->getOverriddenDecl ()) ) {
3522- auto iso = getActorIsolation (overriddenValue);
3523- SubstitutionMap subs;
3524-
3525- if (Type selfType = value->getDeclContext ()->getSelfInterfaceType ()) {
3526- subs = selfType->getMemberSubstitutionMap (
3527- value->getModuleContext (), overriddenValue);
3528- }
3529- iso = iso.subst (subs);
3530-
3565+ ValueDecl *overriddenValue = value->getOverriddenDecl ();
3566+ if (overriddenValue) {
35313567 // use the overridden decl's iso as the default isolation for this decl.
3532- defaultIsolation = iso ;
3533- overriddenIso = iso ;
3568+ defaultIsolation = getOverriddenIsolationFor (value) ;
3569+ overriddenIso = defaultIsolation ;
35343570 }
35353571
35363572 // Function used when returning an inferred isolation.
@@ -3541,8 +3577,16 @@ ActorIsolation ActorIsolationRequest::evaluate(
35413577 if (overriddenValue) {
35423578 // if the inferred isolation is not valid, then carry-over the overridden
35433579 // declaration's isolation as this decl's inferred isolation.
3544- if (!validOverrideIsolation (inferred, overriddenValue, *overriddenIso))
3580+ switch (validOverrideIsolation (
3581+ value, inferred, overriddenValue, *overriddenIso)) {
3582+ case OverrideIsolationResult::Allowed:
3583+ case OverrideIsolationResult::Sendable:
3584+ break ;
3585+
3586+ case OverrideIsolationResult::Disallowed:
35453587 inferred = *overriddenIso;
3588+ break ;
3589+ }
35463590 }
35473591
35483592 // Add an implicit attribute to capture the actor isolation that was
@@ -3811,29 +3855,36 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
38113855 if (!overridden)
38123856 return ;
38133857
3814- // Determine the actor isolation of this declaration .
3858+ // Determine the actor isolation of the overriding function .
38153859 auto isolation = getActorIsolation (value);
3860+
3861+ // Determine the actor isolation of the overridden function.
3862+ auto overriddenIsolation = getOverriddenIsolationFor (value);
3863+ switch (validOverrideIsolation (
3864+ value, isolation, overridden, overriddenIsolation)) {
3865+ case OverrideIsolationResult::Allowed:
3866+ return ;
38163867
3817- // Determine the actor isolation of the overridden function.=
3818- auto overriddenIsolation = getActorIsolation (overridden);
3819-
3820- if (overriddenIsolation.requiresSubstitution ()) {
3821- SubstitutionMap subs;
3822- if (Type selfType = value->getDeclContext ()->getSelfInterfaceType ()) {
3823- subs = selfType->getMemberSubstitutionMap (
3824- value->getModuleContext (), overridden);
3825- }
3868+ case OverrideIsolationResult::Sendable:
3869+ // FIXME: Do the Sendable check.
3870+ return ;
38263871
3827- overriddenIsolation = overriddenIsolation.subst (subs);
3872+ case OverrideIsolationResult::Disallowed:
3873+ // Diagnose below.
3874+ break ;
38283875 }
38293876
3830- if (validOverrideIsolation (isolation, overridden, overriddenIsolation))
3831- return ;
3832-
38333877 // Isolation mismatch. Diagnose it.
3878+ DiagnosticBehavior behavior = DiagnosticBehavior::Unspecified;
3879+ if (overridden->hasClangNode () && !overriddenIsolation) {
3880+ behavior = SendableCheckContext (value->getInnermostDeclContext ())
3881+ .defaultDiagnosticBehavior ();
3882+ }
3883+
38343884 value->diagnose (
38353885 diag::actor_isolation_override_mismatch, isolation,
3836- value->getDescriptiveKind (), value->getName (), overriddenIsolation);
3886+ value->getDescriptiveKind (), value->getName (), overriddenIsolation)
3887+ .limitBehavior (behavior);
38373888 overridden->diagnose (diag::overridden_here);
38383889}
38393890
@@ -4828,14 +4879,6 @@ ActorReferenceResult ActorReferenceResult::forExitsActorToNonisolated(
48284879 return ActorReferenceResult{ExitsActorToNonisolated, None, isolation};
48294880}
48304881
4831- ActorReferenceResult ActorReferenceResult::forReference (
4832- ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
4833- Optional<VarRefUseEnv> useKind,
4834- Optional<ReferencedActor> actorInstance) {
4835- return forReference (declRef, declRefLoc, fromDC, useKind, actorInstance,
4836- getInnermostIsolatedContext (fromDC));
4837- }
4838-
48394882// Determine if two actor isolation contexts are considered to be equivalent.
48404883static bool equivalentIsolationContexts (
48414884 const ActorIsolation &lhs, const ActorIsolation &rhs) {
@@ -4854,11 +4897,26 @@ ActorReferenceResult ActorReferenceResult::forReference(
48544897 ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
48554898 Optional<VarRefUseEnv> useKind,
48564899 Optional<ReferencedActor> actorInstance,
4857- ActorIsolation contextIsolation) {
4858- // Compute the isolation of the declaration, adjusted for references.
4859- auto declIsolation = getActorIsolationForReference (declRef.getDecl (), fromDC);
4860- if (auto subs = declRef.getSubstitutions ())
4861- declIsolation = declIsolation.subst (subs);
4900+ Optional<ActorIsolation> knownDeclIsolation,
4901+ Optional<ActorIsolation> knownContextIsolation) {
4902+ // If not provided, compute the isolation of the declaration, adjusted
4903+ // for references.
4904+ ActorIsolation declIsolation = ActorIsolation::forUnspecified ();
4905+ if (knownDeclIsolation) {
4906+ declIsolation = *knownDeclIsolation;
4907+ } else {
4908+ declIsolation = getActorIsolationForReference (declRef.getDecl (), fromDC);
4909+ if (declIsolation.requiresSubstitution ())
4910+ declIsolation = declIsolation.subst (declRef.getSubstitutions ());
4911+ }
4912+
4913+ // Compute the isolation of the context, if not provided.
4914+ ActorIsolation contextIsolation = ActorIsolation::forUnspecified ();
4915+ if (knownContextIsolation) {
4916+ contextIsolation = *knownContextIsolation;
4917+ } else {
4918+ contextIsolation = getInnermostIsolatedContext (fromDC);
4919+ }
48624920
48634921 // When the declaration is not actor-isolated, it can always be accessed
48644922 // directly.
0 commit comments