Skip to content

Commit 40c7c6b

Browse files
Allow accessing let properties in deinit isolated on different actor
1 parent 4d0b624 commit 40c7c6b

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -509,9 +509,9 @@ Type swift::getExplicitGlobalActor(ClosureExpr *closure) {
509509

510510
/// A 'let' declaration is safe across actors if it is either
511511
/// nonisolated or it is accessed from within the same module.
512-
static bool varIsSafeAcrossActors(const ModuleDecl *fromModule,
513-
VarDecl *var,
512+
static bool varIsSafeAcrossActors(const ModuleDecl *fromModule, VarDecl *var,
514513
const ActorIsolation &varIsolation,
514+
std::optional<ReferencedActor> actorInstance,
515515
ActorReferenceResult::Options &options) {
516516

517517
bool accessWithinModule =
@@ -559,6 +559,11 @@ static bool varIsSafeAcrossActors(const ModuleDecl *fromModule,
559559
return false;
560560
}
561561

562+
// If it's distributed, but known to be local, it's ok
563+
// TODO: Check if this can be obtained from the isolation, without a need for separate argument
564+
if (actorInstance && actorInstance->isKnownToBeLocal()) {
565+
return true;
566+
}
562567
// If it's distributed, generally variable access is not okay...
563568
if (auto nominalParent = var->getDeclContext()->getSelfNominalTypeDecl()) {
564569
if (nominalParent->isDistributedActor())
@@ -585,7 +590,7 @@ bool swift::isLetAccessibleAnywhere(const ModuleDecl *fromModule,
585590
VarDecl *let,
586591
ActorReferenceResult::Options &options) {
587592
auto isolation = getActorIsolation(let);
588-
return varIsSafeAcrossActors(fromModule, let, isolation, options);
593+
return varIsSafeAcrossActors(fromModule, let, isolation, std::nullopt, options);
589594
}
590595

591596
bool swift::isLetAccessibleAnywhere(const ModuleDecl *fromModule,
@@ -6762,7 +6767,7 @@ static ActorIsolation getActorIsolationForReference(ValueDecl *decl,
67626767
if (auto var = dyn_cast<VarDecl>(decl)) {
67636768
auto *fromModule = fromDC->getParentModule();
67646769
ActorReferenceResult::Options options = std::nullopt;
6765-
if (varIsSafeAcrossActors(fromModule, var, declIsolation, options) &&
6770+
if (varIsSafeAcrossActors(fromModule, var, declIsolation, std::nullopt, options) &&
67666771
var->getTypeInContext()->isSendableType())
67676772
return ActorIsolation::forNonisolated(/*unsafe*/false);
67686773

@@ -6869,8 +6874,8 @@ bool swift::isAccessibleAcrossActors(
68696874
// 'let' declarations are immutable, so some of them can be accessed across
68706875
// actors.
68716876
if (auto var = dyn_cast<VarDecl>(value)) {
6872-
return varIsSafeAcrossActors(
6873-
fromDC->getParentModule(), var, isolation, options);
6877+
return varIsSafeAcrossActors(fromDC->getParentModule(), var, isolation,
6878+
actorInstance, options);
68746879
}
68756880

68766881
return false;

lib/Sema/TypeCheckDistributed.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,11 @@ void TypeChecker::checkDistributedActor(SourceFile *SF, NominalTypeDecl *nominal
727727

728728
// --- Ensure 'distributed func' all thunks
729729
if (auto func = dyn_cast<AbstractFunctionDecl>(member)) {
730+
if (auto dtor = dyn_cast<DestructorDecl>(func)) {
731+
ASTContext &C = dtor->getASTContext();
732+
auto selfDecl = dtor->getImplicitSelfDecl();
733+
selfDecl->getAttrs().add(new (C) KnownToBeLocalAttr(true));
734+
}
730735
if (!func->isDistributed())
731736
continue;
732737

0 commit comments

Comments
 (0)