Skip to content

Conversation

itaiferber
Copy link
Contributor

What's in this pull request?
Resolves a crash which would happen if your Codable type declared its CodingKeys enum as a typealias to a nonexistent type. This allows us to diagnose on the usage of the undeclared identifier instead of crashing.

Resolves rdar://problem/39021733.

@itaiferber itaiferber requested a review from jrose-apple April 10, 2018 22:46
@itaiferber
Copy link
Contributor Author

@swift-ci Please test

@@ -300,9 +300,17 @@ static CodingKeysValidity hasValidCodingKeysEnum(TypeChecker &tc,
if (!tc.conformsToProtocol(codingKeysType, codingKeyProto,
target->getDeclContext(),
ConformanceCheckFlags::Used)) {
tc.diagnose(codingKeysTypeDecl->getLoc(),
diag::codable_codingkeys_type_does_not_conform_here,
// If CodingKeys is a typealias which doesn't point to a valid nominal type,
Copy link
Contributor

@slavapestov slavapestov Apr 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The codable_codingkeys_type_is_not_an_enum_here diagnostic seems misleading, because we never actually check that codingKeysDecl is an enum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do that below on line 318

codingKeysTypeDecl->getLoc() :
cast<TypeDecl>(result)->getLoc();

tc.diagnose(loc, diag::codable_codingkeys_type_does_not_conform_here,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you can suppress this diagnostic if codingKeysTypeDecl->isInvalid(). In your test case you're emitting it twice which is not ideal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you conform to Codable, we go through synthesis twice — once for Decodable, and once for Encodable. There isn't a great way to signal that Decodable synthesis has gone through so Encodable synthesis shouldn't warn, and vice versa.

We can also suppress the diagnostic here if codingKeysTypeDecl is nullptr and just let the error message through. I do think it can be helpful to have the note as well to indicate that we at least looked at this decl, but it's not the end of the world either way.

@@ -300,9 +300,17 @@ static CodingKeysValidity hasValidCodingKeysEnum(TypeChecker &tc,
if (!tc.conformsToProtocol(codingKeysType, codingKeyProto,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need this part at all?

if (isa<TypeAliasDecl>(codingKeysTypeDecl))
     codingKeysTypeDecl = codingKeysType->getAnyNominal();

You're not using codingKeysDecl below for anything, except to get its location. So why not always use the location of the original type to diagnose, even if it was a type alias?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See also the check on line 318; we confirm that the decl itself is indeed an enum

@itaiferber
Copy link
Contributor Author

@slavapestov @jrose-apple Any further feedback here? Happy to address any concerns.

@jrose-apple
Copy link
Contributor

I'm good if Slava is.

@slavapestov
Copy link
Contributor

LGTM

@itaiferber
Copy link
Contributor Author

@swift-ci Please test and merge

@swift-ci swift-ci merged commit 335b029 into swiftlang:master Apr 19, 2018
@itaiferber itaiferber deleted the codingkey-validation-invalid-typealias branch April 19, 2018 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants