@@ -934,7 +934,16 @@ bool swift::diagnoseNonSendableTypes(
934934
935935bool swift::diagnoseNonSendableTypesInReference (
936936 ConcreteDeclRef declRef, const DeclContext *fromDC, SourceLoc loc,
937- SendableCheckReason reason) {
937+ SendableCheckReason reason, Optional<ActorIsolation> knownIsolation) {
938+
939+ // Retrieve the actor isolation to use in diagnostics.
940+ auto getActorIsolation = [&] {
941+ if (knownIsolation)
942+ return *knownIsolation;
943+
944+ return swift::getActorIsolation (declRef.getDecl ());
945+ };
946+
938947 // For functions, check the parameter and result types.
939948 SubstitutionMap subs = declRef.getSubstitutions ();
940949 if (auto function = dyn_cast<AbstractFunctionDecl>(declRef.getDecl ())) {
@@ -943,7 +952,7 @@ bool swift::diagnoseNonSendableTypesInReference(
943952 if (diagnoseNonSendableTypes (
944953 paramType, fromDC, loc, diag::non_sendable_param_type,
945954 (unsigned )reason, function->getDescriptiveKind (),
946- function->getName (), getActorIsolation (function )))
955+ function->getName (), getActorIsolation ()))
947956 return true ;
948957 }
949958
@@ -953,7 +962,7 @@ bool swift::diagnoseNonSendableTypesInReference(
953962 if (diagnoseNonSendableTypes (
954963 resultType, fromDC, loc, diag::non_sendable_result_type,
955964 (unsigned )reason, func->getDescriptiveKind (), func->getName (),
956- getActorIsolation (func )))
965+ getActorIsolation ()))
957966 return true ;
958967 }
959968
@@ -970,7 +979,7 @@ bool swift::diagnoseNonSendableTypesInReference(
970979 var->getDescriptiveKind (), var->getName (),
971980 var->isLocalCapture (),
972981 (unsigned )reason,
973- getActorIsolation (var )))
982+ getActorIsolation ()))
974983 return true ;
975984 }
976985
@@ -980,7 +989,7 @@ bool swift::diagnoseNonSendableTypesInReference(
980989 if (diagnoseNonSendableTypes (
981990 paramType, fromDC, loc, diag::non_sendable_param_type,
982991 (unsigned )reason, subscript->getDescriptiveKind (),
983- subscript->getName (), getActorIsolation (subscript )))
992+ subscript->getName (), getActorIsolation ()))
984993 return true ;
985994 }
986995
@@ -989,7 +998,7 @@ bool swift::diagnoseNonSendableTypesInReference(
989998 if (diagnoseNonSendableTypes (
990999 resultType, fromDC, loc, diag::non_sendable_result_type,
9911000 (unsigned )reason, subscript->getDescriptiveKind (),
992- subscript->getName (), getActorIsolation (subscript )))
1001+ subscript->getName (), getActorIsolation ()))
9931002 return true ;
9941003
9951004 return false ;
@@ -2772,8 +2781,10 @@ namespace {
27722781 if (diagnoseReferenceToUnsafeGlobal (decl, loc))
27732782 return true ;
27742783
2775- // FIXME: SE-0338 would trigger Sendable checks here.
2776- return false ;
2784+ return diagnoseNonSendableTypesInReference (
2785+ declRef, getDeclContext (), loc,
2786+ SendableCheckReason::ExitingActor,
2787+ result.isolation );
27772788
27782789 case ActorReferenceResult::EntersActor:
27792790 // Handle all of the checking below.
@@ -3539,19 +3550,25 @@ static ActorIsolation getOverriddenIsolationFor(ValueDecl *value) {
35393550 return isolation.subst (subs);
35403551}
35413552
3553+ static ConcreteDeclRef getDeclRefInContext (ValueDecl *value) {
3554+ auto declContext = value->getInnermostDeclContext ();
3555+ if (auto genericEnv = declContext->getGenericEnvironmentOfContext ()) {
3556+ return ConcreteDeclRef (
3557+ value, genericEnv->getForwardingSubstitutionMap ());
3558+ }
3559+
3560+ return ConcreteDeclRef (value);
3561+ }
3562+
35423563// / Generally speaking, the isolation of the decl that overrides
35433564// / must match the overridden decl. But there are a number of exceptions,
35443565// / e.g., the decl that overrides can be nonisolated.
35453566// / \param isolation the isolation of the overriding declaration.
35463567static OverrideIsolationResult validOverrideIsolation (
35473568 ValueDecl *value, ActorIsolation isolation,
35483569 ValueDecl *overridden, ActorIsolation overriddenIsolation) {
3549- ConcreteDeclRef valueRef (value);
3570+ ConcreteDeclRef valueRef = getDeclRefInContext (value);
35503571 auto declContext = value->getInnermostDeclContext ();
3551- if (auto genericEnv = declContext->getGenericEnvironmentOfContext ()) {
3552- valueRef = ConcreteDeclRef (
3553- value, genericEnv->getForwardingSubstitutionMap ());
3554- }
35553572
35563573 auto refResult = ActorReferenceResult::forReference (
35573574 valueRef, SourceLoc (), declContext, None, None,
@@ -3570,9 +3587,7 @@ static OverrideIsolationResult validOverrideIsolation(
35703587 if (isAsyncDecl (overridden) ||
35713588 isAccessibleAcrossActors (
35723589 overridden, refResult.isolation , declContext)) {
3573- // FIXME: Perform Sendable checking here because we're entering an
3574- // actor.
3575- return OverrideIsolationResult::Allowed;
3590+ return OverrideIsolationResult::Sendable;
35763591 }
35773592
35783593 // If the overridden declaration is from Objective-C with no actor
@@ -3948,7 +3963,9 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
39483963 return ;
39493964
39503965 case OverrideIsolationResult::Sendable:
3951- // FIXME: Do the Sendable check.
3966+ diagnoseNonSendableTypesInReference (
3967+ getDeclRefInContext (value), value->getInnermostDeclContext (),
3968+ value->getLoc (), SendableCheckReason::Override);
39523969 return ;
39533970
39543971 case OverrideIsolationResult::Disallowed:
@@ -4886,9 +4903,8 @@ bool swift::isThrowsDecl(ConcreteDeclRef declRef) {
48864903 return false ;
48874904}
48884905
4889- bool swift::isAccessibleAcrossActors (
4890- ValueDecl *value, const ActorIsolation &isolation,
4891- const DeclContext *fromDC, Optional<ReferencedActor> actorInstance) {
4906+ // / Determine whether a reference to this value isn't actually a value.
4907+ static bool isNonValueReference (const ValueDecl *value) {
48924908 switch (value->getKind ()) {
48934909 case DeclKind::AssociatedType:
48944910 case DeclKind::Class:
@@ -4899,13 +4915,7 @@ bool swift::isAccessibleAcrossActors(
48994915 case DeclKind::Protocol:
49004916 case DeclKind::Struct:
49014917 case DeclKind::TypeAlias:
4902- return true ;
4903-
49044918 case DeclKind::EnumCase:
4905- case DeclKind::EnumElement:
4906- // Type-level entities are always accessible across actors.
4907- return true ;
4908-
49094919 case DeclKind::IfConfig:
49104920 case DeclKind::Import:
49114921 case DeclKind::InfixOperator:
@@ -4917,16 +4927,26 @@ bool swift::isAccessibleAcrossActors(
49174927 case DeclKind::PrecedenceGroup:
49184928 case DeclKind::PrefixOperator:
49194929 case DeclKind::TopLevelCode:
4920- // Non-value entities are always accessible across actors.
4921- return true ;
4922-
49234930 case DeclKind::Destructor:
4924- // Destructors are always accessible across actors.
49254931 return true ;
49264932
4933+ case DeclKind::EnumElement:
49274934 case DeclKind::Constructor:
4928- // Initializers are accessible across actors unless they are global-actor
4929- // qualified.
4935+ case DeclKind::Param:
4936+ case DeclKind::Var:
4937+ case DeclKind::Accessor:
4938+ case DeclKind::Func:
4939+ case DeclKind::Subscript:
4940+ return false ;
4941+ }
4942+ }
4943+
4944+ bool swift::isAccessibleAcrossActors (
4945+ ValueDecl *value, const ActorIsolation &isolation,
4946+ const DeclContext *fromDC, Optional<ReferencedActor> actorInstance) {
4947+ // Initializers and enum elements are accessible across actors unless they
4948+ // are global-actor qualified.
4949+ if (isa<ConstructorDecl>(value) || isa<EnumElementDecl>(value)) {
49304950 switch (isolation) {
49314951 case ActorIsolation::ActorInstance:
49324952 case ActorIsolation::Independent:
@@ -4937,19 +4957,15 @@ bool swift::isAccessibleAcrossActors(
49374957 case ActorIsolation::GlobalActor:
49384958 return false ;
49394959 }
4960+ }
49404961
4941- case DeclKind::Param:
4942- case DeclKind::Var:
4943- // 'let' declarations are immutable, so some of them can be accessed across
4944- // actors.
4945- return varIsSafeAcrossActors (
4946- fromDC->getParentModule (), cast<VarDecl>(value), isolation);
4947-
4948- case DeclKind::Accessor:
4949- case DeclKind::Func:
4950- case DeclKind::Subscript:
4951- return false ;
4962+ // 'let' declarations are immutable, so some of them can be accessed across
4963+ // actors.
4964+ if (auto var = dyn_cast<VarDecl>(value)) {
4965+ return varIsSafeAcrossActors (fromDC->getParentModule (), var, isolation);
49524966 }
4967+
4968+ return false ;
49534969}
49544970
49554971ActorReferenceResult ActorReferenceResult::forSameConcurrencyDomain (
@@ -4998,6 +5014,11 @@ ActorReferenceResult ActorReferenceResult::forReference(
49985014 declIsolation = declIsolation.subst (declRef.getSubstitutions ());
49995015 }
50005016
5017+ // If the entity we are referencing is not a value, we're in thesame
5018+ // concurrency domain.
5019+ if (isNonValueReference (declRef.getDecl ()))
5020+ return forSameConcurrencyDomain (declIsolation);
5021+
50015022 // Compute the isolation of the context, if not provided.
50025023 ActorIsolation contextIsolation = ActorIsolation::forUnspecified ();
50035024 if (knownContextIsolation) {
0 commit comments