Skip to content

Commit 94553fd

Browse files
committed
allow nonisolated + async + delegating actor inits.
1 parent 3e60e12 commit 94553fd

File tree

6 files changed

+34
-15
lines changed

6 files changed

+34
-15
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4706,9 +4706,6 @@ ERROR(nonisolated_local_var,none,
47064706
ERROR(nonisolated_actor_sync_init,none,
47074707
"'nonisolated' on an actor's synchronous initializer is invalid",
47084708
())
4709-
ERROR(nonisolated_actor_convenience_init,none,
4710-
"'nonisolated' on an actor's convenience initializer is redundant",
4711-
())
47124709

47134710
ERROR(actor_instance_property_wrapper,none,
47144711
"%0 property in property wrapper type %1 cannot be isolated to "

lib/Sema/TypeCheckAttr.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5643,17 +5643,13 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
56435643
}
56445644
}
56455645

5646-
// `nonisolated` on most actor initializers is invalid or redundant.
5646+
// `nonisolated` on non-async actor initializers is invalid
5647+
// the reasoning is that there is a "little bit" of isolation,
5648+
// as afforded by flow-isolation.
56475649
if (auto ctor = dyn_cast<ConstructorDecl>(D)) {
56485650
if (auto nominal = dyn_cast<NominalTypeDecl>(dc)) {
56495651
if (nominal->isAnyActor()) {
5650-
if (ctor->isConvenienceInit()) {
5651-
// all convenience inits are `nonisolated` by default
5652-
diagnoseAndRemoveAttr(attr, diag::nonisolated_actor_convenience_init)
5653-
.warnUntilSwiftVersion(6);
5654-
return;
5655-
5656-
} else if (!ctor->hasAsync()) {
5652+
if (!ctor->hasAsync()) {
56575653
// the isolation for a synchronous init cannot be `nonisolated`.
56585654
diagnoseAndRemoveAttr(attr, diag::nonisolated_actor_sync_init)
56595655
.warnUntilSwiftVersion(6);

test/Concurrency/actor_isolation.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,16 +1160,25 @@ class GenericSub2<T>: GenericSuper<[T]> { } // expected-error{{global actor 'Gen
11601160

11611161
/// Diagnostics for `nonisolated` on an actor initializer.
11621162
actor Butterfly {
1163+
var flapsPerSec = 0 // expected-note 3{{mutation of this property is only permitted within the actor}}
1164+
11631165
nonisolated init() {} // expected-warning {{'nonisolated' on an actor's synchronous initializer is invalid; this is an error in Swift 6}} {{3-15=}}
11641166

11651167
nonisolated init(async: Void) async {}
11661168

1167-
nonisolated convenience init(icecream: Void) { // expected-warning {{'nonisolated' on an actor's convenience initializer is redundant; this is an error in Swift 6}} {{3-15=}}
1169+
nonisolated convenience init(icecream: Void) { // expected-warning {{'nonisolated' on an actor's synchronous initializer is invalid; this is an error in Swift 6}} {{3-15=}}
1170+
self.init()
1171+
self.flapsPerSec += 1 // expected-error {{actor-isolated property 'flapsPerSec' can not be mutated from a non-isolated context}}
1172+
}
1173+
1174+
nonisolated convenience init(cookies: Void) async {
11681175
self.init()
1176+
self.flapsPerSec += 1 // expected-error {{actor-isolated property 'flapsPerSec' can not be mutated from a non-isolated context}}
11691177
}
11701178

1171-
nonisolated convenience init(cookies: Void) async { // expected-warning {{'nonisolated' on an actor's convenience initializer is redundant; this is an error in Swift 6}} {{3-15=}}
1179+
convenience init(brownies: Void) {
11721180
self.init()
1181+
self.flapsPerSec = 0 // expected-error {{actor-isolated property 'flapsPerSec' can not be mutated from a non-isolated context}}
11731182
}
11741183
}
11751184

test/Concurrency/concurrent_value_checking.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %target-typecheck-verify-swift -disable-availability-checking -warn-concurrency
22
// REQUIRES: concurrency
33

4-
class NotConcurrent { } // expected-note 26{{class 'NotConcurrent' does not conform to the 'Sendable' protocol}}
4+
class NotConcurrent { } // expected-note 27{{class 'NotConcurrent' does not conform to the 'Sendable' protocol}}
55

66
// ----------------------------------------------------------------------
77
// Sendable restriction on actor operations
@@ -37,6 +37,14 @@ actor A2 {
3737
await self.init(valueAsync: value)
3838
}
3939

40+
nonisolated convenience init(nonisoAsync value: NotConcurrent, _ c: Int) async {
41+
if c == 0 {
42+
await self.init(valueAsync: value)
43+
} else {
44+
self.init(value: value)
45+
}
46+
}
47+
4048
convenience init(delegatingAsync value: NotConcurrent, _ c: Int) async {
4149
if c == 0 {
4250
await self.init(valueAsync: value)
@@ -58,6 +66,8 @@ func testActorCreation(value: NotConcurrent) async {
5866
_ = A2(delegatingSync: value) // expected-warning{{non-sendable type 'NotConcurrent' passed in call to nonisolated initializer 'init(delegatingSync:)' cannot cross actor boundary}}
5967

6068
_ = await A2(delegatingAsync: value, 9) // expected-warning{{non-sendable type 'NotConcurrent' passed in call to actor-isolated initializer 'init(delegatingAsync:_:)' cannot cross actor boundary}}
69+
70+
_ = await A2(nonisoAsync: value, 3) // expected-warning{{non-sendable type 'NotConcurrent' passed in call to nonisolated initializer 'init(nonisoAsync:_:)' cannot cross actor boundary}}
6171
}
6272

6373
extension A1 {

test/Concurrency/flow_isolation.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,13 @@ actor MyActor {
392392
callMethod(self)
393393
}
394394

395+
convenience init(ci2 c: Bool) async {
396+
self.init(i1: c)
397+
self.x = 1
398+
callMethod(self)
399+
self.x = 0
400+
}
401+
395402
init(i1 c: Bool) {
396403
self.x = 0
397404
_ = self.x

test/Distributed/distributed_actor_isolation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ distributed actor DijonMustard {
197197

198198
func f() {} // expected-note {{distributed actor-isolated instance method 'f()' declared here}}
199199

200-
nonisolated convenience init(conv2: FakeActorSystem) { // expected-warning {{'nonisolated' on an actor's convenience initializer is redundant; this is an error in Swift 6}} {{3-15=}}
200+
nonisolated convenience init(conv2: FakeActorSystem) { // expected-warning {{'nonisolated' on an actor's synchronous initializer is invalid; this is an error in Swift 6}} {{3-15=}}
201201
self.init(system: conv2)
202202
}
203203
}

0 commit comments

Comments
 (0)