Skip to content

Commit eb71bbd

Browse files
committed
[Concurrency] add fixit to add final to non-sendable class -> Sendable
The previous message was just suggesting unchecked Sendable, but instead we should be suggesting to add final to the class. We also don't outright suggest using unchecked Sendable -- following swiftlang#81738 precedent. Resolves rdar://155790695
1 parent d7808f7 commit eb71bbd

File tree

10 files changed

+17
-18
lines changed

10 files changed

+17
-18
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5898,8 +5898,7 @@ ERROR(concurrent_value_outside_source_file,none,
58985898
"%kind0; use '@unchecked Sendable' for retroactive conformance",
58995899
(const ValueDecl *))
59005900
ERROR(concurrent_value_nonfinal_class,none,
5901-
"non-final class %0 cannot conform to 'Sendable'; "
5902-
"use '@unchecked Sendable'", (DeclName))
5901+
"non-final class %0 can not conform to the 'Sendable' protocol", (DeclName))
59035902
ERROR(concurrent_value_inherit,none,
59045903
"'Sendable' class %1 cannot inherit from another class"
59055904
"%select{| other than 'NSObject'}0",

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7270,9 +7270,9 @@ bool swift::checkSendableConformance(
72707270

72717271
// An non-final class cannot conform to `Sendable`.
72727272
if (!classDecl->isSemanticallyFinal()) {
7273-
classDecl->diagnose(diag::concurrent_value_nonfinal_class,
7274-
classDecl->getName())
7275-
.limitBehaviorUntilSwiftVersion(behavior, 6);
7273+
classDecl->diagnose(diag::concurrent_value_nonfinal_class,classDecl->getName())
7274+
.fixItInsert(classDecl->getStartLoc(), "final")
7275+
.limitBehaviorUntilSwiftVersion(behavior, 6);
72767276

72777277
if (behavior == DiagnosticBehavior::Unspecified)
72787278
return true;

test/Concurrency/concurrency_warnings.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ let rs = GlobalCounter() // expected-warning {{let 'rs' is not concurrency-safe
1717

1818
import GlobalVariables
1919

20-
class MyError: Error { // expected-warning{{non-final class 'MyError' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
20+
class MyError: Error { // expected-warning{{non-final class 'MyError' can not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode}}
2121
var storage = 0 // expected-warning{{stored property 'storage' of 'Sendable'-conforming class 'MyError' is mutable}}
2222
}
2323

test/Concurrency/concurrent_value_checking.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ extension C6_Restated_Extension: @unchecked Sendable {}
377377

378378
final class C7<T>: Sendable { }
379379

380-
class C9: Sendable { } // expected-warning{{non-final class 'C9' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
380+
class C9: Sendable { } // expected-warning{{non-final class 'C9' can not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode}}
381381

382382
@available(*, unavailable)
383383
extension HasUnavailableSendable : @unchecked Sendable { }

test/Concurrency/sendable_conformance_checking.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ actor A10: AsyncThrowingProtocolWithNotSendable {
158158
}
159159

160160
// rdar://86653457 - Crash due to missing Sendable conformances.
161-
// expected-warning @+1 {{non-final class 'Klass' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
161+
// expected-warning @+1 {{non-final class 'Klass' can not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode}}
162162
class Klass<Output: Sendable>: Sendable {}
163163
// expected-complete-and-tns-warning @+1 {{type 'S' does not conform to the 'Sendable' protocol}}
164164
final class SubKlass: Klass<[S]> {}
@@ -184,7 +184,7 @@ extension MultiConformance: @unchecked Sendable {} // expected-warning {{redunda
184184

185185
@available(SwiftStdlib 5.1, *)
186186
actor MyActor {
187-
// expected-warning@+1 {{non-final class 'Nested' cannot conform to 'Sendable'; use '@unchecked Sendable'; this is an error in the Swift 6 language mode}}
187+
// expected-warning@+1 {{non-final class 'Nested' can not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode}}
188188
class Nested: Sendable {}
189189
}
190190

test/Concurrency/sendable_objc_protocol_attr.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ extension MyObjCProtocol {
4141
}
4242

4343
class K : NSObject, MyObjCProtocol {
44-
// expected-warning@-1 {{non-final class 'K' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
44+
// expected-warning@-1 {{non-final class 'K' can not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode}}
4545
let test: String = "k"
4646
}
4747

@@ -50,7 +50,7 @@ class UncheckedK : NSObject, MyObjCProtocol, @unchecked Sendable { // ok
5050
}
5151

5252
class KRefined : NSObject, MyRefinedObjCProtocol {
53-
// expected-warning@-1 {{non-final class 'KRefined' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
53+
// expected-warning@-1 {{non-final class 'KRefined' can not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode}}
5454
let test: String = "refined"
5555
}
5656

@@ -76,7 +76,7 @@ do {
7676
}
7777

7878
class C : A, MyObjCProtocol {
79-
// expected-warning@-1 {{non-final class 'C' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
79+
// expected-warning@-1 {{non-final class 'C' can not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode}}
8080
// expected-warning@-2 {{'Sendable' class 'C' cannot inherit from another class other than 'NSObject'}}
8181
let test: String = "c"
8282
}

test/Distributed/actor_protocols.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ actor A3: AnyActor {} // expected-warning {{'AnyActor' is deprecated: Use 'any A
9595
distributed actor DA3: AnyActor {} // expected-warning {{'AnyActor' is deprecated: Use 'any Actor' with 'DistributedActor.asLocalActor' instead}}
9696

9797
class C3: AnyActor { // expected-warning {{'AnyActor' is deprecated: Use 'any Actor' with 'DistributedActor.asLocalActor' instead}}
98-
// expected-warning@-1 {{non-final class 'C3' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
98+
// expected-warning@-1 {{non-final class 'C3' cannot conform to 'Sendable'}}
9999
}
100100

101101
struct S3: AnyActor { // expected-warning {{'AnyActor' is deprecated: Use 'any Actor' with 'DistributedActor.asLocalActor' instead}}

test/Macros/macro_expand_extensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ macro AddSendable() = #externalMacro(module: "MacroDefinition", type: "SendableM
269269
final class SendableClass {
270270
}
271271

272-
// expected-warning@+2 {{non-final class 'InvalidSendableClass' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
272+
// expected-warning@+2 {{non-final class 'InvalidSendableClass' cannot conform to 'Sendable'}}
273273
@AddSendable
274274
class InvalidSendableClass {
275275
}

test/decl/class/actor/basic.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +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-warning@-3 {{non-final class 'MyActorSubclass1' cannot conform to 'Sendable'; use '@unchecked Sendable'; this is an error in the Swift 6 language mode}}
10+
// expected-warning@-3 {{non-final class 'MyActorSubclass1' cannot conform to 'Sendable'; this is an error in the Swift 6 language mode}}
1111

1212
actor MyActorSubclass2: MyActor { } // expected-error{{actor types do not support inheritance}}
1313

test/decl/protocol/special/Actor.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ 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-warning@-2{{non-final class 'C1' cannot conform to 'Sendable'}}
4848
nonisolated var unownedExecutor: UnownedSerialExecutor {
4949
fatalError("")
5050
}
@@ -53,7 +53,7 @@ class C1: Actor {
5353
@available(SwiftStdlib 5.1, *)
5454
class C2: Actor {
5555
// 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'}}
56+
// expected-warning@-2{{non-final class 'C2' cannot conform to 'Sendable'}}
5757
// FIXME: this should be an isolation violation
5858
var unownedExecutor: UnownedSerialExecutor {
5959
fatalError("")
@@ -65,7 +65,7 @@ class C3: Actor {
6565
// expected-error@-1{{type 'C3' does not conform to protocol 'Actor'}}
6666
// expected-note@-2{{add stubs for conformance}}
6767
// expected-error@-3{{non-actor type 'C3' cannot conform to the 'Actor' protocol}}
68-
// expected-warning@-4{{non-final class 'C3' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
68+
// expected-warning@-4{{non-final class 'C3' cannot conform to 'Sendable'}}
6969
nonisolated func enqueue(_ job: UnownedJob) { }
7070
}
7171

0 commit comments

Comments
 (0)