From a4a39f2a98c3258d0b962a8f06dc526718201f41 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Tue, 15 Jul 2025 13:00:45 -0700 Subject: [PATCH] [SE-0466] Nested types of nonisolated types don't infer main-actor isolation Under discussion as part of an amendment to SE-0466, limit default main actor inference so it doesn't apply to a nested type within a nonisolated type. --- lib/Sema/TypeCheckConcurrency.cpp | 21 ++++++++++++++++--- ...tor_typechecker_errors_sendablecheck.swift | 7 ++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index 86b6670b2a4cb..a13432f2e20b9 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -6104,13 +6104,28 @@ computeDefaultInferredActorIsolation(ValueDecl *value) { -> std::optional>> { // Default global actor isolation does not apply to any declarations - // within actors and distributed actors. - bool inActorContext = false; + // within actors and distributed actors, nor does it apply in a + // nonisolated type. auto *dc = value->getInnermostDeclContext(); - while (dc && !inActorContext) { + while (dc) { if (auto *nominal = dc->getSelfNominalTypeDecl()) { if (nominal->isAnyActor()) return {}; + + if (dc != dyn_cast(value)) { + switch (getActorIsolation(nominal)) { + case ActorIsolation::Unspecified: + case ActorIsolation::ActorInstance: + case ActorIsolation::Nonisolated: + case ActorIsolation::NonisolatedUnsafe: + case ActorIsolation::Erased: + case ActorIsolation::CallerIsolationInheriting: + return {}; + + case ActorIsolation::GlobalActor: + break; + } + } } dc = dc->getParent(); } diff --git a/test/Concurrency/assume_mainactor_typechecker_errors_sendablecheck.swift b/test/Concurrency/assume_mainactor_typechecker_errors_sendablecheck.swift index e85ca00f762f2..2b258a768a785 100644 --- a/test/Concurrency/assume_mainactor_typechecker_errors_sendablecheck.swift +++ b/test/Concurrency/assume_mainactor_typechecker_errors_sendablecheck.swift @@ -9,8 +9,13 @@ enum CK: CodingKey { case one func f() { } + + struct Nested { + func g() { } + } } -nonisolated func testCK(x: CK) { +nonisolated func testCK(x: CK, y: CK.Nested) { x.f() // okay, because CK and CK.f are not @MainActor. + y.g() }