Uploaded image for project: 'Swift'
  1. Swift
  2. SR-10045

Codable synthesis fails when instance property and static property share the same name

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Medium
    • Resolution: Done
    • Component/s: Compiler
    • Labels:
    • Environment:

      Originally found on Swift 4.2.2 running on Ubuntu 18.04

      Reproduced on Swift 4.2 running on macOS 10.14.3

      Reproduced on Swift 5 beta 4 running on macOS 10.14.3

      Description

      Details

      Variation 1

      Given the following code:

      import Foundation
      
      struct MyStruct: Decodable {
          static let name = "aaa"
          let _id: String?
          let name: PersonNameComponents?
      }
      
      let decoded = try JSONDecoder().decode(MyStruct.self, from: "{\"_id\": \"abc123\", \"name\": { \"givenName\": \"John\"}}".data(using: .utf8)!)
      
      print(decoded.name!)
      

      The following error is produced:

      Swift5.playground:6:9: note: 'self.name' not initialized
          let name: PersonNameComponents?
              ^
      

      Swift fails to understand that Decodable synthesis should only take into account instance property names and should ignore static property names. By having an instance property and static property with the same name, it confuses the compiler into not adding the Decodable synthesis for that particular property.

      If the static property name is changed then Decodable synthesis works correctly. 

      Variation 2

      Given the following code (note the instance property is now a var instead of a let):

      import Foundation
      
      struct MyStruct: Decodable {
          static let name = "aaa"
          let _id: String?
          var name: PersonNameComponents?
      }
      
      
      let decoded = try JSONDecoder().decode(MyStruct.self, from: "{\"_id\": \"abc123\", \"name\": { \"givenName\": \"John\"}}".data(using: .utf8)!)
      
      
      print(decoded.name)
      

      The following output is produced:

      nil

      This is arguably a worse result as it is not found at compile time and only found at run time. This means that code that should work at first glance and that passes compilation doesn't produce the expected output.

      Expected Result

      I would expect that the struct conformance to Decodable would be correctly synthesised and the static property name would be ignored. Failing that I would at least expect the decoding of the instance property to throw an error at runtime if it manages to compile, but this isn't the case.

      The most desirable result would for Decodable synthesis to be correctly applied.

      Workaround

      To circumvent the issue, add in manual support of Decodable.

      required init(decoder: Decoder) throws { ... }
      

        Attachments

          Activity

            People

            • Assignee:
              brentdax Brent Royal-Gordon
              Reporter:
              dlbuckley Dale Buckley
            • Votes:
              1 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: