Skip to content

Commit bf48fcf

Browse files
authored
Merge pull request #36548 from DougGregor/global-actor-unsafe-propagation
2 parents e770154 + b93688c commit bf48fcf

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,11 +2383,11 @@ static Optional<ActorIsolation> getIsolationFromAttributes(
23832383
}
23842384
}
23852385

2386-
// If the declaration is explicitly marked 'nonisolated', report it as
2387-
// independent.
2388-
if (nonisolatedAttr) {
2389-
return ActorIsolation::forIndependent(ActorIndependentKind::Safe);
2390-
}
2386+
// If the declaration is explicitly marked 'nonisolated', report it as
2387+
// independent.
2388+
if (nonisolatedAttr) {
2389+
return ActorIsolation::forIndependent(ActorIndependentKind::Safe);
2390+
}
23912391

23922392
// If the declaration is explicitly marked @actorIndependent, report it as
23932393
// independent.
@@ -2562,8 +2562,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
25622562
}
25632563

25642564
// Function used when returning an inferred isolation.
2565-
auto inferredIsolation = [&](
2566-
ActorIsolation inferred, bool propagateUnsafe = false) {
2565+
auto inferredIsolation = [&](ActorIsolation inferred) {
25672566
// Add an implicit attribute to capture the actor isolation that was
25682567
// inferred, so that (e.g.) it will be printed and serialized.
25692568
ASTContext &ctx = value->getASTContext();
@@ -2576,13 +2575,6 @@ ActorIsolation ActorIsolationRequest::evaluate(
25762575
break;
25772576

25782577
case ActorIsolation::GlobalActorUnsafe:
2579-
if (!propagateUnsafe && !value->hasClangNode()) {
2580-
// Don't infer unsafe global actor isolation.
2581-
return ActorIsolation::forUnspecified();
2582-
}
2583-
2584-
LLVM_FALLTHROUGH;
2585-
25862578
case ActorIsolation::GlobalActor: {
25872579
auto typeExpr = TypeExpr::createImplicit(inferred.getGlobalActor(), ctx);
25882580
auto attr = CustomAttr::create(
@@ -2631,7 +2623,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
26312623
if (auto wrapperInfo = var->getAttachedPropertyWrapperTypeInfo(0)) {
26322624
if (auto wrappedValue = wrapperInfo.valueVar) {
26332625
if (auto isolation = getActorIsolation(wrappedValue))
2634-
return inferredIsolation(isolation, /*propagateUnsafe=*/true);
2626+
return inferredIsolation(isolation);
26352627
}
26362628
}
26372629

@@ -2645,7 +2637,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
26452637
if (!isa<ClassDecl>(backingNominal) ||
26462638
!cast<ClassDecl>(backingNominal)->isActor()) {
26472639
if (auto isolation = getActorIsolation(backingNominal))
2648-
return inferredIsolation(isolation, /*propagateUnsafe=*/true);
2640+
return inferredIsolation(isolation);
26492641
}
26502642
}
26512643
}
@@ -2659,7 +2651,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
26592651
originalVar->getAttachedPropertyWrapperTypeInfo(0)) {
26602652
if (auto projectedValue = wrapperInfo.projectedValueVar) {
26612653
if (auto isolation = getActorIsolation(projectedValue))
2662-
return inferredIsolation(isolation, /*propagateUnsafe=*/true);
2654+
return inferredIsolation(isolation);
26632655
}
26642656
}
26652657
}
@@ -2669,8 +2661,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
26692661
// If the declaration witnesses a protocol requirement that is isolated,
26702662
// use that.
26712663
if (auto witnessedIsolation = getIsolationFromWitnessedRequirements(value)) {
2672-
if (auto inferred = inferredIsolation(
2673-
*witnessedIsolation, /*propagateUnsafe=*/defaultIsolation))
2664+
if (auto inferred = inferredIsolation(*witnessedIsolation))
26742665
return inferred;
26752666
}
26762667

@@ -2710,10 +2701,8 @@ ActorIsolation ActorIsolationRequest::evaluate(
27102701
// If the declaration is in a nominal type (or extension thereof) that
27112702
// has isolation, use that.
27122703
if (auto selfTypeDecl = value->getDeclContext()->getSelfNominalTypeDecl()) {
2713-
auto selfTypeIsolation = getActorIsolation(selfTypeDecl);
2714-
if (!selfTypeIsolation.isUnspecified()) {
2704+
if (auto selfTypeIsolation = getActorIsolation(selfTypeDecl))
27152705
return inferredIsolation(selfTypeIsolation);
2716-
}
27172706
}
27182707
}
27192708

test/Concurrency/actor_isolation_unsafe.swift

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,31 @@ struct S4_P1: P1 {
3333
@SomeGlobalActor func onMainActor() { } // expected-error{{instance method 'onMainActor()' isolated to global actor 'SomeGlobalActor' can not satisfy corresponding requirement from protocol 'P1' isolated to global actor 'MainActor'}}
3434
}
3535

36+
@MainActor(unsafe)
37+
protocol P2 {
38+
func f() // expected-note{{calls to instance method 'f()' from outside of its actor context are implicitly asynchronous}}
39+
@actorIndependent func g()
40+
}
41+
42+
struct S5_P2: P2 {
43+
func f() { } // expected-note{{calls to instance method 'f()' from outside of its actor context are implicitly asynchronous}}
44+
func g() { }
45+
}
46+
47+
@actorIndependent func testP2(x: S5_P2, p2: P2) {
48+
p2.f() // expected-error{{instance method 'f()' isolated to global actor 'MainActor' can not be referenced from a non-isolated synchronous context}}
49+
p2.g() // OKAY
50+
x.f() // expected-error{{'f()' isolated to global actor 'MainActor' can not be referenced from a non-isolated synchronous context}}
51+
x.g() // OKAY
52+
}
53+
54+
func testP2_noconcurrency(x: S5_P2, p2: P2) {
55+
p2.f() // okay, not concurrency-related code
56+
p2.g() // okay
57+
x.f() // okay, not concurrency-related code
58+
x.g() // OKAY
59+
}
60+
3661
// ----------------------------------------------------------------------
3762
// Overriding and unsafe global actor
3863
// ----------------------------------------------------------------------
@@ -41,7 +66,7 @@ class C1 {
4166
}
4267

4368
class C2: C1 {
44-
override func method() { // expected-note{{overridden declaration is here}}
69+
override func method() { // expected-note 2{{overridden declaration is here}}
4570
globalSome() // okay
4671
}
4772
}
@@ -65,14 +90,12 @@ class C5: C1 {
6590

6691
class C6: C2 {
6792
// We didn't infer any actor isolation for C2.method().
68-
@SomeGlobalActor override func method() { // expected-error{{global actor 'SomeGlobalActor'-isolated instance method 'method()' has different actor isolation from non-actor-isolated overridden declaration}}
93+
@SomeGlobalActor override func method() { // expected-error{{global actor 'SomeGlobalActor'-isolated instance method 'method()' has different actor isolation from global actor 'MainActor'-isolated overridden declaration}}
6994
}
7095
}
7196

7297
class C7: C2 {
73-
// We didn't infer any actor isolation for C2.method(), but it's okay to be
74-
// explicitly unsafe.
75-
@SomeGlobalActor(unsafe) override func method() {
98+
@SomeGlobalActor(unsafe) override func method() { // expected-error{{global actor 'SomeGlobalActor'-isolated instance method 'method()' has different actor isolation from global actor 'MainActor'-isolated overridden declaration}}
7699
globalMain() // expected-error{{global function 'globalMain()' isolated to global actor 'MainActor' can not be referenced from different global actor 'SomeGlobalActor'}}
77100
globalSome() // okay
78101
}

0 commit comments

Comments
 (0)