Skip to content

Commit 03a1f62

Browse files
committed
[SE-0316] Non-final classes cannot be global actors
(cherry picked from commit 83050d6)
1 parent 200b442 commit 03a1f62

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
@@ -4545,6 +4545,8 @@ ERROR(global_actor_on_local_variable,none,
45454545
"local variable %0 cannot have a global actor", (DeclName))
45464546
ERROR(global_actor_non_unsafe_init,none,
45474547
"global actor attribute %0 argument can only be '(unsafe)'", (Type))
4548+
ERROR(global_actor_non_final_class,none,
4549+
"non-final class %0 cannot be a global actor", (DeclName))
45484550

45494551
ERROR(actor_isolation_multiple_attr,none,
45504552
"%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
@@ -313,8 +313,17 @@ VarDecl *GlobalActorInstanceRequest::evaluate(
313313
return nullptr;
314314
}
315315

316+
// Non-final classes cannot be global actors.
317+
if (auto classDecl = dyn_cast<ClassDecl>(nominal)) {
318+
if (!classDecl->isSemanticallyFinal()) {
319+
nominal->diagnose(diag::global_actor_non_final_class, nominal->getName())
320+
.highlight(globalActorAttr->getRangeWithAt());
321+
}
322+
}
323+
316324
// Global actors have a static property "shared" that provides an actor
317-
// instance. The value must
325+
// instance. The value must be of Actor type, which is validated by
326+
// conformance to the 'GlobalActor' protocol.
318327
SmallVector<ValueDecl *, 4> decls;
319328
nominal->lookupQualified(
320329
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)