Skip to content

[Concurrency] Don't propagate global actor-ness to deinit #36972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions lib/Sema/TypeCheckConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2255,18 +2255,18 @@ namespace {

LLVM_FALLTHROUGH;

case ActorIsolationRestriction::GlobalActor:
// If we are within an initializer and are referencing a stored
// property on "self", we are not crossing actors.
if (isa<ConstructorDecl>(getDeclContext()) &&
isa<VarDecl>(member) && cast<VarDecl>(member)->hasStorage() &&
getReferencedSelf(base))
case ActorIsolationRestriction::GlobalActor: {
const bool isInitDeInit = isa<ConstructorDecl>(getDeclContext()) ||
isa<DestructorDecl>(getDeclContext());
// If we are within an initializer or deinitilizer and are referencing a
// stored property on "self", we are not crossing actors.
if (isInitDeInit && isa<VarDecl>(member) &&
cast<VarDecl>(member)->hasStorage() && getReferencedSelf(base))
return false;

return checkGlobalActorReference(
memberRef, memberLoc, isolation.getGlobalActor(),
isolation.isCrossActor, context);

}
case ActorIsolationRestriction::Unsafe:
// This case is hit when passing actor state inout to functions in some
// cases. The error is emitted by diagnoseInOutArg.
Expand Down Expand Up @@ -2745,13 +2745,13 @@ static Optional<MemberIsolationPropagation> getMemberIsolationPropagation(
case DeclKind::OpaqueType:
case DeclKind::Param:
case DeclKind::Module:
case DeclKind::Destructor:
return None;

case DeclKind::PatternBinding:
case DeclKind::EnumCase:
case DeclKind::EnumElement:
case DeclKind::Constructor:
case DeclKind::Destructor:
return MemberIsolationPropagation::GlobalActor;

case DeclKind::Func:
Expand Down
7 changes: 5 additions & 2 deletions test/Concurrency/actor_isolation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ struct GenericGlobalActor<T> {

@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
@MainActor func beets() { onions() } // expected-error{{call to global actor 'SomeGlobalActor'-isolated global function 'onions()' in a synchronous main actor-isolated context}}
// expected-note@-1{{calls to global function 'beets()' from outside of its actor context are implicitly asynchronous}}

@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
actor Crystal {
Expand Down Expand Up @@ -686,7 +687,7 @@ class SomeClassWithInits {
var mutableState: Int = 17
var otherMutableState: Int

static var shared = SomeClassWithInits() // expected-note{{static property declared here}}
static var shared = SomeClassWithInits() // expected-note 2{{static property declared here}}

init() { // expected-note{{calls to initializer 'init()' from outside of its actor context are implicitly asynchronous}}
self.mutableState = 42
Expand All @@ -696,7 +697,9 @@ class SomeClassWithInits {
}

deinit {
print(SomeClassWithInits.shared) // okay, we're actor-isolated
print(mutableState) // Okay, we're actor-isolated
print(SomeClassWithInits.shared) // expected-error{{static property 'shared' isolated to global actor 'MainActor' can not be referenced from this synchronous context}}
beets() //expected-error{{call to main actor-isolated global function 'beets()' in a synchronous nonisolated context}}
}

func isolated() { }
Expand Down