Skip to content

Commit c6282ce

Browse files
authored
Merge pull request #58473 from ktoso/wip-explicitly-ban-class-anyactor
[Concurrency] Explicitly ban a class extending AnyActor as well
2 parents 5480577 + 60ef959 commit c6282ce

File tree

9 files changed

+52
-15
lines changed

9 files changed

+52
-15
lines changed

include/swift/AST/DiagnosticsSema.def

+2-2
Original file line numberDiff line numberDiff line change
@@ -4495,8 +4495,8 @@ ERROR(actor_inheritance,none,
44954495
(bool))
44964496

44974497
ERROR(actor_protocol_illegal_inheritance,none,
4498-
"non-actor type %0 cannot conform to the 'Actor' protocol",
4499-
(DeclName))
4498+
"non-actor type %0 cannot conform to the %1 protocol",
4499+
(DeclName, DeclName))
45004500
ERROR(distributed_actor_conformance_missing_system_type,none,
45014501
"distributed actor %0 does not declare ActorSystem it can be used with.",
45024502
(DeclName))

include/swift/AST/KnownProtocols.def

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
BUILTIN_EXPRESSIBLE_BY_LITERAL_PROTOCOL_WITH_NAME(name, "_" #name)
6060

6161
PROTOCOL(Actor)
62+
PROTOCOL(AnyActor)
6263
PROTOCOL(Sequence)
6364
PROTOCOL(Identifiable)
6465
PROTOCOL(IteratorProtocol)

lib/IRGen/GenMeta.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -5770,6 +5770,7 @@ SpecialProtocol irgen::getSpecialProtocolID(ProtocolDecl *P) {
57705770
case KnownProtocolKind::Differentiable:
57715771
case KnownProtocolKind::FloatingPoint:
57725772
case KnownProtocolKind::Identifiable:
5773+
case KnownProtocolKind::AnyActor:
57735774
case KnownProtocolKind::Actor:
57745775
case KnownProtocolKind::DistributedActor:
57755776
case KnownProtocolKind::DistributedActorSystem:

lib/Sema/TypeCheckProtocol.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -6445,7 +6445,19 @@ void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
64456445
if (!classDecl->isExplicitActor()) {
64466446
dc->getSelfNominalTypeDecl()
64476447
->diagnose(diag::actor_protocol_illegal_inheritance,
6448-
dc->getSelfNominalTypeDecl()->getName())
6448+
dc->getSelfNominalTypeDecl()->getName(),
6449+
proto->getName())
6450+
.fixItReplace(nominal->getStartLoc(), "actor");
6451+
}
6452+
}
6453+
} else if (proto->isSpecificProtocol(KnownProtocolKind::AnyActor)) {
6454+
if (auto classDecl = dyn_cast<ClassDecl>(nominal)) {
6455+
if (!classDecl->isExplicitActor() &&
6456+
!classDecl->isExplicitDistributedActor()) {
6457+
dc->getSelfNominalTypeDecl()
6458+
->diagnose(diag::actor_protocol_illegal_inheritance,
6459+
dc->getSelfNominalTypeDecl()->getName(),
6460+
proto->getName())
64496461
.fixItReplace(nominal->getStartLoc(), "actor");
64506462
}
64516463
}

stdlib/public/Concurrency/Actor.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ static void traceJobQueue(DefaultActorImpl *actor, Job *first) {
10661066
static SWIFT_ATTRIBUTE_ALWAYS_INLINE void traceActorStateTransition(DefaultActorImpl *actor,
10671067
ActiveActorStatus oldState, ActiveActorStatus newState) {
10681068

1069-
SWIFT_TASK_DEBUG_LOG("Actor %p transitioned from %#x to %#x (%s)\n", actor,
1069+
SWIFT_TASK_DEBUG_LOG("Actor %p transitioned from %#x to %#x (%s)", actor,
10701070
oldState.getOpaqueFlags(), newState.getOpaqueFlags(),
10711071
__FUNCTION__);
10721072
newState.traceStateChanged(actor);

test/Concurrency/actor_isolation.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,8 @@ actor A: Actor { // ok
10531053
@available(SwiftStdlib 5.1, *)
10541054
class C: Actor, UnsafeSendable {
10551055
// expected-error@-1{{non-actor type 'C' cannot conform to the 'Actor' protocol}}
1056-
// expected-warning@-2{{'UnsafeSendable' is deprecated: Use @unchecked Sendable instead}}
1056+
// expected-error@-2{{non-actor type 'C' cannot conform to the 'AnyActor' protocol}}
1057+
// expected-warning@-3{{'UnsafeSendable' is deprecated: Use @unchecked Sendable instead}}
10571058
nonisolated var unownedExecutor: UnownedSerialExecutor {
10581059
fatalError()
10591060
}

test/Distributed/actor_protocols.swift

+25-7
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ typealias DefaultDistributedActorSystem = FakeActorSystem
1414
actor A: Actor {} // ok
1515

1616
class C: Actor, UnsafeSendable {
17-
// expected-error@-1{{non-actor type 'C' cannot conform to the 'Actor' protocol}} {{1-6=actor}}
18-
// expected-warning@-2{{'UnsafeSendable' is deprecated: Use @unchecked Sendable instead}}
17+
// expected-error@-1{{non-actor type 'C' cannot conform to the 'AnyActor' protocol}} {{1-6=actor}}
18+
// expected-error@-2{{non-actor type 'C' cannot conform to the 'Actor' protocol}} {{1-6=actor}}
19+
// expected-warning@-3{{'UnsafeSendable' is deprecated: Use @unchecked Sendable instead}}
1920
nonisolated var unownedExecutor: UnownedSerialExecutor {
2021
fatalError()
2122
}
@@ -43,10 +44,10 @@ distributed actor DA: DistributedActor {
4344
typealias ActorSystem = FakeActorSystem
4445
}
4546

46-
// FIXME(distributed): error reporting is a bit whacky here; needs cleanup
47-
// expected-error@+2{{actor type 'A2' cannot conform to the 'DistributedActor' protocol. Isolation rules of these actor types are not interchangeable.}}
48-
// expected-error@+1{{actor type 'A2' cannot conform to the 'DistributedActor' protocol. Isolation rules of these actor types are not interchangeable.}}
4947
actor A2: DistributedActor {
48+
// FIXME(distributed): error reporting is a bit whacky here; needs cleanup
49+
// expected-error@-2{{actor type 'A2' cannot conform to the 'DistributedActor' protocol. Isolation rules of these actor types are not interchangeable.}}
50+
// expected-error@-3{{actor type 'A2' cannot conform to the 'DistributedActor' protocol. Isolation rules of these actor types are not interchangeable.}}
5051
nonisolated var id: ID {
5152
fatalError()
5253
}
@@ -63,8 +64,9 @@ actor A2: DistributedActor {
6364
}
6465
}
6566

66-
// expected-error@+1{{non-distributed actor type 'C2' cannot conform to the 'DistributedActor' protocol}}
67-
final class C2: DistributedActor {
67+
final class DA2: DistributedActor {
68+
// expected-error@-1{{non-actor type 'DA2' cannot conform to the 'AnyActor' protocol}}
69+
// expected-error@-2{{non-distributed actor type 'DA2' cannot conform to the 'DistributedActor' protocol}}
6870
nonisolated var id: ID {
6971
fatalError()
7072
}
@@ -86,3 +88,19 @@ struct S2: DistributedActor {
8688
// expected-error@-3{{type 'S2' does not conform to protocol 'Identifiable'}}
8789
}
8890

91+
// ==== -----------------------------------------------------------------------
92+
93+
actor A3: AnyActor {} // ok
94+
distributed actor DA3: AnyActor {} // ok
95+
96+
class C3: AnyActor, @unchecked Sendable {
97+
// expected-error@-1{{non-actor type 'C3' cannot conform to the 'AnyActor' protocol}} {{1-6=actor}}
98+
}
99+
100+
struct S3: AnyActor {
101+
// expected-error@-1{{non-class type 'S3' cannot conform to class protocol 'AnyActor'}}
102+
}
103+
104+
enum E3: AnyActor {
105+
// expected-error@-1{{non-class type 'E3' cannot conform to class protocol 'AnyActor'}}
106+
}

test/decl/class/actor/basic.swift

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ actor MyActor { }
77
class MyActorSubclass1: MyActor { }
88
// expected-error@-1{{actor types do not support inheritance}}
99
// expected-error@-2{{type 'MyActorSubclass1' cannot conform to the 'Actor' protocol}}
10+
// expected-error@-3{{non-actor type 'MyActorSubclass1' cannot conform to the 'AnyActor' protocol}}
1011

1112
actor MyActorSubclass2: MyActor { } // expected-error{{actor types do not support inheritance}}
1213

test/decl/protocol/special/Actor.swift

+6-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ actor A7 {
4444
@available(SwiftStdlib 5.1, *)
4545
class C1: Actor {
4646
// expected-error@-1{{non-actor type 'C1' cannot conform to the 'Actor' protocol}}
47-
// expected-warning@-2{{non-final class 'C1' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
47+
// expected-error@-2{{non-actor type 'C1' cannot conform to the 'AnyActor' protocol}}
48+
// expected-warning@-3{{non-final class 'C1' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
4849
nonisolated var unownedExecutor: UnownedSerialExecutor {
4950
fatalError("")
5051
}
@@ -53,7 +54,8 @@ class C1: Actor {
5354
@available(SwiftStdlib 5.1, *)
5455
class C2: Actor {
5556
// expected-error@-1{{non-actor type 'C2' cannot conform to the 'Actor' protocol}}
56-
// expected-warning@-2{{non-final class 'C2' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
57+
// expected-error@-2{{non-actor type 'C2' cannot conform to the 'AnyActor' protocol}}
58+
// expected-warning@-3{{non-final class 'C2' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
5759
// FIXME: this should be an isolation violation
5860
var unownedExecutor: UnownedSerialExecutor {
5961
fatalError("")
@@ -64,7 +66,8 @@ class C2: Actor {
6466
class C3: Actor {
6567
// expected-error@-1{{type 'C3' does not conform to protocol 'Actor'}}
6668
// expected-error@-2{{non-actor type 'C3' cannot conform to the 'Actor' protocol}}
67-
// expected-warning@-3{{non-final class 'C3' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
69+
// expected-error@-3{{non-actor type 'C3' cannot conform to the 'AnyActor' protocol}}
70+
// expected-warning@-4{{non-final class 'C3' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
6871
nonisolated func enqueue(_ job: UnownedJob) { }
6972
}
7073

0 commit comments

Comments
 (0)