@@ -252,27 +252,36 @@ convertToUnqualifiedLookupOptions(NameLookupOptions options) {
252
252
return newOptions;
253
253
}
254
254
255
+ // / HACK: Qualified lookup cannot be allowed to synthesize CodingKeys because
256
+ // / it would lead to a number of egregious cycles through QualifiedLookupRequest
257
+ // / when we resolve the protocol conformance. Codable's magic has pushed its way
258
+ // / so deeply into the compiler, when doing unqualified lookup we have to
259
+ // / pessimistically force every nominal context above this one to synthesize it
260
+ // / in the event the user needs it from e.g. a non-primary input.
261
+ // /
262
+ // / We can undo this if Codable's semantic content is divorced from its
263
+ // / syntactic content - so we synthesize just enough to allow lookups to
264
+ // / succeed, but don't force protocol conformances while we're doing it.
265
+ static void synthesizeCodingKeysIfNeededForUnqualifiedLookup (ASTContext &ctx,
266
+ DeclContext *dc,
267
+ DeclNameRef name) {
268
+ if (name.getBaseIdentifier () != ctx.Id_CodingKeys )
269
+ return ;
270
+
271
+ for (auto typeCtx = dc->getInnermostTypeContext (); typeCtx != nullptr ;
272
+ typeCtx = typeCtx->getParent ()->getInnermostTypeContext ()) {
273
+ if (auto *nominal = typeCtx->getSelfNominalTypeDecl ())
274
+ nominal->synthesizeSemanticMembersIfNeeded (name.getFullName ());
275
+ }
276
+ }
277
+
255
278
LookupResult TypeChecker::lookupUnqualified (DeclContext *dc, DeclNameRef name,
256
279
SourceLoc loc,
257
280
NameLookupOptions options) {
258
281
auto &ctx = dc->getASTContext ();
259
- // HACK: Qualified lookup cannot be allowed to synthesize CodingKeys because
260
- // it would lead to a number of egregious cycles through
261
- // QualifiedLookupRequest when we resolve the protocol conformance. Codable's
262
- // magic has pushed its way so deeply into the compiler, we have to
263
- // pessimistically force every nominal context above this one to synthesize
264
- // it in the event the user needs it from e.g. a non-primary input.
265
- // We can undo this if Codable's semantic content is divorced from its
266
- // syntactic content - so we synthesize just enough to allow lookups to
267
- // succeed, but don't force protocol conformances while we're doing it.
268
- if (name.getBaseIdentifier () == ctx.Id_CodingKeys ) {
269
- for (auto typeCtx = dc->getInnermostTypeContext (); typeCtx != nullptr ;
270
- typeCtx = typeCtx->getParent ()->getInnermostTypeContext ()) {
271
- if (auto *nominal = typeCtx->getSelfNominalTypeDecl ()) {
272
- nominal->synthesizeSemanticMembersIfNeeded (name.getFullName ());
273
- }
274
- }
275
- }
282
+
283
+ // HACK: Synthesize CodingKeys if needed.
284
+ synthesizeCodingKeysIfNeededForUnqualifiedLookup (ctx, dc, name);
276
285
277
286
auto ulOptions = convertToUnqualifiedLookupOptions (options);
278
287
auto descriptor = UnqualifiedLookupDescriptor (name, dc, loc, ulOptions);
@@ -314,6 +323,10 @@ TypeChecker::lookupUnqualifiedType(DeclContext *dc, DeclNameRef name,
314
323
SourceLoc loc,
315
324
NameLookupOptions options) {
316
325
auto &ctx = dc->getASTContext ();
326
+
327
+ // HACK: Synthesize CodingKeys if needed.
328
+ synthesizeCodingKeysIfNeededForUnqualifiedLookup (ctx, dc, name);
329
+
317
330
auto ulOptions = convertToUnqualifiedLookupOptions (options) |
318
331
UnqualifiedLookupFlags::TypeLookup;
319
332
{
0 commit comments