Skip to content

Commit db30c77

Browse files
committed
[SE-0258] Adjust name for CodingKeys property to drop the '$'.
When synthesizing Codable conformances, the enum case name for a property with an attached delegate does not have the '$', i.e., it's the name of the originally-declared property.
1 parent 5df8897 commit db30c77

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

lib/Sema/DerivedConformanceCodable.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ static CodableConformanceType varConformsToCodable(TypeChecker &tc,
136136
isIUO, proto);
137137
}
138138

139+
/// Retrieve the variable name for the purposes of encoding/decoding.
140+
static Identifier getVarNameForCoding(VarDecl *var) {
141+
if (auto originalVar = var->getOriginalDelegatedProperty())
142+
return originalVar->getName();
143+
144+
return var->getName();
145+
}
146+
139147
/// Validates the given CodingKeys enum decl by ensuring its cases are a 1-to-1
140148
/// match with the stored vars of the given type.
141149
///
@@ -162,7 +170,7 @@ static bool validateCodingKeysEnum(DerivedConformance &derived,
162170
if (varDecl->getAttrs().hasAttribute<LazyAttr>())
163171
continue;
164172

165-
properties[varDecl->getName()] = varDecl;
173+
properties[getVarNameForCoding(varDecl)] = varDecl;
166174
}
167175

168176
bool propertiesAreValid = true;
@@ -365,7 +373,8 @@ static EnumDecl *synthesizeCodingKeysEnum(DerivedConformance &derived) {
365373
switch (conformance) {
366374
case Conforms:
367375
{
368-
auto *elt = new (C) EnumElementDecl(SourceLoc(), varDecl->getName(),
376+
auto *elt = new (C) EnumElementDecl(SourceLoc(),
377+
getVarNameForCoding(varDecl),
369378
nullptr, SourceLoc(), nullptr,
370379
enumDecl);
371380
elt->setImplicit();
@@ -518,6 +527,11 @@ lookupVarDeclForCodingKeysCase(DeclContext *conformanceDC,
518527
NominalTypeDecl *targetDecl) {
519528
for (auto decl : targetDecl->lookupDirect(DeclName(elt->getName()))) {
520529
if (auto *vd = dyn_cast<VarDecl>(decl)) {
530+
// If we found a property with an attached delegate, retrieve the
531+
// backing property.
532+
if (auto backingVar = vd->getPropertyDelegateBackingProperty())
533+
vd = backingVar;
534+
521535
if (!vd->isStatic()) {
522536
// This is the VarDecl we're looking for.
523537

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown
2+
3+
@_propertyDelegate
4+
struct Wrapper<T: Codable> {
5+
var value: T
6+
}
7+
8+
@_propertyDelegate
9+
struct WrapperWithInitialValue<T: Codable> {
10+
var value: T
11+
12+
init(initialValue: T) {
13+
self.value = initialValue
14+
}
15+
}
16+
17+
extension WrapperWithInitialValue: Codable { }
18+
19+
struct X: Codable {
20+
@WrapperWithInitialValue var foo = 17
21+
22+
// Make sure the generated key is named 'foo', like the original property.
23+
private func getFooKey() -> CodingKeys {
24+
return .foo
25+
}
26+
}
27+
28+
29+
30+
// expected-error@+2{{type 'Y' does not conform to protocol 'Encodable'}}
31+
// expected-error@+1{{type 'Y' does not conform to protocol 'Decodable'}}
32+
struct Y: Codable {
33+
@Wrapper var foo: Int
34+
// expected-note@-1{{cannot automatically synthesize 'Encodable' because 'Wrapper<Int>' does not conform to 'Encodable'}}
35+
// expected-note@-2{{cannot automatically synthesize 'Decodable' because 'Wrapper<Int>' does not conform to 'Decodable'}}
36+
37+
}

0 commit comments

Comments
 (0)