Skip to content

Commit 6df3fcf

Browse files
committed
Add Missing Definitions of canDerive{En,De}codable
1 parent 55fd879 commit 6df3fcf

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

lib/Sema/DerivedConformanceCodable.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -1071,10 +1071,35 @@ static bool canSynthesize(DerivedConformance &derived, ValueDecl *requirement) {
10711071
LLVM_FALLTHROUGH;
10721072
case CodingKeysClassification::Valid:
10731073
return true;
1074+
static bool canDeriveCodable(NominalTypeDecl *NTD,
1075+
KnownProtocolKind Kind) {
1076+
assert(Kind == KnownProtocolKind::Encodable ||
1077+
Kind == KnownProtocolKind::Decodable);
1078+
1079+
// Structs and classes can explicitly derive Encodable and Decodable
1080+
// conformance (explicitly meaning we can synthesize an implementation if
1081+
// a type conforms manually).
1082+
// FIXME: Enums too!
1083+
if (!isa<StructDecl>(NTD) && !isa<ClassDecl>(NTD)) {
1084+
return false;
10741085
}
1086+
1087+
auto *PD = NTD->getASTContext().getProtocol(Kind);
1088+
if (!PD) {
1089+
return false;
1090+
}
1091+
10751092
return true;
10761093
}
10771094

1095+
bool DerivedConformance::canDeriveDecodable(NominalTypeDecl *NTD) {
1096+
return canDeriveCodable(NTD, KnownProtocolKind::Decodable);
1097+
}
1098+
1099+
bool DerivedConformance::canDeriveEncodable(NominalTypeDecl *NTD) {
1100+
return canDeriveCodable(NTD, KnownProtocolKind::Encodable);
1101+
}
1102+
10781103
ValueDecl *DerivedConformance::deriveEncodable(ValueDecl *requirement) {
10791104
// We can only synthesize Encodable for structs and classes.
10801105
if (!isa<StructDecl>(Nominal) && !isa<ClassDecl>(Nominal))

lib/Sema/DerivedConformances.cpp

+15-25
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ bool DerivedConformance::derivesProtocolConformance(DeclContext *DC,
8888
if (*derivableKind == KnownDerivableProtocolKind::Differentiable)
8989
return true;
9090

91+
if (*derivableKind == KnownDerivableProtocolKind::Encodable) {
92+
return canDeriveEncodable(Nominal);
93+
}
94+
95+
if (*derivableKind == KnownDerivableProtocolKind::Decodable) {
96+
return canDeriveDecodable(Nominal);
97+
}
98+
9199
if (auto *enumDecl = dyn_cast<EnumDecl>(Nominal)) {
92100
switch (*derivableKind) {
93101
// The presence of a raw type is an explicit declaration that
@@ -137,31 +145,13 @@ bool DerivedConformance::derivesProtocolConformance(DeclContext *DC,
137145
default:
138146
return false;
139147
}
140-
} else if (isa<StructDecl>(Nominal) || isa<ClassDecl>(Nominal)) {
141-
// Structs and classes can explicitly derive Encodable and Decodable
142-
// conformance (explicitly meaning we can synthesize an implementation if
143-
// a type conforms manually).
144-
if (*derivableKind == KnownDerivableProtocolKind::Encodable ||
145-
*derivableKind == KnownDerivableProtocolKind::Decodable) {
146-
// FIXME: This is not actually correct. We cannot promise to always
147-
// provide a witness here for all structs and classes. Unfortunately,
148-
// figuring out whether this is actually possible requires much more
149-
// context -- a TypeChecker and the parent decl context at least -- and is
150-
// tightly coupled to the logic within DerivedConformance.
151-
// This unfortunately means that we expect a witness even if one will not
152-
// be produced, which requires DerivedConformance::deriveCodable to output
153-
// its own diagnostics.
154-
return true;
155-
}
156-
157-
// Structs can explicitly derive Equatable conformance.
158-
if (isa<StructDecl>(Nominal)) {
159-
switch (*derivableKind) {
160-
case KnownDerivableProtocolKind::Equatable:
161-
return canDeriveEquatable(DC, Nominal);
162-
default:
163-
return false;
164-
}
148+
} else if (isa<StructDecl>(Nominal)) {
149+
switch (*derivableKind) {
150+
case KnownDerivableProtocolKind::Equatable:
151+
// Structs can explicitly derive Equatable conformance.
152+
return canDeriveEquatable(DC, Nominal);
153+
default:
154+
return false;
165155
}
166156
}
167157
return false;

lib/Sema/DerivedConformances.h

+5
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,11 @@ class DerivedConformance {
278278
/// \returns the derived member, which will also be added to the type.
279279
ValueDecl *deriveBridgedNSError(ValueDecl *requirement);
280280

281+
/// Determine if \c Encodable can be derived for the given type.
282+
static bool canDeriveEncodable(NominalTypeDecl *NTD);
283+
/// Determine if \c Decodable can be derived for the given type.
284+
static bool canDeriveDecodable(NominalTypeDecl *NTD);
285+
281286
/// Derive a CodingKey requirement for an enum type.
282287
///
283288
/// \returns the derived member, which will also be added to the type.

0 commit comments

Comments
 (0)