diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 4ddc17810fe14..a5338258538b9 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -1842,9 +1842,11 @@ ERROR(use_of_equal_instead_of_equality,none, "use of '=' in a boolean context, did you mean '=='?", ()) ERROR(type_cannot_conform, none, "%select{type %1|protocol %1 as a type}0 cannot conform to " - "%select{%3|the protocol itself}2; " - "only concrete types such as structs, enums and classes can conform to protocols", + "%select{%3|the protocol itself}2", (bool, Type, bool, Type)) +NOTE(only_concrete_types_conform_to_protocols,none, + "only concrete types such as structs, enums and classes can conform to protocols", + ()) NOTE(required_by_opaque_return,none, "required by opaque return type of %0 %1", (DescriptiveDeclKind, DeclName)) NOTE(required_by_decl,none, diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index bc48910f3b2b8..7e293267be78b 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -516,6 +516,8 @@ bool MissingConformanceFailure::diagnoseTypeCannotConform( nonConformingType->isEqual(protocolType), protocolType); + emitDiagnostic(diag::only_concrete_types_conform_to_protocols); + if (auto *OTD = dyn_cast(AffectedDecl)) { auto *namingDecl = OTD->getNamingDecl(); if (auto *repr = namingDecl->getOpaqueResultTypeRepr()) { @@ -2171,6 +2173,7 @@ bool ContextualFailure::diagnoseAsError() { emitDiagnostic(diag::type_cannot_conform, /*isExistentialType=*/true, fromType, fromType->isEqual(toType), toType); + emitDiagnostic(diag::only_concrete_types_conform_to_protocols); return true; } diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 54e2c50d0d204..aceff9963ba87 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -4735,6 +4735,8 @@ void swift::diagnoseConformanceFailure(Type T, diags.diagnose(ComplainLoc, diag::type_cannot_conform, true, T, T->isEqual(Proto->getDeclaredInterfaceType()), Proto->getDeclaredInterfaceType()); + diags.diagnose(ComplainLoc, + diag::only_concrete_types_conform_to_protocols); return; } diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift index fd1a40913a80d..2e9eb5dd8a03a 100644 --- a/test/Constraints/diagnostics.swift +++ b/test/Constraints/diagnostics.swift @@ -51,9 +51,9 @@ f0(i, i, // expected-error@:7 {{cannot convert value of type 'Int' to expected a // Cannot conform to protocols. -f5(f4) // expected-error {{type '(Int) -> Int' cannot conform to 'P2'; only concrete types such as structs, enums and classes can conform to protocols}} -f5((1, "hello")) // expected-error {{type '(Int, String)' cannot conform to 'P2'; only concrete types such as structs, enums and classes can conform to protocols}} -f5(Int.self) // expected-error {{type 'Int.Type' cannot conform to 'P2'; only concrete types such as structs, enums and classes can conform to protocols}} +f5(f4) // expected-error {{type '(Int) -> Int' cannot conform to 'P2'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} +f5((1, "hello")) // expected-error {{type '(Int, String)' cannot conform to 'P2'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} +f5(Int.self) // expected-error {{type 'Int.Type' cannot conform to 'P2'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} // Tuple element not convertible. f0(i, @@ -104,7 +104,7 @@ func f8(_ n: T, _ f: @escaping (T) -> T) {} // expected-note {{where 'T' f8(3, f4) // expected-error {{global function 'f8' requires that 'Int' conform to 'P2'}} typealias Tup = (Int, Double) func f9(_ x: Tup) -> Tup { return x } -f8((1,2.0), f9) // expected-error {{type 'Tup' (aka '(Int, Double)') cannot conform to 'P2'; only concrete types such as structs, enums and classes can conform to protocols}} +f8((1,2.0), f9) // expected-error {{type 'Tup' (aka '(Int, Double)') cannot conform to 'P2'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} // QoI: Incorrect diagnostic for calling nonexistent members on literals 1.doesntExist(0) // expected-error {{value of type 'Int' has no member 'doesntExist'}} diff --git a/test/Constraints/generics.swift b/test/Constraints/generics.swift index ab8f724622ebb..6f72cb902814a 100644 --- a/test/Constraints/generics.swift +++ b/test/Constraints/generics.swift @@ -188,7 +188,7 @@ func r22459135() { // QoI: Friendlier error message for "[] as Set" // QoI: "argument for generic parameter 'Element' could not be inferred" lacks context -_ = [] as Set // expected-error {{protocol 'Any' as a type cannot conform to 'Hashable'; only concrete types such as structs, enums and classes can conform to protocols}} +_ = [] as Set // expected-error {{protocol 'Any' as a type cannot conform to 'Hashable'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} // expected-note@-1 {{required by generic struct 'Set' where 'Element' = 'Any'}} diff --git a/test/Constraints/rdar68155466.swift b/test/Constraints/rdar68155466.swift index f8c4e176b7029..78d9371809567 100644 --- a/test/Constraints/rdar68155466.swift +++ b/test/Constraints/rdar68155466.swift @@ -25,4 +25,4 @@ func data() -> [A] { } _ = Loop(data(), id: \.uniqueID) { $0 } // expected-error {{key path cannot refer to instance method 'uniqueID()'}} -// expected-error@-1 {{type '() -> Int' cannot conform to 'Hashable'; only concrete types such as structs, enums and classes can conform to protocols}} +// expected-error@-1 {{type '() -> Int' cannot conform to 'Hashable'}} expected-note@-1 {{only concrete types such as structs, enums and classes can conform to protocols}} diff --git a/test/Constraints/result_builder_diags.swift b/test/Constraints/result_builder_diags.swift index 13153cb1146cb..08c59e638ce96 100644 --- a/test/Constraints/result_builder_diags.swift +++ b/test/Constraints/result_builder_diags.swift @@ -195,7 +195,7 @@ struct Label : P where L : P { // expected-note 2 {{'L' declared as parameter } func test_51167632() -> some P { - AnyP(G { // expected-error {{type 'Label<_>.Type' cannot conform to 'P'; only concrete types such as structs, enums and classes can conform to protocols}} + AnyP(G { // expected-error {{type 'Label<_>.Type' cannot conform to 'P'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} Text("hello") Label // expected-error {{generic parameter 'L' could not be inferred}} // expected-note@-1 {{explicitly specify the generic arguments to fix this issue}} {{10-10=<<#L: P#>>}} diff --git a/test/Generics/conditional_conformances_literals.swift b/test/Generics/conditional_conformances_literals.swift index 37f4729f14d17..9e26cc495776e 100644 --- a/test/Generics/conditional_conformances_literals.swift +++ b/test/Generics/conditional_conformances_literals.swift @@ -128,9 +128,9 @@ func combined() { // Needs self conforming protocols: let _: Conforms = [[0: [1 : [works]] as Conforms]] - // expected-error@-1 {{protocol 'Conforms' as a type cannot conform to the protocol itself; only concrete types such as structs, enums and classes can conform to protocols}} + // expected-error@-1 {{protocol 'Conforms' as a type cannot conform to the protocol itself}} expected-note@-1 {{only concrete types such as structs, enums and classes can conform to protocols}} let _: Conforms = [[0: [1 : [fails]] as Conforms]] // expected-error@-1 {{protocol 'Conforms' requires that 'Fails' conform to 'Conforms'}} - // expected-error@-2 {{protocol 'Conforms' as a type cannot conform to the protocol itself; only concrete types such as structs, enums and classes can conform to protocols}} + // expected-error@-2 {{protocol 'Conforms' as a type cannot conform to the protocol itself}} expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}} } diff --git a/test/Generics/existential_restrictions.swift b/test/Generics/existential_restrictions.swift index 425308b798901..8dd84dcccc953 100644 --- a/test/Generics/existential_restrictions.swift +++ b/test/Generics/existential_restrictions.swift @@ -23,7 +23,7 @@ func fAOE(_ t: AnyObject) { } func fT(_ t: T) { } func testPassExistential(_ p: P, op: OP, opp: OP & P, cp: CP, sp: SP, any: Any, ao: AnyObject) { - fP(p) // expected-error{{protocol 'P' as a type cannot conform to the protocol itself; only concrete types such as structs, enums and classes can conform to protocols}} + fP(p) // expected-error{{protocol 'P' as a type cannot conform to the protocol itself}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} fAO(p) // expected-error{{global function 'fAO' requires that 'P' be a class type}} fAOE(p) // expected-error{{argument type 'P' expected to be an instance of a class or class-constrained type}} fT(p) @@ -37,8 +37,8 @@ func testPassExistential(_ p: P, op: OP, opp: OP & P, cp: CP, sp: SP, any: Any, fAOE(cp) fT(cp) - fP(opp) // expected-error{{protocol 'OP & P' as a type cannot conform to 'P'; only concrete types such as structs, enums and classes can conform to protocols}} - fOP(opp) // expected-error{{protocol 'OP & P' as a type cannot conform to 'OP'; only concrete types such as structs, enums and classes can conform to protocols}} + fP(opp) // expected-error{{protocol 'OP & P' as a type cannot conform to 'P'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} + fOP(opp) // expected-error{{protocol 'OP & P' as a type cannot conform to 'OP'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} fAO(opp) // expected-error{{global function 'fAO' requires that 'OP & P' be a class type}} fAOE(opp) fT(opp) @@ -64,9 +64,9 @@ class GAO {} // expected-note 2{{requirement specified as 'T' : ' func blackHole(_ t: Any) {} func testBindExistential() { - blackHole(GP

()) // expected-error{{protocol 'P' as a type cannot conform to the protocol itself; only concrete types such as structs, enums and classes can conform to protocols}} + blackHole(GP

()) // expected-error{{protocol 'P' as a type cannot conform to the protocol itself}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} blackHole(GOP()) - blackHole(GCP()) // expected-error{{protocol 'CP' as a type cannot conform to the protocol itself; only concrete types such as structs, enums and classes can conform to protocols}} + blackHole(GCP()) // expected-error{{protocol 'CP' as a type cannot conform to the protocol itself}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} blackHole(GAO

()) // expected-error{{'GAO' requires that 'P' be a class type}} blackHole(GAO()) blackHole(GAO()) // expected-error{{'GAO' requires that 'CP' be a class type}} @@ -92,5 +92,5 @@ func foo() { // generic no overloads error path. The error should actually talk // about the return type, and this can happen in other contexts as well; // tracks improving QoI here. - allMine.takeAll() // expected-error{{protocol 'Mine' as a type cannot conform to the protocol itself; only concrete types such as structs, enums and classes can conform to protocols}} + allMine.takeAll() // expected-error{{protocol 'Mine' as a type cannot conform to the protocol itself}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} } diff --git a/test/Parse/confusables.swift b/test/Parse/confusables.swift index 626e2660560e4..b2969fd992053 100644 --- a/test/Parse/confusables.swift +++ b/test/Parse/confusables.swift @@ -17,9 +17,10 @@ if (true ꝸꝸꝸ false) {} // expected-note {{identifier 'ꝸꝸꝸ' contains // expected-error @+3 {{invalid character in source file}} // expected-error @+2 {{expected ',' separator}} -// expected-error @+1 {{type '(Int, Int)' cannot conform to 'BinaryInteger'; only concrete types such as structs, enums and classes can conform to protocols}} +// expected-error @+1 {{type '(Int, Int)' cannot conform to 'BinaryInteger'}} if (5 ‒ 5) == 0 {} // expected-note {{unicode character '‒' (Figure Dash) looks similar to '-' (Hyphen Minus); did you mean to use '-' (Hyphen Minus)?}} {{7-10=-}} // expected-note @-1 {{operator function '=='}} +// expected-note @-2 {{only concrete types such as structs, enums and classes can conform to protocols}} // FIXME(rdar://61028087): The above note should read "required by referencing operator function '==' on 'BinaryInteger' where 'Self' = '(Int, Int)'". diff --git a/test/decl/protocol/conforms/error_self_conformance.swift b/test/decl/protocol/conforms/error_self_conformance.swift index b451839b0e5ec..c09e53b107b98 100644 --- a/test/decl/protocol/conforms/error_self_conformance.swift +++ b/test/decl/protocol/conforms/error_self_conformance.swift @@ -11,15 +11,15 @@ func testSimple(error: Error) { protocol ErrorRefinement : Error {} func testErrorRefinment(error: ErrorRefinement) { - wantsError(error) // expected-error {{protocol 'ErrorRefinement' as a type cannot conform to 'Error'; only concrete types such as structs, enums and classes can conform to protocols}} + wantsError(error) // expected-error {{protocol 'ErrorRefinement' as a type cannot conform to 'Error'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} } protocol OtherProtocol {} func testErrorComposition(error: Error & OtherProtocol) { - wantsError(error) // expected-error {{protocol 'Error & OtherProtocol' as a type cannot conform to 'Error'; only concrete types such as structs, enums and classes can conform to protocols}} + wantsError(error) // expected-error {{protocol 'Error & OtherProtocol' as a type cannot conform to 'Error'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} } class C {} func testErrorCompositionWithClass(error: Error & C) { - wantsError(error) // expected-error {{protocol 'C & Error' as a type cannot conform to 'Error'; only concrete types such as structs, enums and classes can conform to protocols}} + wantsError(error) // expected-error {{protocol 'C & Error' as a type cannot conform to 'Error'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} } diff --git a/test/stmt/foreach.swift b/test/stmt/foreach.swift index 0b4ca6de47112..20ddf6add1cfd 100644 --- a/test/stmt/foreach.swift +++ b/test/stmt/foreach.swift @@ -177,7 +177,7 @@ func testOptionalSequence() { // Crash with (invalid) for each over an existential func testExistentialSequence(s: Sequence) { // expected-error {{protocol 'Sequence' can only be used as a generic constraint because it has Self or associated type requirements}} - for x in s { // expected-error {{protocol 'Sequence' as a type cannot conform to the protocol itself; only concrete types such as structs, enums and classes can conform to protocols}} + for x in s { // expected-error {{protocol 'Sequence' as a type cannot conform to the protocol itself}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} _ = x } } diff --git a/test/type/opaque.swift b/test/type/opaque.swift index 4b8190d7ff724..7bc754ff02c50 100644 --- a/test/type/opaque.swift +++ b/test/type/opaque.swift @@ -383,7 +383,7 @@ protocol P_51641323 { func rdar_51641323() { struct Foo: P_51641323 { var foo: some P_51641323 { // expected-note {{required by opaque return type of property 'foo'}} - {} // expected-error {{type '() -> ()' cannot conform to 'P_51641323'; only concrete types such as structs, enums and classes can conform to protocols}} + {} // expected-error {{type '() -> ()' cannot conform to 'P_51641323'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} } } } diff --git a/test/type/subclass_composition.swift b/test/type/subclass_composition.swift index a7c52f539bf58..76b1efb3fd850 100644 --- a/test/type/subclass_composition.swift +++ b/test/type/subclass_composition.swift @@ -413,7 +413,8 @@ func conformsTo & P2>( // expected-error@-1 {{global function 'conformsToAnyObject' requires that 'P1' be a class type}} conformsToP1(p1) - // expected-error@-1 {{protocol 'P1' as a type cannot conform to the protocol itself; only concrete types such as structs, enums and classes can conform to protocols}} + // expected-error@-1 {{protocol 'P1' as a type cannot conform to the protocol itself}} + // expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}} // FIXME: Following diagnostics are not great because when // `conformsTo*` methods are re-typechecked, they loose information diff --git a/validation-test/compiler_crashers_2_fixed/0196-rdar48937223.swift b/validation-test/compiler_crashers_2_fixed/0196-rdar48937223.swift index 2414c14a4442d..945fc56f7db87 100644 --- a/validation-test/compiler_crashers_2_fixed/0196-rdar48937223.swift +++ b/validation-test/compiler_crashers_2_fixed/0196-rdar48937223.swift @@ -6,7 +6,7 @@ func fn(_ arg1: T, arg2: (T) -> U) {} // expected-note@-1 {{required by global function 'fn(_:arg2:)' where 'U' = '()'}} func test(str: String) { - fn(str) { arg in // expected-error {{type '()' cannot conform to 'P'; only concrete types such as structs, enums and classes can conform to protocols}} + fn(str) { arg in // expected-error {{type '()' cannot conform to 'P'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}} <#FOO#> // expected-error {{editor placeholder in source file}} } } diff --git a/validation-test/compiler_crashers_fixed/00017-llvm-foldingset-llvm-attributesetnode-nodeequals.swift b/validation-test/compiler_crashers_fixed/00017-llvm-foldingset-llvm-attributesetnode-nodeequals.swift index 6f574b0e9dcac..579c0ee8993f9 100644 --- a/validation-test/compiler_crashers_fixed/00017-llvm-foldingset-llvm-attributesetnode-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/00017-llvm-foldingset-llvm-attributesetnode-nodeequals.swift @@ -20,4 +20,4 @@ extension Bool : BooleanProtocol { func f(_ b: T) {} // expected-note@-1 {{required by global function 'f' where 'T' = 'BooleanProtocol'}} -f(true as BooleanProtocol) // expected-error {{protocol 'BooleanProtocol' as a type cannot conform to the protocol itself; only concrete types such as structs, enums and classes can conform to protocols}} +f(true as BooleanProtocol) // expected-error {{protocol 'BooleanProtocol' as a type cannot conform to the protocol itself}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}}