-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Explicit Codable & CodingKey Derived Conformance #8125
Changes from all commits
c41aabe
d7651eb
888fded
b98b68e
8ab7f87
f4d7d43
369a89b
a411077
a1902cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2092,9 +2092,42 @@ bool NominalTypeDecl::derivesProtocolConformance(ProtocolDecl *protocol) const { | |
case KnownProtocolKind::BridgedNSError: | ||
return isObjC() && enumDecl->hasOnlyCasesWithoutAssociatedValues(); | ||
|
||
// Enums without associated values and enums with a raw type of String | ||
// or Int can explicitly derive CodingKey conformance. | ||
case KnownProtocolKind::CodingKey: { | ||
Type rawType = enumDecl->getRawType(); | ||
if (rawType) { | ||
auto parentDC = enumDecl->getDeclContext(); | ||
ASTContext &C = parentDC->getASTContext(); | ||
|
||
auto nominal = rawType->getAnyNominal(); | ||
return nominal == C.getStringDecl() || nominal == C.getIntDecl(); | ||
} | ||
|
||
// Empty enums are allowed to conform as well. | ||
return enumDecl->getAllElements().empty() || | ||
enumDecl->hasOnlyCasesWithoutAssociatedValues(); | ||
} | ||
|
||
default: | ||
return false; | ||
} | ||
} else if (isa<StructDecl>(this) || isa<ClassDecl>(this)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This violates LLVM style: http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return All of the code paths before the else if return. The else is not necessary. In fact, you could even invert the if condition and do an early return false if you want to. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When you fix this, can you also add a * to the auto above on knownProtocol. (Or even change it to a reference). I know that this is something that is not in the code that you have touched yourself. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixing the else after return. |
||
// Structs and classes can explicitly derive Encodable and Decodable | ||
// conformance (explicitly meaning we can synthesize an implementation if | ||
// a type conforms manually). | ||
if (*knownProtocol == KnownProtocolKind::Encodable || | ||
*knownProtocol == KnownProtocolKind::Decodable) { | ||
// FIXME: This is not actually correct. We cannot promise to always | ||
// provide a witness here for all structs and classes. Unfortunately, | ||
// figuring out whether this is actually possible requires much more | ||
// context -- a TypeChecker and the parent decl context at least -- and is | ||
// tightly coupled to the logic within DerivedConformance. | ||
// This unfortunately means that we expect a witness even if one will not | ||
// be produced, which requires DerivedConformance::deriveCodable to output | ||
// its own diagnostics. | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a heads up: I'm changing
hasOnlyCasesWithoutAssociatedValues
so you no longer need the first part of this clause.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CodaFi Thanks for the heads up on this. (Sorry for the delay, got back from vacation yesterday.) Is this change in, or not yet? Any good way for me to track the change so I can update accordingly?