[Sema] Diagnose invalid uses of protocol suppression via ~ syntax

This commit is contained in:
Pavel Yaskevich
2025-10-08 13:23:10 -07:00
parent 389c240a2a
commit c50602b2ce
4 changed files with 67 additions and 0 deletions

View File

@@ -8950,6 +8950,10 @@ ERROR(tilde_sendable_requires_feature_flag,none,
"'~Sendable' requires -enable-experimental-feature TildeSendable",
())
ERROR(conformance_repression_only_on_struct_class_enum,none,
"conformance to %0 can only be suppressed on structs, classes, and enums",
(const ProtocolDecl *))
//===----------------------------------------------------------------------===//
// MARK: Swift Performance hints
//===----------------------------------------------------------------------===//

View File

@@ -132,6 +132,18 @@ public:
}
}
if (auto *TD = dyn_cast<const TypeDecl *>(decl)) {
if (!(isa<StructDecl>(TD) || isa<ClassDecl>(TD) || isa<EnumDecl>(TD))) {
diagnoseInvalid(repr, repr.getLoc(),
diag::conformance_repression_only_on_struct_class_enum,
ctx.getProtocol(*kp))
// Downgrade to a warning for `~BitwiseCopyable` because it was accepted
// in some incorrect positions before.
.warnUntilFutureSwiftVersionIf(kp == KnownProtocolKind::BitwiseCopyable);
return Type();
}
}
if (auto *extension = dyn_cast<const ExtensionDecl *>(decl)) {
diagnoseInvalid(repr, extension,
diag::suppress_inferrable_protocol_extension,

View File

@@ -7,6 +7,23 @@
// This test file only exists in order to test without noncopyable_generics and can be deleted once that is always enabled.
protocol P: ~BitwiseCopyable {
// expected-warning@-1 {{conformance to 'BitwiseCopyable' can only be suppressed on structs, classes, and enums; this will be an error in a future}}
}
protocol Q {
associatedtype V: ~BitwiseCopyable
// expected-warning@-1 {{conformance to 'BitwiseCopyable' can only be suppressed on structs, classes, and enums; this will be an error in a future}}
}
func test<T: ~BitwiseCopyable>(_: T) {
// expected-warning@-1 {{conformance to 'BitwiseCopyable' can only be suppressed on structs, classes, and enums; this will be an error in a future}}
}
func test<T>() -> T where T: ~BitwiseCopyable {
// expected-error@-1 {{type 'BitwiseCopyable' cannot be suppressed}}
}
@_nonescapable
struct S_Implicit_Nonescapable {}

View File

@@ -0,0 +1,34 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-feature TildeSendable
// REQUIRES: swift_feature_TildeSendable
protocol P: ~Sendable { // expected-error {{conformance to 'Sendable' can only be suppressed on structs, classes, and enums}}
}
protocol Q {
associatedtype T: ~Sendable
// expected-error@-1 {{conformance to 'Sendable' can only be suppressed on structs, classes, and enums}}
}
struct A: ~Sendable {}
class B: ~Sendable {}
enum C: ~Sendable {}
struct E1: Sendable, ~Sendable {}
enum E2: ~Sendable, ~Sendable {} // expected-warning {{already suppressed conformance to 'Sendable'}}
struct InExt {}
extension InExt: ~Sendable { // expected-error {{conformance to inferrable protocol 'Sendable' cannot be suppressed in an extension}}
}
func test<T: ~Sendable>(_: T) {} // expected-error {{conformance to 'Sendable' can only be suppressed on structs, classes, and enums}}
func test<Q>(other: Q) where Q: ~Sendable {} // expected-error {{type 'Sendable' cannot be suppressed}}
struct Generic<T: ~Sendable> { // expected-error {{conformance to 'Sendable' can only be suppressed on structs, classes, and enums}}
var x: T
}
var x: some BinaryInteger & ~Sendable // expected-error {{type 'Sendable' cannot be suppressed}}