Skip to content

Commit 3691e34

Browse files
committed
Use "isolated" parameters to check for synchronous actor access.
Rework the checking of actor member access to rely on "isolated" parameters (and captures thereof) to determine whether one can synchronously access an actor or not. This allows synchronous access via an "isolated" parameter as a general notion, which subsumes the declaration-based "self" access. Simplify the checking of and diagnostic reporting for actor member access by collapsing a number of redundant diagnostics down into a single, parameterized diagnostic with a single point of emission. This normalizes the logic a bit. (cherry picked from commit 5bcd5a8)
1 parent a11f67b commit 3691e34

File tree

10 files changed

+480
-220
lines changed

10 files changed

+480
-220
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4373,24 +4373,20 @@ ERROR(override_implicit_unowned_executor,none,
43734373
"explicitly defined", ())
43744374

43754375
ERROR(actor_isolated_non_self_reference,none,
4376-
"actor-isolated %0 %1 can only be %select{referenced|mutated|used 'inout'}3 "
4377-
"%select{from inside the actor|on 'self'}2",
4378-
(DescriptiveDeclKind, DeclName, bool, unsigned))
4379-
ERROR(actor_isolated_self_independent_context,none,
4380-
"actor-isolated %0 %1 can not be %select{referenced|mutated|used 'inout'}2 from a "
4381-
"non-isolated context",
4382-
(DescriptiveDeclKind, DeclName, unsigned))
4376+
"actor-isolated %0 %1 can not be "
4377+
"%select{referenced|mutated|used 'inout'}2 "
4378+
"%select{on a non-isolated actor instance|"
4379+
"from a Sendable function|from a Sendable closure|"
4380+
"from an 'async let' initializer|from global actor %4|"
4381+
"from the main actor|from a non-isolated context}3",
4382+
(DescriptiveDeclKind, DeclName, unsigned, unsigned, Type))
43834383
ERROR(actor_isolated_inout_state,none,
43844384
"actor-isolated %0 %1 cannot be passed 'inout' to"
43854385
"%select{| implicitly}2 'async' function call",
43864386
(DescriptiveDeclKind, DeclName, bool))
43874387
ERROR(actor_isolated_mutating_func,none,
43884388
"cannot call mutating async function %0 on actor-isolated %1 %2",
43894389
(DeclName, DescriptiveDeclKind, DeclName))
4390-
ERROR(actor_isolated_global_actor_context,none,
4391-
"actor-isolated %0 %1 can not be %select{referenced|mutated|used 'inout'}3 "
4392-
"from%select{| synchronous}4 context of global actor %2",
4393-
(DescriptiveDeclKind, DeclName, Type, unsigned, bool))
43944390
ERROR(global_actor_from_instance_actor_context,none,
43954391
"%0 %1 isolated to global actor %2 can not be %select{referenced|mutated|used 'inout'}4"
43964392
" from actor %3 %select{|in a synchronous context}5",
@@ -4415,15 +4411,6 @@ ERROR(actor_isolated_partial_apply,none,
44154411
ERROR(concurrent_access_local,none,
44164412
"use of local %0 %1 in concurrently-executing code",
44174413
(DescriptiveDeclKind, DeclName))
4418-
ERROR(actor_isolated_from_concurrent_closure,none,
4419-
"actor-isolated %0 %1 cannot be %select{referenced|mutated|used 'inout'}2 from a concurrent closure",
4420-
(DescriptiveDeclKind, DeclName, unsigned))
4421-
ERROR(actor_isolated_from_concurrent_function,none,
4422-
"actor-isolated %0 %1 cannot be %select{referenced|mutated|used 'inout'}2 from a concurrent function",
4423-
(DescriptiveDeclKind, DeclName, unsigned))
4424-
ERROR(actor_isolated_from_async_let,none,
4425-
"actor-isolated %0 %1 cannot be %select{referenced|mutated|used 'inout'}2 from 'async let' initializer",
4426-
(DescriptiveDeclKind, DeclName, unsigned))
44274414
ERROR(actor_isolated_keypath_component,none,
44284415
"cannot form key path to actor-isolated %0 %1",
44294416
(DescriptiveDeclKind, DeclName))

lib/AST/Decl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,15 @@ ParamDecl *PatternBindingInitializer::getImplicitSelfDecl() const {
14181418
LazySelfParam->setImplicit();
14191419
LazySelfParam->setSpecifier(specifier);
14201420
LazySelfParam->setInterfaceType(DC->getSelfInterfaceType());
1421+
1422+
// Lazy members of actors have an isolated 'self', assuming there is
1423+
// no "nonisolated" attribute.
1424+
if (auto nominal = DC->getSelfNominalTypeDecl()) {
1425+
if (nominal->isActor() &&
1426+
!singleVar->getAttrs().hasAttribute<NonisolatedAttr>())
1427+
LazySelfParam->setIsolated();
1428+
}
1429+
14211430
mutableThis->SelfParam = LazySelfParam;
14221431
}
14231432
}
@@ -8233,6 +8242,7 @@ ActorIsolation swift::getActorIsolationOfContext(DeclContext *dc) {
82338242
auto selfDecl = isolation.getActorInstance();
82348243
auto actorClass = selfDecl->getType()->getRValueType()
82358244
->getClassOrBoundGenericClass();
8245+
// FIXME: Doesn't work properly with generics
82368246
assert(actorClass && "Bad closure actor isolation?");
82378247
return ActorIsolation::forActorInstance(actorClass);
82388248
}

0 commit comments

Comments
 (0)