From 546f66b1059a63a1caf17033b98e5138402334ab Mon Sep 17 00:00:00 2001 From: Konrad Malawski Date: Mon, 8 Dec 2025 11:30:12 +0900 Subject: [PATCH] [Concurrency] warn about 'final' on actors being ineffective --- include/swift/AST/DiagnosticsSema.def | 3 +++ lib/Sema/TypeCheckDeclPrimary.cpp | 8 +++++++- test/Distributed/distributed_actor_basic.swift | 2 ++ test/Interop/SwiftToCxx/class/swift-actor-in-cxx.swift | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 116e11f825d1e..8b633708d456b 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -5699,6 +5699,9 @@ ERROR(async_objc_dynamic_self,none, ERROR(actor_inheritance,none, "%select{actor|distributed actor}0 types do not support inheritance", (bool)) +WARNING(actor_final_no_effect,none, + "'final' on %kind0 has no effect", + (const ValueDecl*)) ERROR(actor_protocol_illegal_inheritance,none, "non-actor type %0 cannot conform to the %1 protocol", diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index 6c3c4466a2d99..9e9ce1f5f998c 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -3284,9 +3284,15 @@ class DeclChecker : public DeclVisitor { TypeChecker::checkDeclAttributes(CD); - if (CD->isActor()) + if (CD->isActor()) { TypeChecker::checkConcurrencyAvailability(CD->getLoc(), CD); + if (CD->isFinal()) { + CD->diagnose(diag::actor_final_no_effect, CD) + .fixItRemove(CD->getAttrs().getAttribute()->getLocation()); + } + } + for (Decl *Member : CD->getABIMembers()) visit(Member); diff --git a/test/Distributed/distributed_actor_basic.swift b/test/Distributed/distributed_actor_basic.swift index 868e169298484..85d8c32b5a67e 100644 --- a/test/Distributed/distributed_actor_basic.swift +++ b/test/Distributed/distributed_actor_basic.swift @@ -23,3 +23,5 @@ distributed actor Second { try! await first.one(second: self) } } + +final distributed actor WarnAboutMe { } // expected-warning{{'final' on distributed actor 'WarnAboutMe' has no effect}} diff --git a/test/Interop/SwiftToCxx/class/swift-actor-in-cxx.swift b/test/Interop/SwiftToCxx/class/swift-actor-in-cxx.swift index 52e5c26cd8564..f2f6d1f4910d7 100644 --- a/test/Interop/SwiftToCxx/class/swift-actor-in-cxx.swift +++ b/test/Interop/SwiftToCxx/class/swift-actor-in-cxx.swift @@ -16,7 +16,7 @@ // REQUIRES: concurrency @_expose(Cxx) -public final actor ActorWithField { +public final actor ActorWithField { // expected-warning{{'final' on actor 'ActorWithField' has no effect}} var field: Int64 public init() {