Skip to content

Commit bc41ce2

Browse files
committed
SE-0302: Limit ConcurrentValue on classes to final classes
1 parent 258d47a commit bc41ce2

File tree

4 files changed

+17
-27
lines changed

4 files changed

+17
-27
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4360,11 +4360,11 @@ WARNING(concurrent_value_outside_source_file_warn,none,
43604360
"conformance to 'ConcurrentValue' must occur in the same source file as "
43614361
"%0 %1; use 'UnsafeConcurrentValue' for retroactive conformance",
43624362
(DescriptiveDeclKind, DeclName))
4363-
ERROR(concurrent_value_open_class,none,
4364-
"open class %0 cannot conform to `ConcurrentValue`; "
4363+
ERROR(concurrent_value_nonfinal_class,none,
4364+
"non-final class %0 cannot conform to `ConcurrentValue`; "
43654365
"use `UnsafeConcurrentValue`", (DeclName))
4366-
WARNING(concurrent_value_open_class_warn,none,
4367-
"open class %0 cannot conform to `ConcurrentValue`; "
4366+
WARNING(concurrent_value_nonfinal_class_warn,none,
4367+
"non-final class %0 cannot conform to `ConcurrentValue`; "
43684368
"use `UnsafeConcurrentValue`", (DeclName))
43694369
ERROR(concurrent_value_inherit,none,
43704370
"`ConcurrentValue` class %1 cannot inherit from another class"

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2483,11 +2483,11 @@ bool swift::checkConcurrentValueConformance(
24832483
}
24842484

24852485
if (classDecl) {
2486-
// An open class cannot conform to `ConcurrentValue`.
2487-
if (classDecl->getFormalAccess() == AccessLevel::Open) {
2486+
// An non-final class cannot conform to `ConcurrentValue`.
2487+
if (!classDecl->isFinal()) {
24882488
classDecl->diagnose(
2489-
asWarning ? diag::concurrent_value_open_class_warn
2490-
: diag::concurrent_value_open_class,
2489+
asWarning ? diag::concurrent_value_nonfinal_class_warn
2490+
: diag::concurrent_value_nonfinal_class,
24912491
classDecl->getName());
24922492

24932493
if (!asWarning)

test/Concurrency/concurrent_value_checking.swift

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -215,21 +215,19 @@ enum E2<T> {
215215

216216
extension E2: ConcurrentValue where T: ConcurrentValue { }
217217

218-
class C1: ConcurrentValue {
218+
final class C1: ConcurrentValue {
219219
let nc: NotConcurrent? = nil // expected-error{{stored property 'nc' of 'ConcurrentValue'-conforming class 'C1' has non-concurrent-value type 'NotConcurrent?'}}
220220
var x: Int = 0 // expected-error{{stored property 'x' of 'ConcurrentValue'-conforming class 'C1' is mutable}}
221221
let i: Int = 0
222222
}
223223

224-
class C2: ConcurrentValue {
224+
final class C2: ConcurrentValue {
225225
let x: Int = 0
226226
}
227227

228-
class C3: C2 {
229-
var y: Int = 0 // expected-error{{stored property 'y' of 'ConcurrentValue'-conforming class 'C3' is mutable}}
230-
}
228+
class C3 { }
231229

232-
class C4: C2, UnsafeConcurrentValue {
230+
class C4: C3, UnsafeConcurrentValue {
233231
var y: Int = 0 // okay
234232
}
235233

@@ -241,17 +239,9 @@ class C6: C5 {
241239
var y: Int = 0 // still okay, it's unsafe
242240
}
243241

244-
class C7<T>: ConcurrentValue { }
245-
246-
class C8: C7<Int> { } // okay
247-
248-
open class C9: ConcurrentValue { } // expected-error{{open class 'C9' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
242+
final class C7<T>: ConcurrentValue { }
249243

250-
public class C10: ConcurrentValue { }
251-
// expected-note@-1{{superclass is declared here}}
252-
open class C11: C10 { }
253-
// expected-error@-1{{superclass 'C10' of open class must be open}}
254-
// expected-error@-2{{open class 'C11' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
244+
class C9: ConcurrentValue { } // expected-error{{non-final class 'C9' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
255245

256246
// ----------------------------------------------------------------------
257247
// UnsafeConcurrentValue disabling checking

test/Concurrency/concurrent_value_checking_objc.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55

66
import Foundation
77

8-
class A: NSObject, ConcurrentValue {
8+
final class A: NSObject, ConcurrentValue {
99
let x: Int = 5
1010
}
1111

12-
class B: NSObject, ConcurrentValue {
12+
final class B: NSObject, ConcurrentValue {
1313
var x: Int = 5 // expected-error{{stored property 'x' of 'ConcurrentValue'-conforming class 'B' is mutable}}
1414
}
1515

1616
class C { }
1717

18-
class D: NSObject, ConcurrentValue {
18+
final class D: NSObject, ConcurrentValue {
1919
let c: C = C() // expected-error{{stored property 'c' of 'ConcurrentValue'-conforming class 'D' has non-concurrent-value type 'C'}}
2020
}
2121

0 commit comments

Comments
 (0)