@@ -3459,34 +3459,79 @@ static bool checkClassGlobalActorIsolation(
34593459 return true ;
34603460}
34613461
3462+ namespace {
3463+ // / Describes the result of checking override isolation.
3464+ enum class OverrideIsolationResult {
3465+ // / The override is permitted.
3466+ Allowed,
3467+ // / The override is permitted, but requires a Sendable check.
3468+ Sendable,
3469+ // / The override is not permitted.
3470+ Disallowed,
3471+ };
3472+ }
3473+
3474+ // / Return the isolation of the declaration overridden by this declaration,
3475+ // / in the context of the
3476+ static ActorIsolation getOverriddenIsolationFor (ValueDecl *value) {
3477+ auto overridden = value->getOverriddenDecl ();
3478+ assert (overridden && " Doesn't have an overridden declaration" );
3479+
3480+ auto isolation = getActorIsolation (overridden);
3481+ if (!isolation.requiresSubstitution ())
3482+ return isolation;
3483+
3484+ SubstitutionMap subs;
3485+ if (Type selfType = value->getDeclContext ()->getSelfInterfaceType ()) {
3486+ subs = selfType->getMemberSubstitutionMap (
3487+ value->getModuleContext (), overridden);
3488+ }
3489+ return isolation.subst (subs);
3490+ }
3491+
34623492// / Generally speaking, the isolation of the decl that overrides
34633493// / must match the overridden decl. But there are a number of exceptions,
34643494// / e.g., the decl that overrides can be nonisolated.
3465- // / \param newIso the isolation of the overriding declaration.
3466- static bool validOverrideIsolation (ActorIsolation newIso,
3467- ValueDecl *overriddenDecl,
3468- ActorIsolation overriddenIso) {
3469- // If the isolation matches, we're done.
3470- if (newIso == overriddenIso)
3471- return true ;
3472-
3473- // If the overriding declaration is non-isolated, it's okay.
3474- if (newIso.isIndependent () || newIso.isUnspecified ())
3475- return true ;
3495+ // / \param isolation the isolation of the overriding declaration.
3496+ static OverrideIsolationResult validOverrideIsolation (
3497+ ValueDecl *value, ActorIsolation isolation,
3498+ ValueDecl *overridden, ActorIsolation overriddenIsolation) {
3499+ ConcreteDeclRef valueRef (value);
3500+ auto declContext = value->getInnermostDeclContext ();
3501+ if (auto genericEnv = declContext->getGenericEnvironmentOfContext ()) {
3502+ valueRef = ConcreteDeclRef (
3503+ value, genericEnv->getForwardingSubstitutionMap ());
3504+ }
34763505
3477- // If both are actor-instance isolated, we're done. This wasn't caught by
3478- // the equality case above because the nominal type describing the actor
3479- // will differ when we're overriding.
3480- if (newIso.getKind () == overriddenIso.getKind () &&
3481- newIso.getKind () == ActorIsolation::ActorInstance)
3482- return true ;
3506+ auto refResult = ActorReferenceResult::forReference (
3507+ valueRef, SourceLoc (), declContext, None, None,
3508+ isolation, overriddenIsolation);
3509+ switch (refResult) {
3510+ case ActorReferenceResult::SameConcurrencyDomain:
3511+ return OverrideIsolationResult::Allowed;
3512+
3513+ case ActorReferenceResult::ExitsActorToNonisolated:
3514+ return OverrideIsolationResult::Sendable;
3515+
3516+ case ActorReferenceResult::EntersActor:
3517+ // It's okay to enter the actor when the overridden declaration is
3518+ // asynchronous (because it will do the switch) or is accessible from
3519+ // anywhere.
3520+ if (isAsyncDecl (overridden) ||
3521+ isAccessibleAcrossActors (
3522+ overridden, refResult.isolation , declContext)) {
3523+ // FIXME: Perform Sendable checking here because we're entering an
3524+ // actor.
3525+ return OverrideIsolationResult::Allowed;
3526+ }
34833527
3484- // If the overridden declaration is from Objective-C with no actor annotation,
3485- // allow it.
3486- if (overriddenDecl ->hasClangNode () && !overriddenIso )
3487- return true ;
3528+ // If the overridden declaration is from Objective-C with no actor
3529+ // annotation, allow it.
3530+ if (overridden ->hasClangNode () && !overriddenIsolation )
3531+ return OverrideIsolationResult::Allowed ;
34883532
3489- return false ;
3533+ return OverrideIsolationResult::Disallowed;
3534+ }
34903535}
34913536
34923537ActorIsolation ActorIsolationRequest::evaluate (
@@ -3548,20 +3593,11 @@ ActorIsolation ActorIsolationRequest::evaluate(
35483593
35493594 // Look for and remember the overridden declaration's isolation.
35503595 Optional<ActorIsolation> overriddenIso;
3551- ValueDecl *overriddenValue = nullptr ;
3552- if ( (overriddenValue = value->getOverriddenDecl ()) ) {
3553- auto iso = getActorIsolation (overriddenValue);
3554- SubstitutionMap subs;
3555-
3556- if (Type selfType = value->getDeclContext ()->getSelfInterfaceType ()) {
3557- subs = selfType->getMemberSubstitutionMap (
3558- value->getModuleContext (), overriddenValue);
3559- }
3560- iso = iso.subst (subs);
3561-
3596+ ValueDecl *overriddenValue = value->getOverriddenDecl ();
3597+ if (overriddenValue) {
35623598 // use the overridden decl's iso as the default isolation for this decl.
3563- defaultIsolation = iso ;
3564- overriddenIso = iso ;
3599+ defaultIsolation = getOverriddenIsolationFor (value) ;
3600+ overriddenIso = defaultIsolation ;
35653601 }
35663602
35673603 // Function used when returning an inferred isolation.
@@ -3572,8 +3608,16 @@ ActorIsolation ActorIsolationRequest::evaluate(
35723608 if (overriddenValue) {
35733609 // if the inferred isolation is not valid, then carry-over the overridden
35743610 // declaration's isolation as this decl's inferred isolation.
3575- if (!validOverrideIsolation (inferred, overriddenValue, *overriddenIso))
3611+ switch (validOverrideIsolation (
3612+ value, inferred, overriddenValue, *overriddenIso)) {
3613+ case OverrideIsolationResult::Allowed:
3614+ case OverrideIsolationResult::Sendable:
3615+ break ;
3616+
3617+ case OverrideIsolationResult::Disallowed:
35763618 inferred = *overriddenIso;
3619+ break ;
3620+ }
35773621 }
35783622
35793623 // Add an implicit attribute to capture the actor isolation that was
@@ -3843,29 +3887,36 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
38433887 if (!overridden)
38443888 return ;
38453889
3846- // Determine the actor isolation of this declaration .
3890+ // Determine the actor isolation of the overriding function .
38473891 auto isolation = getActorIsolation (value);
3892+
3893+ // Determine the actor isolation of the overridden function.
3894+ auto overriddenIsolation = getOverriddenIsolationFor (value);
3895+ switch (validOverrideIsolation (
3896+ value, isolation, overridden, overriddenIsolation)) {
3897+ case OverrideIsolationResult::Allowed:
3898+ return ;
38483899
3849- // Determine the actor isolation of the overridden function.=
3850- auto overriddenIsolation = getActorIsolation (overridden);
3851-
3852- if (overriddenIsolation.requiresSubstitution ()) {
3853- SubstitutionMap subs;
3854- if (Type selfType = value->getDeclContext ()->getSelfInterfaceType ()) {
3855- subs = selfType->getMemberSubstitutionMap (
3856- value->getModuleContext (), overridden);
3857- }
3900+ case OverrideIsolationResult::Sendable:
3901+ // FIXME: Do the Sendable check.
3902+ return ;
38583903
3859- overriddenIsolation = overriddenIsolation.subst (subs);
3904+ case OverrideIsolationResult::Disallowed:
3905+ // Diagnose below.
3906+ break ;
38603907 }
38613908
3862- if (validOverrideIsolation (isolation, overridden, overriddenIsolation))
3863- return ;
3864-
38653909 // Isolation mismatch. Diagnose it.
3910+ DiagnosticBehavior behavior = DiagnosticBehavior::Unspecified;
3911+ if (overridden->hasClangNode () && !overriddenIsolation) {
3912+ behavior = SendableCheckContext (value->getInnermostDeclContext ())
3913+ .defaultDiagnosticBehavior ();
3914+ }
3915+
38663916 value->diagnose (
38673917 diag::actor_isolation_override_mismatch, isolation,
3868- value->getDescriptiveKind (), value->getName (), overriddenIsolation);
3918+ value->getDescriptiveKind (), value->getName (), overriddenIsolation)
3919+ .limitBehavior (behavior);
38693920 overridden->diagnose (diag::overridden_here);
38703921}
38713922
@@ -4866,14 +4917,6 @@ ActorReferenceResult ActorReferenceResult::forExitsActorToNonisolated(
48664917 return ActorReferenceResult{ExitsActorToNonisolated, None, isolation};
48674918}
48684919
4869- ActorReferenceResult ActorReferenceResult::forReference (
4870- ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
4871- Optional<VarRefUseEnv> useKind,
4872- Optional<ReferencedActor> actorInstance) {
4873- return forReference (declRef, declRefLoc, fromDC, useKind, actorInstance,
4874- getInnermostIsolatedContext (fromDC));
4875- }
4876-
48774920// Determine if two actor isolation contexts are considered to be equivalent.
48784921static bool equivalentIsolationContexts (
48794922 const ActorIsolation &lhs, const ActorIsolation &rhs) {
@@ -4892,11 +4935,26 @@ ActorReferenceResult ActorReferenceResult::forReference(
48924935 ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
48934936 Optional<VarRefUseEnv> useKind,
48944937 Optional<ReferencedActor> actorInstance,
4895- ActorIsolation contextIsolation) {
4896- // Compute the isolation of the declaration, adjusted for references.
4897- auto declIsolation = getActorIsolationForReference (declRef.getDecl (), fromDC);
4898- if (auto subs = declRef.getSubstitutions ())
4899- declIsolation = declIsolation.subst (subs);
4938+ Optional<ActorIsolation> knownDeclIsolation,
4939+ Optional<ActorIsolation> knownContextIsolation) {
4940+ // If not provided, compute the isolation of the declaration, adjusted
4941+ // for references.
4942+ ActorIsolation declIsolation = ActorIsolation::forUnspecified ();
4943+ if (knownDeclIsolation) {
4944+ declIsolation = *knownDeclIsolation;
4945+ } else {
4946+ declIsolation = getActorIsolationForReference (declRef.getDecl (), fromDC);
4947+ if (declIsolation.requiresSubstitution ())
4948+ declIsolation = declIsolation.subst (declRef.getSubstitutions ());
4949+ }
4950+
4951+ // Compute the isolation of the context, if not provided.
4952+ ActorIsolation contextIsolation = ActorIsolation::forUnspecified ();
4953+ if (knownContextIsolation) {
4954+ contextIsolation = *knownContextIsolation;
4955+ } else {
4956+ contextIsolation = getInnermostIsolatedContext (fromDC);
4957+ }
49004958
49014959 // When the declaration is not actor-isolated, it can always be accessed
49024960 // directly.
0 commit comments