diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 2368540dcc059..9fa095aa5852f 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2795,7 +2795,7 @@ WARNING(differentiable_let_property_implicit_noderivative_fixit,none, NOTE(codable_extraneous_codingkey_case_here,none, "CodingKey case %0 does not match any stored properties", (Identifier)) NOTE(codable_non_conforming_property_here,none, - "cannot automatically synthesize %0 because %1 does not conform to %0", (Type, Type)) + "cannot automatically synthesize %0 because %1 does not conform to %0", (Type, TypeLoc)) NOTE(codable_non_decoded_property_here,none, "cannot automatically synthesize %0 because %1 does not have a matching CodingKey and does not have a default value", (Type, Identifier)) NOTE(codable_codingkeys_type_is_not_an_enum_here,none, diff --git a/lib/Sema/DerivedConformanceCodable.cpp b/lib/Sema/DerivedConformanceCodable.cpp index 843049dea1a4d..a76fd5e3be6fe 100644 --- a/lib/Sema/DerivedConformanceCodable.cpp +++ b/lib/Sema/DerivedConformanceCodable.cpp @@ -172,10 +172,20 @@ static bool validateCodingKeysEnum(DerivedConformance &derived, properties.erase(it); break; - case DoesNotConform: + case DoesNotConform: { + // We use a TypeLoc here so diagnostics can show the type + // as written by the user in source if possible. This is useful + // when the user has written an IUO type for example, since + // diagnostics would show the type as 'T?' instead of 'T!' if + // we use a Type instead. + TypeLoc typeLoc = { + it->second->getTypeReprOrParentPatternTypeRepr(), + it->second->getType(), + }; it->second->diagnose(diag::codable_non_conforming_property_here, - derived.getProtocolType(), it->second->getType()); + derived.getProtocolType(), typeLoc); LLVM_FALLTHROUGH; + } case TypeNotValidated: // We don't produce a diagnostic for a type which failed to validate. @@ -352,10 +362,20 @@ static EnumDecl *synthesizeCodingKeysEnum(DerivedConformance &derived) { break; } - case DoesNotConform: + case DoesNotConform: { + // We use a TypeLoc here so diagnostics can show the type + // as written by the user in source if possible. This is useful + // when the user has written an IUO type for example, since + // diagnostics would show the type as 'T?' instead of 'T!' if + // we use a Type instead. + TypeLoc typeLoc = { + varDecl->getTypeReprOrParentPatternTypeRepr(), + varDecl->getType(), + }; varDecl->diagnose(diag::codable_non_conforming_property_here, - derived.getProtocolType(), varDecl->getType()); + derived.getProtocolType(), typeLoc); LLVM_FALLTHROUGH; + } case TypeNotValidated: // We don't produce a diagnostic for a type which failed to validate. diff --git a/test/decl/protocol/special/coding/class_codable_excluded_optional_properties.swift b/test/decl/protocol/special/coding/class_codable_excluded_optional_properties.swift index fe5c36bcc2acd..1b2d1ccb5f6a5 100644 --- a/test/decl/protocol/special/coding/class_codable_excluded_optional_properties.swift +++ b/test/decl/protocol/special/coding/class_codable_excluded_optional_properties.swift @@ -45,8 +45,8 @@ class ClassWithNonExcludedVarMembers : Codable { // expected-error {{type 'Class // AnyHashable does not conform to Codable. var p3: AnyHashable? // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}} // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}} - var p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}} - // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}} + var p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable!' does not conform to 'Decodable'}} + // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable!' does not conform to 'Encodable'}} } class ClassWithExcludedVarMembers : Codable { diff --git a/test/decl/protocol/special/coding/class_codable_failure_diagnostics.swift b/test/decl/protocol/special/coding/class_codable_failure_diagnostics.swift index ba35fb4e92e4a..e06724325099c 100644 --- a/test/decl/protocol/special/coding/class_codable_failure_diagnostics.swift +++ b/test/decl/protocol/special/coding/class_codable_failure_diagnostics.swift @@ -9,8 +9,8 @@ class C1 : Codable { var a: String = "" var b: Int = 0 var c: Nested = Nested() - // expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'C1.Nested' does not conform to 'Decodable'}} - // expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'C1.Nested' does not conform to 'Encodable'}} + // expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'Nested' does not conform to 'Decodable'}} + // expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'Nested' does not conform to 'Encodable'}} } // Codable class with non-enum CodingKeys. diff --git a/test/decl/protocol/special/coding/struct_codable_excluded_optional_properties.swift b/test/decl/protocol/special/coding/struct_codable_excluded_optional_properties.swift index 8d8d5939fee02..84e9b9c3022ec 100644 --- a/test/decl/protocol/special/coding/struct_codable_excluded_optional_properties.swift +++ b/test/decl/protocol/special/coding/struct_codable_excluded_optional_properties.swift @@ -12,8 +12,8 @@ struct StructWithNonExcludedLetMembers : Codable { // expected-error {{type 'Str // AnyHashable does not conform to Codable. let p3: AnyHashable? // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}} // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}} - let p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}} - // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}} + let p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable!' does not conform to 'Decodable'}} + // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable!' does not conform to 'Encodable'}} } struct StructWithExcludedLetMembers : Codable { // expected-error {{type 'StructWithExcludedLetMembers' does not conform to protocol 'Decodable'}} @@ -46,8 +46,8 @@ struct StructWithNonExcludedVarMembers : Codable { // expected-error {{type 'Str // AnyHashable does not conform to Codable. var p3: AnyHashable? // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}} // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}} - var p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}} - // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}} + var p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable!' does not conform to 'Decodable'}} + // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable!' does not conform to 'Encodable'}} } struct StructWithExcludedVarMembers : Codable { diff --git a/test/decl/protocol/special/coding/struct_codable_failure_diagnostics.swift b/test/decl/protocol/special/coding/struct_codable_failure_diagnostics.swift index fa26222b73602..4928fb44ecc68 100644 --- a/test/decl/protocol/special/coding/struct_codable_failure_diagnostics.swift +++ b/test/decl/protocol/special/coding/struct_codable_failure_diagnostics.swift @@ -9,8 +9,8 @@ struct S1 : Codable { var a: String = "" var b: Int = 0 var c: Nested = Nested() - // expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'S1.Nested' does not conform to 'Decodable'}} - // expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'S1.Nested' does not conform to 'Encodable'}} + // expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'Nested' does not conform to 'Decodable'}} + // expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'Nested' does not conform to 'Encodable'}} } // Codable struct with non-enum CodingKeys. diff --git a/test/decl/protocol/special/coding/struct_codable_simple.swift b/test/decl/protocol/special/coding/struct_codable_simple.swift index 05b04f37f8374..05b6423f98cd7 100644 --- a/test/decl/protocol/special/coding/struct_codable_simple.swift +++ b/test/decl/protocol/special/coding/struct_codable_simple.swift @@ -34,8 +34,8 @@ let _ = SimpleStruct.CodingKeys.self // expected-error {{'CodingKeys' is inacces struct SR_12248_1: Codable { // expected-error {{type 'SR_12248_1' does not conform to protocol 'Encodable'}} var x: Int // expected-note {{'x' previously declared here}} var x: Int // expected-error {{invalid redeclaration of 'x'}} - // expected-note@-1 {{cannot automatically synthesize 'Encodable' because '<>' does not conform to 'Encodable'}} - // expected-note@-2 {{cannot automatically synthesize 'Encodable' because '<>' does not conform to 'Encodable'}} + // expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'Int' does not conform to 'Encodable'}} + // expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'Int' does not conform to 'Encodable'}} } struct SR_12248_2: Decodable {