@@ -199,14 +199,6 @@ static bool validateCodingKeysEnum(DerivedConformance &derived,
199
199
return propertiesAreValid;
200
200
}
201
201
202
- // / A type which has information about the validity of an encountered
203
- // / CodingKeys type.
204
- struct CodingKeysValidity {
205
- bool hasType;
206
- bool isValid;
207
- CodingKeysValidity (bool ht, bool iv) : hasType(ht), isValid(iv) {}
208
- };
209
-
210
202
// / Returns whether the given type has a valid nested \c CodingKeys enum.
211
203
// /
212
204
// / If the type has an invalid \c CodingKeys entity, produces diagnostics to
@@ -216,12 +208,12 @@ struct CodingKeysValidity {
216
208
// / enum.
217
209
// /
218
210
// / \returns A \c CodingKeysValidity value representing the result of the check.
219
- static CodingKeysValidity hasValidCodingKeysEnum (DerivedConformance &derived) {
211
+ static TypeDecl * getExistingValidCodingKeysDecl (DerivedConformance &derived) {
220
212
auto &C = derived.Context ;
221
213
auto codingKeysDecls =
222
214
derived.Nominal ->lookupDirect (DeclName (C.Id_CodingKeys ));
223
215
if (codingKeysDecls.empty ())
224
- return CodingKeysValidity ( /* hasType= */ false , /* isValid= */ true ) ;
216
+ return nullptr ;
225
217
226
218
// Only ill-formed code would produce multiple results for this lookup.
227
219
// This would get diagnosed later anyway, so we're free to only look at the
@@ -232,7 +224,7 @@ static CodingKeysValidity hasValidCodingKeysEnum(DerivedConformance &derived) {
232
224
if (!codingKeysTypeDecl) {
233
225
result->diagnose (diag::codable_codingkeys_type_is_not_an_enum_here,
234
226
derived.getProtocolType ());
235
- return CodingKeysValidity ( /* hasType= */ true , /* isValid= */ false ) ;
227
+ return nullptr ;
236
228
}
237
229
238
230
// CodingKeys may be a typealias. If so, follow the alias to its canonical
@@ -256,7 +248,7 @@ static CodingKeysValidity hasValidCodingKeysEnum(DerivedConformance &derived) {
256
248
C.Diags .diagnose (loc, diag::codable_codingkeys_type_does_not_conform_here,
257
249
derived.getProtocolType ());
258
250
259
- return CodingKeysValidity ( /* hasType= */ true , /* isValid= */ false ) ;
251
+ return nullptr ;
260
252
}
261
253
262
254
// CodingKeys must be an enum for synthesized conformance.
@@ -265,11 +257,15 @@ static CodingKeysValidity hasValidCodingKeysEnum(DerivedConformance &derived) {
265
257
codingKeysTypeDecl->diagnose (
266
258
diag::codable_codingkeys_type_is_not_an_enum_here,
267
259
derived.getProtocolType ());
268
- return CodingKeysValidity (/* hasType=*/ true , /* isValid=*/ false );
260
+ return nullptr ;
261
+ }
262
+
263
+ // FIXME: This is a really expensive check.
264
+ if (!validateCodingKeysEnum (derived, codingKeysEnum)) {
265
+ return nullptr ;
269
266
}
270
267
271
- bool valid = validateCodingKeysEnum (derived, codingKeysEnum);
272
- return CodingKeysValidity (/* hasType=*/ true , /* isValid=*/ valid);
268
+ return codingKeysEnum;
273
269
}
274
270
275
271
// / Synthesizes a new \c CodingKeys enum based on the {En,De}codable members of
@@ -317,24 +313,12 @@ static EnumDecl *synthesizeCodingKeysEnum(DerivedConformance &derived) {
317
313
if (!varDecl->isUserAccessible ())
318
314
continue ;
319
315
320
- // Despite creating the enum in the context of the type, we're
321
- // concurrently checking the variables for the current protocol
322
- // conformance being synthesized, for which we use the conformance
323
- // context, not the type.
324
- auto conformance = varConformsToCodable (derived.getConformanceContext (),
325
- varDecl, derived.Protocol );
326
- if (conformance.isInvalid ()) {
327
- varDecl->diagnose (diag::codable_non_conforming_property_here,
328
- derived.getProtocolType (), varDecl->getType ());
329
- allConform = false ;
330
- } else {
331
- auto *elt = new (C) EnumElementDecl (SourceLoc (),
332
- getVarNameForCoding (varDecl),
333
- nullptr , SourceLoc (), nullptr ,
334
- enumDecl);
335
- elt->setImplicit ();
336
- enumDecl->addMember (elt);
337
- }
316
+ auto *elt = new (C) EnumElementDecl (SourceLoc (),
317
+ getVarNameForCoding (varDecl),
318
+ nullptr , SourceLoc (), nullptr ,
319
+ enumDecl);
320
+ elt->setImplicit ();
321
+ enumDecl->addMember (elt);
338
322
}
339
323
340
324
if (!allConform)
@@ -1070,22 +1054,8 @@ static bool canSynthesize(DerivedConformance &derived, ValueDecl *requirement) {
1070
1054
}
1071
1055
}
1072
1056
1073
- // If the target already has a valid CodingKeys enum, we won't need to
1074
- // synthesize one.
1075
- auto validity = hasValidCodingKeysEnum (derived);
1076
-
1077
- // We found a type, but it wasn't valid.
1078
- if (!validity.isValid )
1079
- return false ;
1080
-
1081
- // We can try to synthesize a type here.
1082
- if (!validity.hasType ) {
1083
- auto *synthesizedEnum = synthesizeCodingKeysEnum (derived);
1084
- if (!synthesizedEnum)
1085
- return false ;
1086
- }
1087
-
1088
- return true ;
1057
+ // Validate the CodingKeys enum.
1058
+ return getExistingValidCodingKeysDecl (derived) != nullptr ;
1089
1059
}
1090
1060
1091
1061
ValueDecl *DerivedConformance::deriveEncodable (ValueDecl *requirement) {
0 commit comments