Skip to content

Commit 6428c1f

Browse files
authored
[Diagnostic] Fix diagnostic when checking conformance for IUO of gene… (swiftlang#32987)
* [Diagnostic] Fix diagnostic when checking conformance for IUO of generic parameter Prints TypeRepr in diagnostic if possible to throw accurate diagnostic for IUO conformance checking Fixes [rdar://problem/64953106]. Fixes SR-13119 * Nested name lookup tests update Name lookup will see the innermost name anyway and preferred over fully qualified name. Hence the test cases are also updated. * Replaced a letter in test case that inadvertently got added * Code format, corrections and better comments This commit includes better comments for easy understanding, formatted the bug fix code with clang-format and fixes wrong variables inadvertently introduced. * [Test] Update type in struct codable test This commit changes diagnostic type from error type to Int. Although this diagnostic updated is incorrect, this will be resolved when 32371 gets pulled.
1 parent 98253ae commit 6428c1f

7 files changed

+37
-17
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2795,7 +2795,7 @@ WARNING(differentiable_let_property_implicit_noderivative_fixit,none,
27952795
NOTE(codable_extraneous_codingkey_case_here,none,
27962796
"CodingKey case %0 does not match any stored properties", (Identifier))
27972797
NOTE(codable_non_conforming_property_here,none,
2798-
"cannot automatically synthesize %0 because %1 does not conform to %0", (Type, Type))
2798+
"cannot automatically synthesize %0 because %1 does not conform to %0", (Type, TypeLoc))
27992799
NOTE(codable_non_decoded_property_here,none,
28002800
"cannot automatically synthesize %0 because %1 does not have a matching CodingKey and does not have a default value", (Type, Identifier))
28012801
NOTE(codable_codingkeys_type_is_not_an_enum_here,none,

lib/Sema/DerivedConformanceCodable.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,20 @@ static bool validateCodingKeysEnum(DerivedConformance &derived,
172172
properties.erase(it);
173173
break;
174174

175-
case DoesNotConform:
175+
case DoesNotConform: {
176+
// We use a TypeLoc here so diagnostics can show the type
177+
// as written by the user in source if possible. This is useful
178+
// when the user has written an IUO type for example, since
179+
// diagnostics would show the type as 'T?' instead of 'T!' if
180+
// we use a Type instead.
181+
TypeLoc typeLoc = {
182+
it->second->getTypeReprOrParentPatternTypeRepr(),
183+
it->second->getType(),
184+
};
176185
it->second->diagnose(diag::codable_non_conforming_property_here,
177-
derived.getProtocolType(), it->second->getType());
186+
derived.getProtocolType(), typeLoc);
178187
LLVM_FALLTHROUGH;
188+
}
179189

180190
case TypeNotValidated:
181191
// We don't produce a diagnostic for a type which failed to validate.
@@ -352,10 +362,20 @@ static EnumDecl *synthesizeCodingKeysEnum(DerivedConformance &derived) {
352362
break;
353363
}
354364

355-
case DoesNotConform:
365+
case DoesNotConform: {
366+
// We use a TypeLoc here so diagnostics can show the type
367+
// as written by the user in source if possible. This is useful
368+
// when the user has written an IUO type for example, since
369+
// diagnostics would show the type as 'T?' instead of 'T!' if
370+
// we use a Type instead.
371+
TypeLoc typeLoc = {
372+
varDecl->getTypeReprOrParentPatternTypeRepr(),
373+
varDecl->getType(),
374+
};
356375
varDecl->diagnose(diag::codable_non_conforming_property_here,
357-
derived.getProtocolType(), varDecl->getType());
376+
derived.getProtocolType(), typeLoc);
358377
LLVM_FALLTHROUGH;
378+
}
359379

360380
case TypeNotValidated:
361381
// We don't produce a diagnostic for a type which failed to validate.

test/decl/protocol/special/coding/class_codable_excluded_optional_properties.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class ClassWithNonExcludedVarMembers : Codable { // expected-error {{type 'Class
4545
// AnyHashable does not conform to Codable.
4646
var p3: AnyHashable? // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}}
4747
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}}
48-
var p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}}
49-
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}}
48+
var p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable!' does not conform to 'Decodable'}}
49+
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable!' does not conform to 'Encodable'}}
5050
}
5151

5252
class ClassWithExcludedVarMembers : Codable {

test/decl/protocol/special/coding/class_codable_failure_diagnostics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ class C1 : Codable {
99
var a: String = ""
1010
var b: Int = 0
1111
var c: Nested = Nested()
12-
// expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'C1.Nested' does not conform to 'Decodable'}}
13-
// expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'C1.Nested' does not conform to 'Encodable'}}
12+
// expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'Nested' does not conform to 'Decodable'}}
13+
// expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'Nested' does not conform to 'Encodable'}}
1414
}
1515

1616
// Codable class with non-enum CodingKeys.

test/decl/protocol/special/coding/struct_codable_excluded_optional_properties.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ struct StructWithNonExcludedLetMembers : Codable { // expected-error {{type 'Str
1212
// AnyHashable does not conform to Codable.
1313
let p3: AnyHashable? // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}}
1414
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}}
15-
let p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}}
16-
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}}
15+
let p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable!' does not conform to 'Decodable'}}
16+
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable!' does not conform to 'Encodable'}}
1717
}
1818

1919
struct StructWithExcludedLetMembers : Codable { // expected-error {{type 'StructWithExcludedLetMembers' does not conform to protocol 'Decodable'}}
@@ -46,8 +46,8 @@ struct StructWithNonExcludedVarMembers : Codable { // expected-error {{type 'Str
4646
// AnyHashable does not conform to Codable.
4747
var p3: AnyHashable? // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}}
4848
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}}
49-
var p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable?' does not conform to 'Decodable'}}
50-
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable?' does not conform to 'Encodable'}}
49+
var p4: AnyHashable! // expected-note {{cannot automatically synthesize 'Decodable' because 'AnyHashable!' does not conform to 'Decodable'}}
50+
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'AnyHashable!' does not conform to 'Encodable'}}
5151
}
5252

5353
struct StructWithExcludedVarMembers : Codable {

test/decl/protocol/special/coding/struct_codable_failure_diagnostics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ struct S1 : Codable {
99
var a: String = ""
1010
var b: Int = 0
1111
var c: Nested = Nested()
12-
// expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'S1.Nested' does not conform to 'Decodable'}}
13-
// expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'S1.Nested' does not conform to 'Encodable'}}
12+
// expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'Nested' does not conform to 'Decodable'}}
13+
// expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'Nested' does not conform to 'Encodable'}}
1414
}
1515

1616
// Codable struct with non-enum CodingKeys.

test/decl/protocol/special/coding/struct_codable_simple.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ let _ = SimpleStruct.CodingKeys.self // expected-error {{'CodingKeys' is inacces
3434
struct SR_12248_1: Codable { // expected-error {{type 'SR_12248_1' does not conform to protocol 'Encodable'}}
3535
var x: Int // expected-note {{'x' previously declared here}}
3636
var x: Int // expected-error {{invalid redeclaration of 'x'}}
37-
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because '<<error type>>' does not conform to 'Encodable'}}
38-
// expected-note@-2 {{cannot automatically synthesize 'Encodable' because '<<error type>>' does not conform to 'Encodable'}}
37+
// expected-note@-1 {{cannot automatically synthesize 'Encodable' because 'Int' does not conform to 'Encodable'}}
38+
// expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'Int' does not conform to 'Encodable'}}
3939
}
4040

4141
struct SR_12248_2: Decodable {

0 commit comments

Comments
 (0)