Understanding Codable/Decodable initialization

Hello,

I'm trying to get an understanding of how Decodable works. The definition of the protocol is:

@_implicitly_synthesizes_nested_requirement("CodingKeys")
public protocol Decodable {
   init(from decoder: Decoder) throws
}

The two things I'm not sure I understand are:

  1. Where is the default implementation of the init? I see it implemented on a bunch of types, but I haven't been able to find a default implementation. IE, if I create a new type that implements Decodable and don't overwrite the init, what gets called? How does that work?

  2. I see that _implicitly_synthesizes_nested_requirement comes from C code, but I don't see a definition of what it does. (I am trying to understand how default coding keys work as well).

Thanks!

Surprisingly, the initializer doesn't have a default implementation, each type that conforms to Decodable must provide its own init(from decoder: Decoder). However, it sometimes looks like there's a default implementation because many types don't explicitly write their own. Instead, they're using a "synthesized conformance", which just means that because the compiler has special built-in knowledge of Decodable, it can generate the implementation automatically in some cases. Synthesizing the init happens entirely within the compiler implementation, which is why it can't be found in the standard library.

Default CodingKeys use a similar mechanism, where the compiler can sometimes insert a synthesized CodingKeys type. @_implicitly_synthesizes_nested_requirement("CodingKeys") is an attribute that identifies Decodable to the compiler as a protocol that is eligible for this synthesis.

It doesn't describe much of the implementation itself, but if you're interested in a high level overview of how Codable requirements are synthesized, the original proposal is a helpful resource.

Essentially, it's all compiler magic. When it can, the compiler synthesizes init() and CodingKeys for a type. Only when it fails will the compiler complain that one or the other is missing.

To add to the existing answers, for some in-depth information on synthesis, please see How does automatic Codable compliance work? For the sake of extending it - #3 by itaiferber (with some additional info in Inheriting from a Codable class) [among some of my other past posts]. There are also direct links to the implementation that you can skim through, if you're comfortable with C++.

Awesome. Thanks so much, this is a big help.