Skip to content

Commit 83050d6

Browse files
committed
[SE-0316] Non-final classes cannot be global actors
1 parent 9ec2077 commit 83050d6

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4608,6 +4608,8 @@ ERROR(global_actor_on_local_variable,none,
46084608
"local variable %0 cannot have a global actor", (DeclName))
46094609
ERROR(global_actor_non_unsafe_init,none,
46104610
"global actor attribute %0 argument can only be '(unsafe)'", (Type))
4611+
ERROR(global_actor_non_final_class,none,
4612+
"non-final class %0 cannot be a global actor", (DeclName))
46114613

46124614
ERROR(actor_isolation_multiple_attr,none,
46134615
"%0 %1 has multiple actor-isolation attributes ('%2' and '%3')",

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,17 @@ VarDecl *GlobalActorInstanceRequest::evaluate(
142142
return nullptr;
143143
}
144144

145+
// Non-final classes cannot be global actors.
146+
if (auto classDecl = dyn_cast<ClassDecl>(nominal)) {
147+
if (!classDecl->isSemanticallyFinal()) {
148+
nominal->diagnose(diag::global_actor_non_final_class, nominal->getName())
149+
.highlight(globalActorAttr->getRangeWithAt());
150+
}
151+
}
152+
145153
// Global actors have a static property "shared" that provides an actor
146-
// instance. The value must
154+
// instance. The value must be of Actor type, which is validated by
155+
// conformance to the 'GlobalActor' protocol.
147156
SmallVector<ValueDecl *, 4> decls;
148157
nominal->lookupQualified(
149158
nominal, DeclNameRef(ctx.Id_shared), NL_QualifiedDefault, decls);

test/attr/global_actor.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct GenericGlobalActor<T> {
2020

2121
// Ill-formed global actors.
2222
@globalActor
23-
open class GA2 { // expected-error{{type 'GA2' does not conform to protocol 'GlobalActor'}}
23+
final class GA2 { // expected-error{{type 'GA2' does not conform to protocol 'GlobalActor'}}
2424
}
2525

2626
@globalActor
@@ -35,7 +35,7 @@ struct GA4 {
3535
}
3636

3737
@globalActor
38-
open class GA5 {
38+
open class GA5 { // expected-error{{non-final class 'GA5' cannot be a global actor}}
3939
static let shared = SomeActor() // expected-error{{property 'shared' must be declared public because it matches a requirement in public protocol 'GlobalActor'}}
4040
// expected-note@-1{{mark the static property as 'public' to satisfy the requirement}}
4141
}
@@ -49,7 +49,7 @@ extension GA6 where T: Equatable {
4949
}
5050

5151
@globalActor
52-
class GA7 { // expected-error{{type 'GA7' does not conform to protocol 'GlobalActor'}}
52+
final class GA7 { // expected-error{{type 'GA7' does not conform to protocol 'GlobalActor'}}
5353
static let shared = 5 // expected-note{{candidate would match and infer 'ActorType' = 'Int' if 'Int' conformed to 'Actor'}}
5454
}
5555

0 commit comments

Comments
 (0)