@@ -495,7 +495,8 @@ Type swift::getExplicitGlobalActor(ClosureExpr *closure) {
495
495
// / nonisolated or it is accessed from within the same module.
496
496
static bool varIsSafeAcrossActors (const ModuleDecl *fromModule,
497
497
VarDecl *var,
498
- const ActorIsolation &varIsolation) {
498
+ const ActorIsolation &varIsolation,
499
+ ActorReferenceResult::Options &options) {
499
500
// must be immutable
500
501
if (!var->isLet ())
501
502
return false ;
@@ -516,8 +517,12 @@ static bool varIsSafeAcrossActors(const ModuleDecl *fromModule,
516
517
517
518
// Static 'let's are initialized upon first access, so they cannot be
518
519
// synchronously accessed across actors.
519
- if (var->isGlobalStorage () && var->isLazilyInitializedGlobal ())
520
+ if (var->isGlobalStorage () && var->isLazilyInitializedGlobal ()) {
521
+ // Compiler versions <= 5.9 accepted this code, so downgrade to a
522
+ // warning prior to Swift 6.
523
+ options = ActorReferenceResult::Flags::Preconcurrency;
520
524
return false ;
525
+ }
521
526
522
527
// If it's distributed, generally variable access is not okay...
523
528
if (auto nominalParent = var->getDeclContext ()->getSelfNominalTypeDecl ()) {
@@ -533,7 +538,8 @@ static bool varIsSafeAcrossActors(const ModuleDecl *fromModule,
533
538
bool swift::isLetAccessibleAnywhere (const ModuleDecl *fromModule,
534
539
VarDecl *let) {
535
540
auto isolation = getActorIsolation (let);
536
- return varIsSafeAcrossActors (fromModule, let, isolation);
541
+ ActorReferenceResult::Options options = llvm::None;
542
+ return varIsSafeAcrossActors (fromModule, let, isolation, options);
537
543
}
538
544
539
545
namespace {
@@ -5829,7 +5835,8 @@ static bool isNonValueReference(const ValueDecl *value) {
5829
5835
5830
5836
bool swift::isAccessibleAcrossActors (
5831
5837
ValueDecl *value, const ActorIsolation &isolation,
5832
- const DeclContext *fromDC, llvm::Optional<ReferencedActor> actorInstance) {
5838
+ const DeclContext *fromDC, ActorReferenceResult::Options &options,
5839
+ llvm::Optional<ReferencedActor> actorInstance) {
5833
5840
// Initializers and enum elements are accessible across actors unless they
5834
5841
// are global-actor qualified.
5835
5842
if (isa<ConstructorDecl>(value) || isa<EnumElementDecl>(value)) {
@@ -5849,12 +5856,22 @@ bool swift::isAccessibleAcrossActors(
5849
5856
// 'let' declarations are immutable, so some of them can be accessed across
5850
5857
// actors.
5851
5858
if (auto var = dyn_cast<VarDecl>(value)) {
5852
- return varIsSafeAcrossActors (fromDC->getParentModule (), var, isolation);
5859
+ return varIsSafeAcrossActors (
5860
+ fromDC->getParentModule (), var, isolation, options);
5853
5861
}
5854
5862
5855
5863
return false ;
5856
5864
}
5857
5865
5866
+ bool swift::isAccessibleAcrossActors (
5867
+ ValueDecl *value, const ActorIsolation &isolation,
5868
+ const DeclContext *fromDC,
5869
+ llvm::Optional<ReferencedActor> actorInstance) {
5870
+ ActorReferenceResult::Options options = llvm::None;
5871
+ return isAccessibleAcrossActors (
5872
+ value, isolation, fromDC, options, actorInstance);
5873
+ }
5874
+
5858
5875
ActorReferenceResult ActorReferenceResult::forSameConcurrencyDomain (
5859
5876
ActorIsolation isolation) {
5860
5877
return ActorReferenceResult{SameConcurrencyDomain, llvm::None, isolation};
@@ -5993,16 +6010,18 @@ ActorReferenceResult ActorReferenceResult::forReference(
5993
6010
(isa<ConstructorDecl>(fromDC) || isa<DestructorDecl>(fromDC)))
5994
6011
return forSameConcurrencyDomain (declIsolation);
5995
6012
6013
+ // Determine what adjustments we need to perform for cross-actor
6014
+ // references.
6015
+ Options options = llvm::None;
6016
+
5996
6017
// At this point, we are accessing the target from outside the actor.
5997
6018
// First, check whether it is something that can be accessed directly,
5998
6019
// without any kind of promotion.
5999
6020
if (isAccessibleAcrossActors (
6000
- declRef.getDecl (), declIsolation, fromDC, actorInstance))
6021
+ declRef.getDecl (), declIsolation, fromDC, options, actorInstance))
6001
6022
return forEntersActor (declIsolation, llvm::None);
6002
6023
6003
- // This is a cross-actor reference, so determine what adjustments we need
6004
- // to perform.
6005
- Options options = llvm::None;
6024
+ // This is a cross-actor reference.
6006
6025
6007
6026
// Note if the reference originates from a @preconcurrency-isolated context.
6008
6027
if (contextIsolation.preconcurrency () || declIsolation.preconcurrency ())
0 commit comments