Skip to content

Commit b3275d9

Browse files
authored
Merge pull request swiftlang#79044 from hborla/default-actor-isolation-fixes
[Concurrency] Two isolation inference changes for default isolation mode.
2 parents 9eeb78b + 2894896 commit b3275d9

File tree

4 files changed

+41
-34
lines changed

4 files changed

+41
-34
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5612,7 +5612,26 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
56125612
// within our module, make our default isolation main actor.
56135613
if (ctx.LangOpts.hasFeature(Feature::UnspecifiedMeansMainActorIsolated) &&
56145614
value->getModuleContext() == ctx.MainModule) {
5615-
defaultIsolation = ActorIsolation::forMainActor(ctx);
5615+
5616+
// Default global actor isolation does not apply to any declarations
5617+
// within actors and distributed actors.
5618+
bool inActorContext = false;
5619+
auto *dc = value->getInnermostDeclContext();
5620+
while (dc && !inActorContext) {
5621+
if (auto *nominal = dc->getSelfNominalTypeDecl()) {
5622+
inActorContext = nominal->isAnyActor();
5623+
}
5624+
dc = dc->getParent();
5625+
}
5626+
5627+
if (!inActorContext) {
5628+
// FIXME: deinit should be implicitly MainActor too.
5629+
if (isa<TypeDecl>(value) || isa<ExtensionDecl>(value) ||
5630+
isa<AbstractStorageDecl>(value) || isa<FuncDecl>(value) ||
5631+
isa<ConstructorDecl>(value)) {
5632+
defaultIsolation = ActorIsolation::forMainActor(ctx);
5633+
}
5634+
}
56165635
}
56175636

56185637
// If we have an async function... by default we inherit isolation.
@@ -5758,32 +5777,6 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
57585777
}
57595778
}
57605779

5761-
// If this is an actor, use the actor isolation of the actor.
5762-
if (ctx.LangOpts.hasFeature(Feature::UnspecifiedMeansMainActorIsolated)) {
5763-
// non-async inits and deinits need to be always nonisolated since we can
5764-
// run the deinit anywhere.
5765-
//
5766-
// TODO: We should add a check for if they are marked with global actor
5767-
// isolation.
5768-
if (auto *func = dyn_cast<AbstractFunctionDecl>(value)) {
5769-
if (isa<DestructorDecl>(func) && !func->isAsyncContext())
5770-
return {ActorIsolation::forNonisolated(false /*unsafe*/),
5771-
IsolationSource(func, IsolationSource::LexicalContext)};
5772-
5773-
if (isa<ConstructorDecl>(func) && !func->isAsyncContext())
5774-
return {ActorIsolation::forNonisolated(false /*unsafe*/),
5775-
IsolationSource(func, IsolationSource::LexicalContext)};
5776-
}
5777-
5778-
if (auto nominal = dyn_cast<NominalTypeDecl>(value)) {
5779-
if (nominal->isActor() && !nominal->isGlobalActor()) {
5780-
auto isolation = ActorIsolation::forActorInstanceSelf(value);
5781-
return {inferredIsolation(isolation),
5782-
IsolationSource(nominal, IsolationSource::LexicalContext)};
5783-
}
5784-
}
5785-
}
5786-
57875780
// If this is an accessor, use the actor isolation of its storage
57885781
// declaration.
57895782
if (auto accessor = dyn_cast<AccessorDecl>(value)) {

test/Concurrency/Runtime/unspecified_is_main_actor.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,17 @@ tests.test("checkIfOnMainQueue crashes off the main queue 2") { @CustomActor ()
7676
class Klass {}
7777

7878
struct MainActorIsolated {
79-
init() {}
79+
init() {
80+
checkIfOnMainQueue()
81+
}
8082

8183
func test() async {
8284
checkIfOnMainQueue()
8385
}
8486
};
8587

8688
tests.test("callNominalType") { @CustomActor () -> () in
87-
let x = MainActorIsolated()
89+
let x = await MainActorIsolated()
8890
// We would crash without hopping here.
8991
await x.test()
9092
}

test/Concurrency/assume_mainactor.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
class Klass {
1111
// Implicit deinit
1212
// CHECK: // Klass.deinit
13-
// CHECK-NEXT: // Isolation: nonisolated
13+
// CHECK-NEXT: // Isolation: unspecified
1414
// CHECK-NEXT: sil hidden [ossa] @$s16assume_mainactor5KlassCfd : $@convention(method) (@guaranteed Klass) -> @owned Builtin.NativeObject {
1515

1616
// Implicit deallocating deinit
@@ -163,7 +163,7 @@ nonisolated func nonisolatedFunctionTest() async {
163163

164164
actor MyActor {
165165
// CHECK: // variable initialization expression of MyActor.k
166-
// CHECK-NEXT: // Isolation: actor_instance
166+
// CHECK-NEXT: // Isolation: unspecified
167167
// CHECK-NEXT: sil hidden [transparent] [ossa] @$s16assume_mainactor7MyActorC1kAA5KlassCvpfi : $@convention(thin) () -> @owned Klass {
168168

169169
// CHECK: // MyActor.k.getter
@@ -175,9 +175,21 @@ actor MyActor {
175175
// CHECK-NEXT: sil hidden [transparent] [ossa] @$s16assume_mainactor7MyActorC1kAA5KlassCvs : $@convention(method) (@owned Klass, @sil_isolated @guaranteed MyActor) -> () {
176176
var k = Klass()
177177

178+
// CHECK: // static MyActor.f()
179+
// CHECK-NEXT: // Isolation: unspecified
180+
// CHECK-NEXT: sil hidden [ossa] @$s16assume_mainactor7MyActorC1fyyFZ : $@convention(method) (@thick MyActor.Type) -> ()
181+
static func f() {}
182+
183+
struct Nested {
184+
// CHECK: // MyActor.Nested.f()
185+
// CHECK-NEXT: // Isolation: unspecified
186+
// CHECK-NEXT: sil hidden [ossa] @$s16assume_mainactor7MyActorC6NestedV1fyyF : $@convention(method) (MyActor.Nested) -> ()
187+
func f() {}
188+
}
189+
178190
// Implicit deinit
179191
// CHECK: // MyActor.deinit
180-
// CHECK-NEXT: // Isolation: nonisolated
192+
// CHECK-NEXT: // Isolation: unspecified
181193
// CHECK-NEXT: sil hidden [ossa] @$s16assume_mainactor7MyActorCfd : $@convention(method) (@guaranteed MyActor) -> @owned Builtin.NativeObject {
182194

183195
// Non-async init should be nonisolated

test/Concurrency/assume_mainactor_typechecker_errors.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func unspecifiedFunctionTest2() async {
5151
}
5252

5353
nonisolated func nonisolatedFunctionTest() async {
54-
let k = StructContainingKlass()
54+
let k = await StructContainingKlass()
5555
await unspecifiedAsync(k.k) // expected-error {{non-sendable type 'Klass' of property 'k' cannot exit main actor-isolated context}}
5656
await nonisolatedAsync(k.k) // expected-error {{non-sendable type 'Klass' of property 'k' cannot exit main actor-isolated context}}
5757
await mainActorAsync(k.k) // expected-error {{non-sendable type 'Klass' of property 'k' cannot exit main actor-isolated context}}
@@ -66,7 +66,7 @@ func testTask() async {
6666

6767
func testTaskDetached() async {
6868
Task.detached {
69-
let k = Klass(getDataFromSocket())
69+
let k = await Klass(getDataFromSocket())
7070
// Have to pop back onto the main thread to do something.
7171
await k.doSomething()
7272
}

0 commit comments

Comments
 (0)