Skip to content

Commit a8beb7b

Browse files
authored
Merge pull request swiftlang#36246 from DougGregor/se-0302-minor-tweaks
2 parents 33cd639 + 09121d7 commit a8beb7b

File tree

13 files changed

+54
-40
lines changed

13 files changed

+54
-40
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4382,11 +4382,11 @@ WARNING(concurrent_value_outside_source_file_warn,none,
43824382
"conformance to 'ConcurrentValue' must occur in the same source file as "
43834383
"%0 %1; use 'UnsafeConcurrentValue' for retroactive conformance",
43844384
(DescriptiveDeclKind, DeclName))
4385-
ERROR(concurrent_value_open_class,none,
4386-
"open class %0 cannot conform to `ConcurrentValue`; "
4385+
ERROR(concurrent_value_nonfinal_class,none,
4386+
"non-final class %0 cannot conform to `ConcurrentValue`; "
43874387
"use `UnsafeConcurrentValue`", (DeclName))
4388-
WARNING(concurrent_value_open_class_warn,none,
4389-
"open class %0 cannot conform to `ConcurrentValue`; "
4388+
WARNING(concurrent_value_nonfinal_class_warn,none,
4389+
"non-final class %0 cannot conform to `ConcurrentValue`; "
43904390
"use `UnsafeConcurrentValue`", (DeclName))
43914391
ERROR(concurrent_value_inherit,none,
43924392
"`ConcurrentValue` class %1 cannot inherit from another class"

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,20 @@ static bool isConcurrentValueType(const DeclContext *dc, Type type) {
768768

769769
bool visitFunctionType(FunctionType *type) {
770770
// Concurrent function types meet the requirements.
771-
return type->isConcurrent();
771+
if (type->isConcurrent())
772+
return true;
773+
774+
// C and thin function types meeting the requirements because they
775+
// cannot have captures.
776+
switch (type->getExtInfo().getRepresentation()) {
777+
case FunctionTypeRepresentation::Block:
778+
case FunctionTypeRepresentation::Swift:
779+
return false;
780+
781+
case FunctionTypeRepresentation::CFunctionPointer:
782+
case FunctionTypeRepresentation::Thin:
783+
return true;
784+
}
772785
}
773786

774787
bool visitProtocolCompositionType(ProtocolCompositionType *type) {
@@ -2470,11 +2483,11 @@ bool swift::checkConcurrentValueConformance(
24702483
}
24712484

24722485
if (classDecl) {
2473-
// An open class cannot conform to `ConcurrentValue`.
2474-
if (classDecl->getFormalAccess() == AccessLevel::Open) {
2486+
// An non-final class cannot conform to `ConcurrentValue`.
2487+
if (!classDecl->isFinal()) {
24752488
classDecl->diagnose(
2476-
asWarning ? diag::concurrent_value_open_class_warn
2477-
: diag::concurrent_value_open_class,
2489+
asWarning ? diag::concurrent_value_nonfinal_class_warn
2490+
: diag::concurrent_value_nonfinal_class,
24782491
classDecl->getName());
24792492

24802493
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

test/Concurrency/concurrent_value_inference.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,16 @@ public enum PublicEnum {
8080
case some
8181
}
8282

83+
struct HasFunctions {
84+
var tfp: @convention(thin) () -> Void
85+
var cfp: @convention(c) () -> Void
86+
}
87+
8388
func testCV(
8489
c1: C1, c2: C2, s1: S1, e1: E1, e2: E2, gs1: GS1<Int>, gs2: GS2<Int>,
8590
bc: Bitcode, ps: PublicStruct, pe: PublicEnum,
86-
fps: FrozenPublicStruct, fpe: FrozenPublicEnum
91+
fps: FrozenPublicStruct, fpe: FrozenPublicEnum,
92+
hf: HasFunctions
8793
) {
8894
acceptCV(c1) // expected-error{{'C1' conform to 'ConcurrentValue'}}
8995
acceptCV(c2)
@@ -103,4 +109,7 @@ func testCV(
103109
// Public is okay when also @frozen.
104110
acceptCV(fps)
105111
acceptCV(fpe)
112+
113+
// Thin and C function types are ConcurrentValue.
114+
acceptCV(hf)
106115
}

test/Constraints/ErrorBridging.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func throwErrorCode() throws {
7575
throw FictionalServerError.meltedDown // expected-error{{thrown error code type 'FictionalServerError.Code' does not conform to 'Error'; construct an 'FictionalServerError' instance}}{{29-29=(}}{{40-40=)}}
7676
}
7777

78-
class MyErrorClass { }
78+
class MyErrorClass { } // expected-warning{{non-final class 'MyErrorClass' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
7979
extension MyErrorClass: Error { }
8080

8181
class MyClass { }

test/Constraints/casts.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ extension Int: JSONLeaf { }
346346
extension Array: JSON where Element: JSON { }
347347

348348
protocol SR13035Error: Error {}
349-
class ChildError: SR13035Error {}
349+
class ChildError: SR13035Error {} // expected-warning{{non-final class 'ChildError' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
350350

351351
protocol AnyC {
352352
func foo()

test/SILGen/errors.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,14 +1013,14 @@ func testOptionalTryNeverFailsAddressOnlyVar<T>(_ obj: T) {
10131013
var copy = try? obj // expected-warning {{no calls to throwing functions occur within 'try' expression}} expected-warning {{initialization of variable 'copy' was never used; consider replacing with assignment to '_' or removing it}}
10141014
}
10151015

1016-
class SomeErrorClass : Error { }
1016+
class SomeErrorClass : Error { } // expected-warning{{non-final class 'SomeErrorClass' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
10171017

10181018
// CHECK-LABEL: sil_vtable SomeErrorClass
10191019
// CHECK-NEXT: #SomeErrorClass.init!allocator: {{.*}} : @$s6errors14SomeErrorClassCACycfC
10201020
// CHECK-NEXT: #SomeErrorClass.deinit!deallocator: @$s6errors14SomeErrorClassCfD
10211021
// CHECK-NEXT: }
10221022

1023-
class OtherErrorSub : OtherError { }
1023+
class OtherErrorSub : OtherError { } // expected-warning{{non-final class 'OtherErrorSub' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
10241024

10251025
// CHECK-LABEL: sil_vtable OtherErrorSub {
10261026
// CHECK-NEXT: #OtherError.init!allocator: {{.*}} : @$s6errors13OtherErrorSubCACycfC [override]

test/decl/func/throwing_functions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ B(foo: 0) // expected-warning{{unused}}
145145

146146
// rdar://problem/33040113 - Provide fix-it for missing "try" when calling throwing Swift function
147147

148-
class E_33040113 : Error {}
148+
class E_33040113 : Error {} // expected-warning{{non-final class 'E_33040113' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
149149
func rdar33040113() throws -> Int {
150150
throw E_33040113()
151151
}

test/decl/protocol/special/Actor.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ actor A7 {
3333
}
3434

3535
// A non-actor can conform to the Actor protocol, if it does it properly.
36-
class C1: Actor {
36+
class C1: Actor { // expected-error{{non-final class 'C1' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
3737
func enqueue(partialTask: PartialAsyncTask) { }
3838
}
3939

@@ -55,8 +55,9 @@ extension BA2 {
5555
@actorIndependent func enqueue(partialTask: PartialAsyncTask) { }
5656
}
5757

58-
// No synthesis for non-actores.
58+
// No synthesis for non-actors.
5959
class C2: Actor { // expected-error{{type 'C2' does not conform to protocol 'Actor'}}
60+
// expected-error@-1{{non-final class 'C2' cannot conform to `ConcurrentValue`; use `UnsafeConcurrentValue`}}
6061
}
6162

6263
// Make sure the conformances actually happen.

0 commit comments

Comments
 (0)