Skip to content

Commit 2c3bef8

Browse files
committed
Top-level variables are on the MainActor
This is an interesting patch that may raise some eyebrows. The machinery we have now can completely handle arbitrary global-actor isolation on the global variables. I'm forcing the variables to be on the main actor because in an ideal future, the variables won't be global and will actually be local to the implicit `async_Main` function, where they will be isolated to the main actor by virtue of the `async_Main` function being run by the main actor executor. For that to work, we can't really allow top-level variables to have global actor isolation since local variables can't have global actor isolation. So while there is no technical reason we can't handle it now, to avoid source-breaking changes in the future, I'm removing the ability to explicitly declare a global actor on top-level global variables and forcing them all to be on the MainActor implicitly.
1 parent f4e93bd commit 2c3bef8

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4771,7 +4771,9 @@ ERROR(global_actor_non_unsafe_init,none,
47714771
"global actor attribute %0 argument can only be '(unsafe)'", (Type))
47724772
ERROR(global_actor_non_final_class,none,
47734773
"non-final class %0 cannot be a global actor", (DeclName))
4774-
4774+
ERROR(global_actor_top_level_var,none,
4775+
"top-level code variables cannot have a global actor", ())
4776+
47754777
ERROR(actor_isolation_multiple_attr,none,
47764778
"%0 %1 has multiple actor-isolation attributes ('%2' and '%3')",
47774779
(DescriptiveDeclKind, DeclName, StringRef, StringRef))

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,12 @@ GlobalActorAttributeRequest::evaluate(
271271
} else if (auto storage = dyn_cast<AbstractStorageDecl>(decl)) {
272272
// Subscripts and properties are fine...
273273
if (auto var = dyn_cast<VarDecl>(storage)) {
274-
if (var->getDeclContext()->isLocalContext() && !var->isTopLevelGlobal()) {
274+
if (var->isTopLevelGlobal() &&
275+
var->getASTContext().LangOpts.EnableExperimentalAsyncTopLevel) {
276+
var->diagnose(diag::global_actor_top_level_var)
277+
.highlight(globalActorAttr->getRangeWithAt());
278+
return None;
279+
} else if (var->getDeclContext()->isLocalContext()) {
275280
var->diagnose(diag::global_actor_on_local_variable, var->getName())
276281
.highlight(globalActorAttr->getRangeWithAt());
277282
return None;
@@ -3505,6 +3510,14 @@ ActorIsolation ActorIsolationRequest::evaluate(
35053510
}
35063511

35073512
if (auto var = dyn_cast<VarDecl>(value)) {
3513+
ASTContext &ctx = var->getASTContext();
3514+
if (var->isTopLevelGlobal() &&
3515+
ctx.LangOpts.EnableExperimentalAsyncTopLevel) {
3516+
if (Type mainActor = ctx.getMainActorType())
3517+
return inferredIsolation(
3518+
ActorIsolation::forGlobalActor(mainActor,
3519+
/*unsafe=*/false));
3520+
}
35083521
if (auto isolation = getActorIsolationFromWrappedProperty(var))
35093522
return inferredIsolation(isolation);
35103523
}

0 commit comments

Comments
 (0)