Skip to content

Commit c979b9f

Browse files
authored
Merge pull request #41763 from etcwilde/ewilde/warn-concurrency-async-top-level
Make toplevel vars MainActor with `-warn-concurrency`
2 parents ee7b941 + d2c3e46 commit c979b9f

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

lib/AST/Decl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9060,7 +9060,9 @@ ActorIsolation swift::getActorIsolationOfContext(DeclContext *dc) {
90609060
}
90619061

90629062
if (auto *tld = dyn_cast<TopLevelCodeDecl>(dc)) {
9063-
if (dc->isAsyncContext()) {
9063+
if (dc->isAsyncContext() ||
9064+
(dc->getASTContext().LangOpts.WarnConcurrency &&
9065+
dc->getASTContext().LangOpts.EnableExperimentalAsyncTopLevel)) {
90649066
if (Type mainActor = dc->getASTContext().getMainActorType())
90659067
return ActorIsolation::forGlobalActor(mainActor, /*unsafe=*/false);
90669068
}

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,9 @@ GlobalActorAttributeRequest::evaluate(
344344
if (auto var = dyn_cast<VarDecl>(storage)) {
345345

346346
// ... but not if it's an async-context top-level global
347-
if (var->isTopLevelGlobal() && var->getDeclContext()->isAsyncContext()) {
347+
if (var->getASTContext().LangOpts.EnableExperimentalAsyncTopLevel &&
348+
var->isTopLevelGlobal() && (var->getDeclContext()->isAsyncContext()
349+
|| var->getASTContext().LangOpts.WarnConcurrency)) {
348350
var->diagnose(diag::global_actor_top_level_var)
349351
.highlight(globalActorAttr->getRangeWithAt());
350352
return None;
@@ -3867,7 +3869,10 @@ ActorIsolation ActorIsolationRequest::evaluate(
38673869
}
38683870

38693871
if (auto var = dyn_cast<VarDecl>(value)) {
3870-
if (var->isTopLevelGlobal() && var->getDeclContext()->isAsyncContext()) {
3872+
if (var->getASTContext().LangOpts.EnableExperimentalAsyncTopLevel &&
3873+
var->isTopLevelGlobal() &&
3874+
(var->getASTContext().LangOpts.WarnConcurrency ||
3875+
var->getDeclContext()->isAsyncContext())) {
38713876
if (Type mainActor = var->getASTContext().getMainActorType())
38723877
return inferredIsolation(
38733878
ActorIsolation::forGlobalActor(mainActor,
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %target-swift-frontend -disable-availability-checking -enable-experimental-async-top-level -warn-concurrency -typecheck -verify %s
2+
3+
var a = 10 // expected-note{{var declared here}}
4+
5+
@MainActor
6+
var b = 15 // expected-error{{top-level code variables cannot have a global actor}}
7+
8+
func unsafeAccess() { // expected-note{{add '@MainActor' to make global function 'unsafeAccess()' part of global actor 'MainActor'}}
9+
print(a) // expected-error@:11{{var 'a' isolated to global actor 'MainActor' can not be referenced from this synchronous context}}
10+
}
11+
12+
func unsafeAsyncAccess() async {
13+
print(a) // expected-error@:5{{expression is 'async' but is not marked with 'await'}}{{5-5=await }}
14+
// expected-note@-1:11{{property access is 'async'}}
15+
}
16+
17+
@MainActor
18+
func safeAccess() {
19+
print(a)
20+
}
21+
22+
@MainActor
23+
func safeSyncAccess() async {
24+
print(a)
25+
}
26+
27+
func safeAsyncAccess() async {
28+
await print(a)
29+
}
30+
31+
print(a)

0 commit comments

Comments
 (0)