Skip to content

Commit f3a26b0

Browse files
authored
Merge pull request #36562 from DougGregor/initializer-no-infer-global-actor
[Actor isolation] Initializers don't infer global actor isolation.
2 parents 3f97abf + 81af954 commit f3a26b0

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)