Skip to content

Commit c50602b

Browse files
committed
[Sema] Diagnose invalid uses of protocol suppression via ~ syntax
1 parent 389c240 commit c50602b

File tree

4 files changed

+67
-0
lines changed

4 files changed

+67
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8950,6 +8950,10 @@ ERROR(tilde_sendable_requires_feature_flag,none,
89508950
"'~Sendable' requires -enable-experimental-feature TildeSendable",
89518951
())
89528952

8953+
ERROR(conformance_repression_only_on_struct_class_enum,none,
8954+
"conformance to %0 can only be suppressed on structs, classes, and enums",
8955+
(const ProtocolDecl *))
8956+
89538957
//===----------------------------------------------------------------------===//
89548958
// MARK: Swift Performance hints
89558959
//===----------------------------------------------------------------------===//

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,18 @@ class CheckRepressions {
132132
}
133133
}
134134

135+
if (auto *TD = dyn_cast<const TypeDecl *>(decl)) {
136+
if (!(isa<StructDecl>(TD) || isa<ClassDecl>(TD) || isa<EnumDecl>(TD))) {
137+
diagnoseInvalid(repr, repr.getLoc(),
138+
diag::conformance_repression_only_on_struct_class_enum,
139+
ctx.getProtocol(*kp))
140+
// Downgrade to a warning for `~BitwiseCopyable` because it was accepted
141+
// in some incorrect positions before.
142+
.warnUntilFutureSwiftVersionIf(kp == KnownProtocolKind::BitwiseCopyable);
143+
return Type();
144+
}
145+
}
146+
135147
if (auto *extension = dyn_cast<const ExtensionDecl *>(decl)) {
136148
diagnoseInvalid(repr, extension,
137149
diag::suppress_inferrable_protocol_extension,

test/Sema/bitwise_copyable_2.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@
77

88
// This test file only exists in order to test without noncopyable_generics and can be deleted once that is always enabled.
99

10+
protocol P: ~BitwiseCopyable {
11+
// expected-warning@-1 {{conformance to 'BitwiseCopyable' can only be suppressed on structs, classes, and enums; this will be an error in a future}}
12+
}
13+
14+
protocol Q {
15+
associatedtype V: ~BitwiseCopyable
16+
// expected-warning@-1 {{conformance to 'BitwiseCopyable' can only be suppressed on structs, classes, and enums; this will be an error in a future}}
17+
}
18+
19+
func test<T: ~BitwiseCopyable>(_: T) {
20+
// expected-warning@-1 {{conformance to 'BitwiseCopyable' can only be suppressed on structs, classes, and enums; this will be an error in a future}}
21+
}
22+
23+
func test<T>() -> T where T: ~BitwiseCopyable {
24+
// expected-error@-1 {{type 'BitwiseCopyable' cannot be suppressed}}
25+
}
26+
1027
@_nonescapable
1128
struct S_Implicit_Nonescapable {}
1229

test/Sema/tilde_sendable.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-feature TildeSendable
2+
3+
// REQUIRES: swift_feature_TildeSendable
4+
5+
protocol P: ~Sendable { // expected-error {{conformance to 'Sendable' can only be suppressed on structs, classes, and enums}}
6+
}
7+
8+
protocol Q {
9+
associatedtype T: ~Sendable
10+
// expected-error@-1 {{conformance to 'Sendable' can only be suppressed on structs, classes, and enums}}
11+
}
12+
13+
struct A: ~Sendable {}
14+
class B: ~Sendable {}
15+
enum C: ~Sendable {}
16+
17+
struct E1: Sendable, ~Sendable {}
18+
19+
enum E2: ~Sendable, ~Sendable {} // expected-warning {{already suppressed conformance to 'Sendable'}}
20+
21+
struct InExt {}
22+
23+
extension InExt: ~Sendable { // expected-error {{conformance to inferrable protocol 'Sendable' cannot be suppressed in an extension}}
24+
}
25+
26+
func test<T: ~Sendable>(_: T) {} // expected-error {{conformance to 'Sendable' can only be suppressed on structs, classes, and enums}}
27+
func test<Q>(other: Q) where Q: ~Sendable {} // expected-error {{type 'Sendable' cannot be suppressed}}
28+
29+
struct Generic<T: ~Sendable> { // expected-error {{conformance to 'Sendable' can only be suppressed on structs, classes, and enums}}
30+
var x: T
31+
}
32+
33+
var x: some BinaryInteger & ~Sendable // expected-error {{type 'Sendable' cannot be suppressed}}
34+

0 commit comments

Comments
 (0)