[Pitch] JSONDecoder.nullDecodingStrategy

Yes, for the same reason above: compiler synthesis only generates decodeIfPresent() calls for Optional. We've, er, had this discussion before, on more than one occasion :sweat_smile:


Although this works, it's very important to understand why and how it works, and take into account that this is a very fragile solution that is hard to recommend.

An extension to KeyedDecodingContainer only works because:

  1. Codable compiler synthesis currently manipulates the AST directly, generating code as-if you had written the source code yourself; because of this, actual resolution of method overloads allows type checking to select more specific overloads for specific calls (e.g., those found in extensions)
  2. An extension in your module makes that overload available for the compiler to select within your module (and modules you make it visible to)

It's really important to keep in mind that this does not actually change the behavior of KeyedDecodingContainer at all, just that it monkey-patches a new overload of the method with the same name that makes it visible at synthesis time. This means that:

  1. Modules which don't have this extension at compile-time will silently behave differently from ones that do. This can happen when, e.g.,
    • Module A declares an internal extension, and Module B encodes and decodes the same type
    • Module A declares a public extension, but Module B is compiled before it and encodes and decodes the same type
  2. You can accidentally and silently end up in situation (1) by moving types/extensions between sibling modules
  3. You can't override behavior for modules you don't control
  4. If other modules also define a similar extension, their version will win out over yours when they compile
  5. If compiler synthesis changes (e.g., it starts performing Codable method lookup only in the stdlib), this is liable to silently break
1 Like