Skip to content

Commit c05dd0b

Browse files
authored
Merge pull request #70329 from xedin/keypath-with-global-actors-5.10
[5.10][Concurrency] Start diagnosing use of global actor isolated propertie…
2 parents c9d8622 + b9d9174 commit c05dd0b

File tree

5 files changed

+73
-21
lines changed

5 files changed

+73
-21
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5234,8 +5234,8 @@ ERROR(concurrent_access_local,none,
52345234
"use of local %kind0 in concurrently-executing code",
52355235
(const ValueDecl *))
52365236
ERROR(actor_isolated_keypath_component,none,
5237-
"cannot form key path to%select{| distributed}0 actor-isolated %kind1",
5238-
(bool, const ValueDecl *))
5237+
"cannot form key path to %0 %kind1",
5238+
(ActorIsolation, const ValueDecl *))
52395239
ERROR(effectful_keypath_component,none,
52405240
"cannot form key path to %0 with 'throws' or 'async'",
52415241
(DescriptiveDeclKind))

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3319,8 +3319,8 @@ namespace {
33193319
for (const auto &component : keyPath->getComponents()) {
33203320
// The decl referred to by the path component cannot be within an actor.
33213321
if (component.hasDeclRef()) {
3322-
auto concDecl = component.getDeclRef();
3323-
auto decl = concDecl.getDecl();
3322+
auto declRef = component.getDeclRef();
3323+
auto decl = declRef.getDecl();
33243324
auto isolation = getActorIsolationForReference(
33253325
decl, getDeclContext());
33263326
switch (isolation) {
@@ -3330,13 +3330,22 @@ namespace {
33303330
break;
33313331

33323332
case ActorIsolation::GlobalActor:
3333-
case ActorIsolation::GlobalActorUnsafe:
3334-
// Disable global actor checking for now.
3335-
if (isolation.isGlobalActor() &&
3336-
!ctx.LangOpts.isSwiftVersionAtLeast(6))
3333+
case ActorIsolation::GlobalActorUnsafe: {
3334+
// Perform the check only in `complete` mode or
3335+
// stricter.
3336+
if (ctx.LangOpts.StrictConcurrencyLevel <
3337+
StrictConcurrency::Complete)
3338+
break;
3339+
3340+
auto result = ActorReferenceResult::forReference(
3341+
declRef, component.getLoc(), getDeclContext(),
3342+
kindOfUsage(decl, keyPath));
3343+
3344+
if (result == ActorReferenceResult::SameConcurrencyDomain)
33373345
break;
33383346

33393347
LLVM_FALLTHROUGH;
3348+
}
33403349

33413350
case ActorIsolation::ActorInstance:
33423351
// If this entity is always accessible across actors, just check
@@ -3352,11 +3361,17 @@ namespace {
33523361
break;
33533362
}
33543363

3355-
ctx.Diags.diagnose(component.getLoc(),
3356-
diag::actor_isolated_keypath_component,
3357-
isolation.isDistributedActor(),
3358-
decl);
3359-
diagnosed = true;
3364+
{
3365+
auto diagnostic = ctx.Diags.diagnose(
3366+
component.getLoc(), diag::actor_isolated_keypath_component,
3367+
isolation, decl);
3368+
3369+
if (isolation == ActorIsolation::ActorInstance)
3370+
diagnosed = true;
3371+
else
3372+
diagnostic.warnUntilSwiftVersion(6);
3373+
}
3374+
33603375
break;
33613376
}
33623377
}

test/Concurrency/actor_keypath_isolation.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func tryKeyPathsMisc(d : Door) {
5858

5959
func tryKeyPathsFromAsync() async {
6060
_ = \Door.unsafeGlobActor_immutable
61-
_ = \Door.unsafeGlobActor_mutable // okay for now
61+
_ = \Door.unsafeGlobActor_mutable // expected-warning {{cannot form key path to main actor-isolated property 'unsafeGlobActor_mutable'; this is an error in Swift 6}}
6262
}
6363

6464
func tryNonSendable() {
@@ -69,7 +69,7 @@ func tryNonSendable() {
6969

7070
func tryKeypaths() {
7171
_ = \Door.unsafeGlobActor_immutable
72-
_ = \Door.unsafeGlobActor_mutable // okay for now
72+
_ = \Door.unsafeGlobActor_mutable // expected-warning {{cannot form key path to main actor-isolated property 'unsafeGlobActor_mutable'; this is an error in Swift 6}}
7373

7474
_ = \Door.immutable
7575
_ = \Door.globActor_immutable
@@ -84,7 +84,13 @@ func tryKeypaths() {
8484
let _ : PartialKeyPath<Door> = \.mutable // expected-error{{cannot form key path to actor-isolated property 'mutable'}}
8585
let _ : AnyKeyPath = \Door.mutable // expected-error{{cannot form key path to actor-isolated property 'mutable'}}
8686

87-
_ = \Door.globActor_mutable // okay for now
87+
_ = \Door.globActor_mutable // expected-warning {{cannot form key path to main actor-isolated property 'globActor_mutable'; this is an error in Swift 6}}
8888
_ = \Door.[0] // expected-error{{cannot form key path to actor-isolated subscript 'subscript(_:)'}}
89-
_ = \Door.["hello"] // okay for now
89+
_ = \Door.["hello"] // expected-warning {{cannot form key path to main actor-isolated subscript 'subscript(_:)'; this is an error in Swift 6}}
90+
}
91+
92+
@MainActor func testGlobalActorRefInSameContext() {
93+
_ = \Door.unsafeGlobActor_mutable // Ok
94+
_ = \Door.globActor_mutable // Ok
95+
_ = \Door.["hello"] // Ok
9096
}

test/Concurrency/actor_keypath_isolation_swift6.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func tryKeyPathsMisc(d : Door) {
5757

5858
func tryKeyPathsFromAsync() async {
5959
_ = \Door.unsafeGlobActor_immutable
60-
_ = \Door.unsafeGlobActor_mutable // expected-error {{cannot form key path to actor-isolated property 'unsafeGlobActor_mutable'}}
60+
_ = \Door.unsafeGlobActor_mutable // expected-error {{cannot form key path to main actor-isolated property 'unsafeGlobActor_mutable'}}
6161
}
6262

6363
func tryNonSendable() {
@@ -68,7 +68,7 @@ func tryNonSendable() {
6868

6969
func tryKeypaths() {
7070
_ = \Door.unsafeGlobActor_immutable
71-
_ = \Door.unsafeGlobActor_mutable // expected-error {{cannot form key path to actor-isolated property 'unsafeGlobActor_mutable'}}
71+
_ = \Door.unsafeGlobActor_mutable // expected-error {{cannot form key path to main actor-isolated property 'unsafeGlobActor_mutable'}}
7272

7373
_ = \Door.immutable
7474
_ = \Door.globActor_immutable
@@ -83,7 +83,13 @@ func tryKeypaths() {
8383
let _ : PartialKeyPath<Door> = \.mutable // expected-error{{cannot form key path to actor-isolated property 'mutable'}}
8484
let _ : AnyKeyPath = \Door.mutable // expected-error{{cannot form key path to actor-isolated property 'mutable'}}
8585

86-
_ = \Door.globActor_mutable // expected-error{{cannot form key path to actor-isolated property 'globActor_mutable'}}
86+
_ = \Door.globActor_mutable // expected-error{{cannot form key path to main actor-isolated property 'globActor_mutable'}}
8787
_ = \Door.[0] // expected-error{{cannot form key path to actor-isolated subscript 'subscript(_:)'}}
88-
_ = \Door.["hello"] // expected-error {{cannot form key path to actor-isolated subscript 'subscript(_:)'}}
88+
_ = \Door.["hello"] // expected-error {{cannot form key path to main actor-isolated subscript 'subscript(_:)'}}
89+
}
90+
91+
@MainActor func testGlobalActorRefInSameContext() {
92+
_ = \Door.unsafeGlobActor_mutable // Ok
93+
_ = \Door.globActor_mutable // Ok
94+
_ = \Door.["hello"] // Ok
8995
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-frontend -disable-availability-checking %s -emit-sil -o /dev/null -verify
2+
3+
// REQUIRES: concurrency && asserts
4+
5+
actor Door {
6+
@MainActor var globActor_mutable : Int = 0
7+
@MainActor(unsafe) var unsafeGlobActor_mutable : Int = 0
8+
@MainActor subscript(byName: String) -> Int { 0 }
9+
}
10+
11+
func tryKeyPathsFromAsync() async {
12+
_ = \Door.unsafeGlobActor_mutable // no warning
13+
}
14+
15+
func tryKeypaths() {
16+
_ = \Door.unsafeGlobActor_mutable // no warning
17+
_ = \Door.globActor_mutable // no warning
18+
_ = \Door.["hello"] // no warning
19+
}
20+
21+
@MainActor func testGlobalActorRefInSameContext() {
22+
_ = \Door.unsafeGlobActor_mutable // Ok
23+
_ = \Door.globActor_mutable // Ok
24+
_ = \Door.["hello"] // Ok
25+
}

0 commit comments

Comments
 (0)