Skip to content

Commit 335b029

Browse files
authored
Merge pull request swiftlang#15859 from itaiferber/codingkey-validation-invalid-typealias
2 parents 3cf0063 + bd02909 commit 335b029

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

lib/Sema/DerivedConformanceCodable.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,17 @@ static CodingKeysValidity hasValidCodingKeysEnum(TypeChecker &tc,
300300
if (!tc.conformsToProtocol(codingKeysType, codingKeyProto,
301301
target->getDeclContext(),
302302
ConformanceCheckFlags::Used)) {
303-
tc.diagnose(codingKeysTypeDecl->getLoc(),
304-
diag::codable_codingkeys_type_does_not_conform_here,
303+
// If CodingKeys is a typealias which doesn't point to a valid nominal type,
304+
// codingKeysTypeDecl will be nullptr here. In that case, we need to warn on
305+
// the location of the usage, since there isn't an underlying type to
306+
// diagnose on.
307+
SourceLoc loc = codingKeysTypeDecl ?
308+
codingKeysTypeDecl->getLoc() :
309+
cast<TypeDecl>(result)->getLoc();
310+
311+
tc.diagnose(loc, diag::codable_codingkeys_type_does_not_conform_here,
305312
proto->getDeclaredType());
313+
306314
return CodingKeysValidity(/*hasType=*/true, /*isValid=*/false);
307315
}
308316

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,12 @@ let _ = SimpleClass.encode(to:)
2525
// The synthesized CodingKeys type should not be accessible from outside the
2626
// class.
2727
let _ = SimpleClass.CodingKeys.self // expected-error {{'CodingKeys' is inaccessible due to 'private' protection level}}
28+
29+
// Classes with CodingKeys which are typealiases that don't point to a valid
30+
// nominal type should produce errors.
31+
struct ClassWithUndecredCodingKeys : Codable { // expected-error {{type 'ClassWithUndecredCodingKeys' does not conform to protocol 'Decodable'}}
32+
// expected-error@-1 {{type 'ClassWithUndecredCodingKeys' does not conform to protocol 'Encodable'}}
33+
private typealias CodingKeys = NonExistentType // expected-error {{use of undeclared type 'NonExistentType'}}
34+
// expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'CodingKeys' does not conform to CodingKey}}
35+
// expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'CodingKeys' does not conform to CodingKey}}
36+
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,12 @@ let _ = SimpleStruct.encode(to:)
2525
// The synthesized CodingKeys type should not be accessible from outside the
2626
// struct.
2727
let _ = SimpleStruct.CodingKeys.self // expected-error {{'CodingKeys' is inaccessible due to 'private' protection level}}
28+
29+
// Structs with CodingKeys which are typealiases that don't point to a valid
30+
// nominal type should produce errors.
31+
struct StructWithUndeclaredCodingKeys : Codable { // expected-error {{type 'StructWithUndeclaredCodingKeys' does not conform to protocol 'Decodable'}}
32+
// expected-error@-1 {{type 'StructWithUndeclaredCodingKeys' does not conform to protocol 'Encodable'}}
33+
private typealias CodingKeys = NonExistentType // expected-error {{use of undeclared type 'NonExistentType'}}
34+
// expected-note@-1 {{cannot automatically synthesize 'Decodable' because 'CodingKeys' does not conform to CodingKey}}
35+
// expected-note@-2 {{cannot automatically synthesize 'Encodable' because 'CodingKeys' does not conform to CodingKey}}
36+
}

0 commit comments

Comments
 (0)