@@ -75,7 +75,7 @@ static Identifier getVarNameForCoding(VarDecl *var) {
75
75
// / match with the stored vars of the given type.
76
76
// /
77
77
// / \param codingKeysDecl The \c CodingKeys enum decl to validate.
78
- static bool validateCodingKeysEnum (DerivedConformance &derived,
78
+ static bool validateCodingKeysEnum (const DerivedConformance &derived,
79
79
EnumDecl *codingKeysDecl) {
80
80
auto conformanceDC = derived.getConformanceContext ();
81
81
@@ -160,11 +160,14 @@ static bool validateCodingKeysEnum(DerivedConformance &derived,
160
160
}
161
161
162
162
// / A type which has information about the validity of an encountered
163
- // / CodingKeys type.
164
- struct CodingKeysValidity {
165
- bool hasType;
166
- bool isValid;
167
- CodingKeysValidity (bool ht, bool iv) : hasType(ht), isValid(iv) {}
163
+ // / \c CodingKeys type.
164
+ enum class CodingKeysClassification {
165
+ // / A \c CodingKeys declaration was found, but it is invalid.
166
+ Invalid,
167
+ // / No \c CodingKeys declaration was found, so it must be synthesized.
168
+ NeedsSynthesizedCodingKeys,
169
+ // / A valid \c CodingKeys declaration was found.
170
+ Valid,
168
171
};
169
172
170
173
// / Returns whether the given type has a valid nested \c CodingKeys enum.
@@ -176,12 +179,14 @@ struct CodingKeysValidity {
176
179
// / enum.
177
180
// /
178
181
// / \returns A \c CodingKeysValidity value representing the result of the check.
179
- static CodingKeysValidity hasValidCodingKeysEnum (DerivedConformance &derived) {
182
+ static CodingKeysClassification
183
+ classifyCodingKeys (const DerivedConformance &derived) {
180
184
auto &C = derived.Context ;
181
185
auto codingKeysDecls =
182
186
derived.Nominal ->lookupDirect (DeclName (C.Id_CodingKeys ));
183
- if (codingKeysDecls.empty ())
184
- return CodingKeysValidity (/* hasType=*/ false , /* isValid=*/ true );
187
+ if (codingKeysDecls.empty ()) {
188
+ return CodingKeysClassification::NeedsSynthesizedCodingKeys;
189
+ }
185
190
186
191
// Only ill-formed code would produce multiple results for this lookup.
187
192
// This would get diagnosed later anyway, so we're free to only look at the
@@ -192,7 +197,7 @@ static CodingKeysValidity hasValidCodingKeysEnum(DerivedConformance &derived) {
192
197
if (!codingKeysTypeDecl) {
193
198
result->diagnose (diag::codable_codingkeys_type_is_not_an_enum_here,
194
199
derived.getProtocolType ());
195
- return CodingKeysValidity ( /* hasType= */ true , /* isValid= */ false ) ;
200
+ return CodingKeysClassification::Invalid ;
196
201
}
197
202
198
203
// CodingKeys may be a typealias. If so, follow the alias to its canonical
@@ -216,7 +221,7 @@ static CodingKeysValidity hasValidCodingKeysEnum(DerivedConformance &derived) {
216
221
C.Diags .diagnose (loc, diag::codable_codingkeys_type_does_not_conform_here,
217
222
derived.getProtocolType ());
218
223
219
- return CodingKeysValidity ( /* hasType= */ true , /* isValid= */ false ) ;
224
+ return CodingKeysClassification::Invalid ;
220
225
}
221
226
222
227
// CodingKeys must be an enum for synthesized conformance.
@@ -225,11 +230,12 @@ static CodingKeysValidity hasValidCodingKeysEnum(DerivedConformance &derived) {
225
230
codingKeysTypeDecl->diagnose (
226
231
diag::codable_codingkeys_type_is_not_an_enum_here,
227
232
derived.getProtocolType ());
228
- return CodingKeysValidity ( /* hasType= */ true , /* isValid= */ false ) ;
233
+ return CodingKeysClassification::Invalid ;
229
234
}
230
235
231
- bool valid = validateCodingKeysEnum (derived, codingKeysEnum);
232
- return CodingKeysValidity (/* hasType=*/ true , /* isValid=*/ valid);
236
+ return validateCodingKeysEnum (derived, codingKeysEnum)
237
+ ? CodingKeysClassification::Valid
238
+ : CodingKeysClassification::Invalid;
233
239
}
234
240
235
241
// / Synthesizes a new \c CodingKeys enum based on the {En,De}codable members of
@@ -1071,19 +1077,18 @@ static bool canSynthesize(DerivedConformance &derived, ValueDecl *requirement) {
1071
1077
1072
1078
// If the target already has a valid CodingKeys enum, we won't need to
1073
1079
// synthesize one.
1074
- auto validity = hasValidCodingKeysEnum (derived);
1075
-
1076
- // We found a type, but it wasn't valid.
1077
- if (!validity.isValid )
1080
+ switch (classifyCodingKeys (derived)) {
1081
+ case CodingKeysClassification::Invalid:
1078
1082
return false ;
1079
-
1080
- // We can try to synthesize a type here.
1081
- if (!validity.hasType ) {
1083
+ case CodingKeysClassification::NeedsSynthesizedCodingKeys: {
1082
1084
auto *synthesizedEnum = synthesizeCodingKeysEnum (derived);
1083
1085
if (!synthesizedEnum)
1084
1086
return false ;
1087
+ }
1088
+ LLVM_FALLTHROUGH;
1089
+ case CodingKeysClassification::Valid:
1090
+ return true ;
1085
1091
}
1086
-
1087
1092
return true ;
1088
1093
}
1089
1094
0 commit comments