Skip to content

Commit 8eab5fe

Browse files
committed
[Concurrency] Isolated static 'let's are not safe to access across actors.
1 parent 8f44abc commit 8eab5fe

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,11 @@ static bool varIsSafeAcrossActors(const ModuleDecl *fromModule,
513513
if (var->getAttrs().hasAttribute<NonisolatedAttr>())
514514
return true;
515515

516+
// Static 'let's are initialized upon first access, so they cannot be
517+
// synchronously accessed across actors.
518+
if (var->isStatic())
519+
return false;
520+
516521
// If it's distributed, generally variable access is not okay...
517522
if (auto nominalParent = var->getDeclContext()->getSelfNominalTypeDecl()) {
518523
if (nominalParent->isDistributedActor())

test/Concurrency/Runtime/actor_assert_precondition_executor.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ actor Someone {
6161
}
6262
}
6363

64+
@MainActor
65+
struct TestStaticVar {
66+
@MainActor static let shared = TestStaticVar()
67+
68+
init() {
69+
checkPreconditionMainActor()
70+
}
71+
}
72+
6473
@main struct Main {
6574
static func main() async {
6675
let tests = TestSuite("AssertPreconditionActorExecutor")
@@ -78,6 +87,10 @@ actor Someone {
7887
await MainFriend().callCheckMainActor()
7988
}
8089

90+
tests.test("MainActor.assertIsolated() from static let initializer") {
91+
_ = await TestStaticVar.shared
92+
}
93+
8194
#if !os(WASI)
8295
tests.test("precondition on actor (main): wrongly assume the main executor, from actor on other executor") {
8396
expectCrashLater(withMessage: "Incorrect actor executor assumption; Expected 'MainActor' executor.")

0 commit comments

Comments
 (0)