@@ -441,71 +441,71 @@ static void deriveBodyEncodable_encode(AbstractFunctionDecl *encodeDecl) {
441
441
DeclNameLoc (), /* Implicit=*/ true ,
442
442
AccessSemantics::DirectToStorage);
443
443
444
- auto enumElements = codingKeysEnum->getAllElements ();
445
- if (!enumElements.empty ()) {
446
- // Need to generate
447
- // `let container = encoder.container(keyedBy: CodingKeys.self)`
448
- // `let container` (containerExpr) is generated above.
449
-
450
- // encoder
451
- auto encoderParam = encodeDecl->getParameterList (1 )->get (0 );
452
- auto *encoderExpr = new (C) DeclRefExpr (ConcreteDeclRef (encoderParam),
453
- DeclNameLoc (), /* Implicit=*/ true );
454
-
455
- // Bound encoder.container(keyedBy: CodingKeys.self) call
456
- auto containerType = containerDecl->getInterfaceType ();
457
- auto *callExpr = createContainerKeyedByCall (C, funcDC, encoderExpr,
458
- containerType, codingKeysEnum);
459
-
460
- // Full `let container = encoder.container(keyedBy: CodingKeys.self)`
461
- // binding.
462
- auto *containerPattern = new (C) NamedPattern (containerDecl,
463
- /* implicit=*/ true );
464
- auto *bindingDecl = PatternBindingDecl::create (C, SourceLoc (),
465
- StaticSpellingKind::None,
466
- SourceLoc (),
467
- containerPattern, callExpr,
468
- funcDC);
469
- statements.push_back (bindingDecl);
470
- statements.push_back (containerDecl);
471
-
472
- // Now need to generate `try container.encode(x, forKey: .x)` for all
473
- // existing properties.
474
- for (auto *elt : enumElements) {
475
- // Only ill-formed code would produce multiple results for this lookup.
476
- // This would get diagnosed later anyway, so we're free to only look at
477
- // the first result here.
478
- auto matchingVars = typeDecl->lookupDirect (DeclName (elt->getName ()));
479
-
480
- // self.x
481
- auto *selfRef = createSelfDeclRef (encodeDecl);
482
- auto *varExpr = new (C) MemberRefExpr (selfRef, SourceLoc (),
483
- ConcreteDeclRef (matchingVars[0 ]),
484
- DeclNameLoc (), /* Implicit=*/ true );
485
-
486
- // CodingKeys.x
487
- auto *eltRef = new (C) DeclRefExpr (elt, DeclNameLoc (), /* implicit=*/ true );
488
- auto *metaTyRef = TypeExpr::createImplicit (codingKeysType, C);
489
- auto *keyExpr = new (C) DotSyntaxCallExpr (eltRef, SourceLoc (), metaTyRef);
490
-
491
- // encode(_:forKey:)
492
- SmallVector<Identifier, 2 > argNames{Identifier (), C.Id_forKey };
493
- DeclName name (C, C.Id_encode , argNames);
494
- auto *encodeCall = new (C) UnresolvedDotExpr (containerExpr, SourceLoc (),
495
- name, DeclNameLoc (),
496
- /* Implicit=*/ true );
497
-
498
- // container.encode(self.x, forKey: CodingKeys.x)
499
- Expr *args[2 ] = {varExpr, keyExpr};
500
- auto *callExpr = CallExpr::createImplicit (C, encodeCall,
501
- C.AllocateCopy (args),
502
- C.AllocateCopy (argNames));
444
+ // Need to generate
445
+ // `let container = encoder.container(keyedBy: CodingKeys.self)`
446
+ // This is unconditional because a type with no properties should encode as an
447
+ // empty container.
448
+ //
449
+ // `let container` (containerExpr) is generated above.
450
+
451
+ // encoder
452
+ auto encoderParam = encodeDecl->getParameterList (1 )->get (0 );
453
+ auto *encoderExpr = new (C) DeclRefExpr (ConcreteDeclRef (encoderParam),
454
+ DeclNameLoc (), /* Implicit=*/ true );
455
+
456
+ // Bound encoder.container(keyedBy: CodingKeys.self) call
457
+ auto containerType = containerDecl->getInterfaceType ();
458
+ auto *callExpr = createContainerKeyedByCall (C, funcDC, encoderExpr,
459
+ containerType, codingKeysEnum);
460
+
461
+ // Full `let container = encoder.container(keyedBy: CodingKeys.self)`
462
+ // binding.
463
+ auto *containerPattern = new (C) NamedPattern (containerDecl,
464
+ /* implicit=*/ true );
465
+ auto *bindingDecl = PatternBindingDecl::create (C, SourceLoc (),
466
+ StaticSpellingKind::None,
467
+ SourceLoc (),
468
+ containerPattern, callExpr,
469
+ funcDC);
470
+ statements.push_back (bindingDecl);
471
+ statements.push_back (containerDecl);
472
+
473
+ // Now need to generate `try container.encode(x, forKey: .x)` for all
474
+ // existing properties.
475
+ for (auto *elt : codingKeysEnum->getAllElements ()) {
476
+ // Only ill-formed code would produce multiple results for this lookup.
477
+ // This would get diagnosed later anyway, so we're free to only look at
478
+ // the first result here.
479
+ auto matchingVars = typeDecl->lookupDirect (DeclName (elt->getName ()));
480
+
481
+ // self.x
482
+ auto *selfRef = createSelfDeclRef (encodeDecl);
483
+ auto *varExpr = new (C) MemberRefExpr (selfRef, SourceLoc (),
484
+ ConcreteDeclRef (matchingVars[0 ]),
485
+ DeclNameLoc (), /* Implicit=*/ true );
486
+
487
+ // CodingKeys.x
488
+ auto *eltRef = new (C) DeclRefExpr (elt, DeclNameLoc (), /* implicit=*/ true );
489
+ auto *metaTyRef = TypeExpr::createImplicit (codingKeysType, C);
490
+ auto *keyExpr = new (C) DotSyntaxCallExpr (eltRef, SourceLoc (), metaTyRef);
491
+
492
+ // encode(_:forKey:)
493
+ SmallVector<Identifier, 2 > argNames{Identifier (), C.Id_forKey };
494
+ DeclName name (C, C.Id_encode , argNames);
495
+ auto *encodeCall = new (C) UnresolvedDotExpr (containerExpr, SourceLoc (),
496
+ name, DeclNameLoc (),
497
+ /* Implicit=*/ true );
498
+
499
+ // container.encode(self.x, forKey: CodingKeys.x)
500
+ Expr *args[2 ] = {varExpr, keyExpr};
501
+ auto *callExpr = CallExpr::createImplicit (C, encodeCall,
502
+ C.AllocateCopy (args),
503
+ C.AllocateCopy (argNames));
503
504
504
- // try container.encode(self.x, forKey: CodingKeys.x)
505
- auto *tryExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
506
- /* Implicit=*/ true );
507
- statements.push_back (tryExpr);
508
- }
505
+ // try container.encode(self.x, forKey: CodingKeys.x)
506
+ auto *tryExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
507
+ /* Implicit=*/ true );
508
+ statements.push_back (tryExpr);
509
509
}
510
510
511
511
// Classes which inherit from something Codable should encode super as well.
0 commit comments