Skip to content

Commit 81af954

Browse files
committed
[Actor isolation] Initializers don't infer global actor isolation.
Initializers within a global-actor-isolated type are not inferred to be global-actor-isolated themselves, because that isn't generally what one wants: usually, you want to be able to create an instance of the type by calling the initializer from somewhere. Within such initializers, allow access to the stored properties on "self" regardless. Fixes rdar://75450300.
1 parent a4db7c8 commit 81af954

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,6 +2186,13 @@ namespace {
21862186
LLVM_FALLTHROUGH;
21872187

21882188
case ActorIsolationRestriction::GlobalActor:
2189+
// If we are within an initializer and are referencing a stored
2190+
// property on "self", we are not crossing actors.
2191+
if (isa<ConstructorDecl>(getDeclContext()) &&
2192+
isa<VarDecl>(member) && cast<VarDecl>(member)->hasStorage() &&
2193+
getReferencedSelf(base))
2194+
return false;
2195+
21892196
return checkGlobalActorReference(
21902197
memberRef, memberLoc, isolation.getGlobalActor(),
21912198
isolation.isCrossActor, context);
@@ -2688,8 +2695,8 @@ ActorIsolation ActorIsolationRequest::evaluate(
26882695
}
26892696
}
26902697

2691-
// Instance members and initializers can infer isolation from their context.
2692-
if (value->isInstanceMember() || isa<ConstructorDecl>(value)) {
2698+
// Instance members infer isolation from their context.
2699+
if (value->isInstanceMember()) {
26932700
// If the declaration is in an extension that has one of the isolation
26942701
// attributes, use that.
26952702
if (auto ext = dyn_cast<ExtensionDecl>(value->getDeclContext())) {

test/Concurrency/actor_isolation.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,10 +651,10 @@ class SomeClassWithInits {
651651
self.mutableState = 42
652652
self.otherMutableState = 17
653653

654-
self.isolated()
654+
self.isolated() // expected-error{{'isolated()' isolated to global actor 'MainActor' can not be referenced from this synchronous context}}
655655
}
656656

657-
func isolated() { }
657+
func isolated() { } // expected-note{{calls to instance method 'isolated()' from outside of its actor context are implicitly asynchronous}}
658658

659659
func hasDetached() {
660660
Task.runDetached {
@@ -668,6 +668,10 @@ class SomeClassWithInits {
668668
}
669669
}
670670

671+
func outsideSomeClassWithInits() {
672+
_ = SomeClassWithInits() // okay, initializer is not isolated
673+
}
674+
671675
// ----------------------------------------------------------------------
672676
// Actor protocols.
673677
// ----------------------------------------------------------------------

0 commit comments

Comments
 (0)