Skip to content

Commit d8c5ed7

Browse files
committed
Reinforce the Sendable requirement on sync actor inits
With the change I made to say that synchronous actor inits that are otherwise not isolated to anything else should be `nonisolated`, we lost the Sendable checking on its parameters. This patch brings that back by enforcing a CrossActorSelf restriction for accesses to such decls, despite them having `nonisolated` isolation.
1 parent 5e5af90 commit d8c5ed7

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,14 @@ ActorIsolationRestriction ActorIsolationRestriction::forDeclaration(
424424
}
425425

426426
case ActorIsolation::Independent:
427+
// While some synchronous, non-delegating actor inits are
428+
// nonisolated, they need cross-actor restrictions (e.g., for Sendable).
429+
if (auto *ctor = dyn_cast<ConstructorDecl>(decl))
430+
if (!ctor->isConvenienceInit())
431+
if (auto *parent = dyn_cast<ClassDecl>(ctor->getParent()))
432+
if (parent->isAnyActor())
433+
return forActorSelf(parent, /*isCrossActor=*/true);
434+
427435
return forUnrestricted();
428436

429437
case ActorIsolation::Unspecified:

test/Concurrency/concurrent_value_checking.swift

Lines changed: 15 additions & 2 deletions
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 18{{class 'NotConcurrent' does not conform to the 'Sendable' protocol}}
4+
class NotConcurrent { } // expected-note 21{{class 'NotConcurrent' does not conform to the 'Sendable' protocol}}
55

66
// ----------------------------------------------------------------------
77
// Sendable restriction on actor operations
@@ -19,10 +19,23 @@ actor A2 {
1919
init(value: NotConcurrent) {
2020
self.localVar = value
2121
}
22+
23+
init(valueAsync value: NotConcurrent) async {
24+
self.localVar = value
25+
}
26+
27+
convenience init(delegatingSync value: NotConcurrent) {
28+
self.init(value: value) // expected-warning{{cannot pass argument of non-sendable type 'NotConcurrent' across actors}}
29+
}
30+
31+
convenience init(delegatingAsync value: NotConcurrent) async {
32+
await self.init(valueAsync: value) // expected-warning{{cannot pass argument of non-sendable type 'NotConcurrent' across actors}}
33+
}
2234
}
2335

24-
func testActorCreation(value: NotConcurrent) {
36+
func testActorCreation(value: NotConcurrent) async {
2537
_ = A2(value: value) // expected-warning{{cannot pass argument of non-sendable type 'NotConcurrent' across actors}}
38+
_ = await A2(valueAsync: value) // expected-warning{{cannot pass argument of non-sendable type 'NotConcurrent' across actors}}
2639
}
2740

2841
extension A1 {

0 commit comments

Comments
 (0)