Skip to content

Commit eef2704

Browse files
committed
Reimplement actor isolation checking for referencing a declaration.
Start collapsing the several implementations of actor isolation checking into a single place that determines what it means to reference a declaration from a given context, potentially supplying an instance for an actor. This is partly cleanup, and partly staging for the implementation of the Sendable restrictions introduced in SE-0338. The result of this check falls into one of three categories: * Reference occurs within the same concurrency domain (actor/task) * Reference leaves an actor context to a nonisolated context (SE-0338) * Reference enters the context of the actor, which might require a combination of implicit async, implicit throws, and a "distributed" check. Throughout this change I've sought to maintain the existing semantics, even where I believe they are incorrect. The changes to the test cases are not semantic changes, but reflect the unification of some diagnostic paths that changed the diagnostic text but not when or how those diagnostics are produced. Additionally, SE-0338 has not yet been implemented, although this refactoring makes it easier to implement SE-0338. Use this new actor isolation checking scheme to implement the most common actor-isolation check, which occurs when accessing a member of an instance.
1 parent cf2e90b commit eef2704

11 files changed

+864
-519
lines changed

include/swift/AST/ActorIsolation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ class ActorIsolation {
131131
return getKind() == GlobalActor || getKind() == GlobalActorUnsafe;
132132
}
133133

134+
bool isDistributedActor() const;
135+
134136
Type getGlobalActor() const {
135137
assert(isGlobalActor());
136138
return globalActor;

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4541,13 +4541,16 @@ ERROR(override_implicit_unowned_executor,none,
45414541
"cannot override an actor's 'unownedExecutor' property that wasn't "
45424542
"explicitly defined", ())
45434543
ERROR(actor_isolated_non_self_reference,none,
4544-
"actor-isolated %0 %1 can not be "
4544+
"%5 %0 %1 can not be "
45454545
"%select{referenced|mutated|used 'inout'}2 "
4546-
"%select{on a non-isolated actor instance|"
4546+
"%select{on a different actor instance|"
4547+
"on a non-isolated actor instance|"
45474548
"from a Sendable function|from a Sendable closure|"
45484549
"from an 'async let' initializer|from global actor %4|"
4549-
"from the main actor|from a non-isolated context|from a non-isolated autoclosure}3",
4550-
(DescriptiveDeclKind, DeclName, unsigned, unsigned, Type))
4550+
"from the main actor|from a non-isolated context|"
4551+
"from a non-isolated autoclosure}3",
4552+
(DescriptiveDeclKind, DeclName, unsigned, unsigned, Type,
4553+
ActorIsolation))
45514554
ERROR(distributed_actor_isolated_non_self_reference,none,
45524555
"distributed actor-isolated %0 %1 can not be accessed from a "
45534556
"non-isolated context",

lib/AST/Decl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9380,3 +9380,7 @@ void swift::simple_display(llvm::raw_ostream &out, AnyFunctionRef fn) {
93809380
else
93819381
out << "closure";
93829382
}
9383+
9384+
bool ActorIsolation::isDistributedActor() const {
9385+
return getKind() == ActorInstance && getActor()->isDistributedActor();
9386+
}

lib/Sema/CSApply.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7827,6 +7827,9 @@ bool ExprRewriter::isDistributedThunk(ConcreteDeclRef ref, Expr *context) {
78277827
}))
78287828
return false;
78297829

7830+
if (actor->isKnownToBeLocal())
7831+
return false;
7832+
78307833
bool isInAsyncLetInitializer = target && target->isAsyncLetInitializer();
78317834

78327835
auto isActorInitOrDeInitContext = [&](const DeclContext *dc) {

0 commit comments

Comments
 (0)