Skip to content

Commit 7fdd7b7

Browse files
committed
[Concurrency] Isolated static 'let's are not safe to access across actors.
(cherry picked from commit 8eab5fe)
1 parent c4da3b8 commit 7fdd7b7

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
@@ -512,6 +512,11 @@ static bool varIsSafeAcrossActors(const ModuleDecl *fromModule,
512512
if (var->getAttrs().hasAttribute<NonisolatedAttr>())
513513
return true;
514514

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