@@ -934,7 +934,16 @@ bool swift::diagnoseNonSendableTypes(
934
934
935
935
bool swift::diagnoseNonSendableTypesInReference (
936
936
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
+
938
947
// For functions, check the parameter and result types.
939
948
SubstitutionMap subs = declRef.getSubstitutions ();
940
949
if (auto function = dyn_cast<AbstractFunctionDecl>(declRef.getDecl ())) {
@@ -943,7 +952,7 @@ bool swift::diagnoseNonSendableTypesInReference(
943
952
if (diagnoseNonSendableTypes (
944
953
paramType, fromDC, loc, diag::non_sendable_param_type,
945
954
(unsigned )reason, function->getDescriptiveKind (),
946
- function->getName (), getActorIsolation (function )))
955
+ function->getName (), getActorIsolation ()))
947
956
return true ;
948
957
}
949
958
@@ -953,7 +962,7 @@ bool swift::diagnoseNonSendableTypesInReference(
953
962
if (diagnoseNonSendableTypes (
954
963
resultType, fromDC, loc, diag::non_sendable_result_type,
955
964
(unsigned )reason, func->getDescriptiveKind (), func->getName (),
956
- getActorIsolation (func )))
965
+ getActorIsolation ()))
957
966
return true ;
958
967
}
959
968
@@ -970,7 +979,7 @@ bool swift::diagnoseNonSendableTypesInReference(
970
979
var->getDescriptiveKind (), var->getName (),
971
980
var->isLocalCapture (),
972
981
(unsigned )reason,
973
- getActorIsolation (var )))
982
+ getActorIsolation ()))
974
983
return true ;
975
984
}
976
985
@@ -980,7 +989,7 @@ bool swift::diagnoseNonSendableTypesInReference(
980
989
if (diagnoseNonSendableTypes (
981
990
paramType, fromDC, loc, diag::non_sendable_param_type,
982
991
(unsigned )reason, subscript->getDescriptiveKind (),
983
- subscript->getName (), getActorIsolation (subscript )))
992
+ subscript->getName (), getActorIsolation ()))
984
993
return true ;
985
994
}
986
995
@@ -989,7 +998,7 @@ bool swift::diagnoseNonSendableTypesInReference(
989
998
if (diagnoseNonSendableTypes (
990
999
resultType, fromDC, loc, diag::non_sendable_result_type,
991
1000
(unsigned )reason, subscript->getDescriptiveKind (),
992
- subscript->getName (), getActorIsolation (subscript )))
1001
+ subscript->getName (), getActorIsolation ()))
993
1002
return true ;
994
1003
995
1004
return false ;
@@ -2772,8 +2781,10 @@ namespace {
2772
2781
if (diagnoseReferenceToUnsafeGlobal (decl, loc))
2773
2782
return true ;
2774
2783
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 );
2777
2788
2778
2789
case ActorReferenceResult::EntersActor:
2779
2790
// Handle all of the checking below.
@@ -3539,19 +3550,25 @@ static ActorIsolation getOverriddenIsolationFor(ValueDecl *value) {
3539
3550
return isolation.subst (subs);
3540
3551
}
3541
3552
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
+
3542
3563
// / Generally speaking, the isolation of the decl that overrides
3543
3564
// / must match the overridden decl. But there are a number of exceptions,
3544
3565
// / e.g., the decl that overrides can be nonisolated.
3545
3566
// / \param isolation the isolation of the overriding declaration.
3546
3567
static OverrideIsolationResult validOverrideIsolation (
3547
3568
ValueDecl *value, ActorIsolation isolation,
3548
3569
ValueDecl *overridden, ActorIsolation overriddenIsolation) {
3549
- ConcreteDeclRef valueRef (value);
3570
+ ConcreteDeclRef valueRef = getDeclRefInContext (value);
3550
3571
auto declContext = value->getInnermostDeclContext ();
3551
- if (auto genericEnv = declContext->getGenericEnvironmentOfContext ()) {
3552
- valueRef = ConcreteDeclRef (
3553
- value, genericEnv->getForwardingSubstitutionMap ());
3554
- }
3555
3572
3556
3573
auto refResult = ActorReferenceResult::forReference (
3557
3574
valueRef, SourceLoc (), declContext, None, None,
@@ -3570,9 +3587,7 @@ static OverrideIsolationResult validOverrideIsolation(
3570
3587
if (isAsyncDecl (overridden) ||
3571
3588
isAccessibleAcrossActors (
3572
3589
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;
3576
3591
}
3577
3592
3578
3593
// If the overridden declaration is from Objective-C with no actor
@@ -3948,7 +3963,9 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
3948
3963
return ;
3949
3964
3950
3965
case OverrideIsolationResult::Sendable:
3951
- // FIXME: Do the Sendable check.
3966
+ diagnoseNonSendableTypesInReference (
3967
+ getDeclRefInContext (value), value->getInnermostDeclContext (),
3968
+ value->getLoc (), SendableCheckReason::Override);
3952
3969
return ;
3953
3970
3954
3971
case OverrideIsolationResult::Disallowed:
@@ -4886,9 +4903,8 @@ bool swift::isThrowsDecl(ConcreteDeclRef declRef) {
4886
4903
return false ;
4887
4904
}
4888
4905
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) {
4892
4908
switch (value->getKind ()) {
4893
4909
case DeclKind::AssociatedType:
4894
4910
case DeclKind::Class:
@@ -4899,13 +4915,7 @@ bool swift::isAccessibleAcrossActors(
4899
4915
case DeclKind::Protocol:
4900
4916
case DeclKind::Struct:
4901
4917
case DeclKind::TypeAlias:
4902
- return true ;
4903
-
4904
4918
case DeclKind::EnumCase:
4905
- case DeclKind::EnumElement:
4906
- // Type-level entities are always accessible across actors.
4907
- return true ;
4908
-
4909
4919
case DeclKind::IfConfig:
4910
4920
case DeclKind::Import:
4911
4921
case DeclKind::InfixOperator:
@@ -4917,16 +4927,26 @@ bool swift::isAccessibleAcrossActors(
4917
4927
case DeclKind::PrecedenceGroup:
4918
4928
case DeclKind::PrefixOperator:
4919
4929
case DeclKind::TopLevelCode:
4920
- // Non-value entities are always accessible across actors.
4921
- return true ;
4922
-
4923
4930
case DeclKind::Destructor:
4924
- // Destructors are always accessible across actors.
4925
4931
return true ;
4926
4932
4933
+ case DeclKind::EnumElement:
4927
4934
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)) {
4930
4950
switch (isolation) {
4931
4951
case ActorIsolation::ActorInstance:
4932
4952
case ActorIsolation::Independent:
@@ -4937,19 +4957,15 @@ bool swift::isAccessibleAcrossActors(
4937
4957
case ActorIsolation::GlobalActor:
4938
4958
return false ;
4939
4959
}
4960
+ }
4940
4961
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);
4952
4966
}
4967
+
4968
+ return false ;
4953
4969
}
4954
4970
4955
4971
ActorReferenceResult ActorReferenceResult::forSameConcurrencyDomain (
@@ -4998,6 +5014,11 @@ ActorReferenceResult ActorReferenceResult::forReference(
4998
5014
declIsolation = declIsolation.subst (declRef.getSubstitutions ());
4999
5015
}
5000
5016
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
+
5001
5022
// Compute the isolation of the context, if not provided.
5002
5023
ActorIsolation contextIsolation = ActorIsolation::forUnspecified ();
5003
5024
if (knownContextIsolation) {
0 commit comments