Synthetic Codable fails with protocol typed property

Hi,

I have the following code example. In my real case the protocol P has additional properties that I want to enforce to protocols A and B, but this does not make a difference to explain the issue I have.

protocol P : Codable { }
  
protocol A : P {
   var prop : B? { get }
}
  
protocol B : P {
   var prop : String? { get }
}
  
class BB : B {
   var prop: String? = nil
}
  
class AA : A {
   var prop: B? = nil
}

Compiling it results in errors:

Error:(, ) type 'AA' does not conform to protocol 'Decodable'
Error:(, ) type 'AA' does not conform to protocol 'Encodable'

I was expecting the hierarchy of protocols and classes here to all support codable, as protocol P is Codable, and protocols A and B both inherits from protocol P. And as a result, I expected the compiler to synthesize the requirements for the Codable typealias for classes AA and BB.
If I change the protocol A definition to require a property of type String instead of B? then it works.
I know that the codable synthesis requires all the properties of the class to be codable, but I can't help but think that they all are...

Why does the compiler not synthesize in my example? Why is it unreasonable to expect it to?

Think about decoding an instance of AA. How would you decode prop if you only know it conforms to B? You need a concrete type to instantiate it.

(It helps me to use a concrete example, let’s say the prop conforms to some Animal protocol with concrete Cat and Dog structs conforming to it. When you want to decode it, you need a particular animal to instantiate. Is it a cat, or a dog? How would the compiler know?)

1 Like

Yeah, I get it, now that you point my attention to the issue of decoding.... From the information there the compiler would not have a init available for creating Bs.

I was so focused on encoding that I wouldn't see it. But of course, codable is about both encode and decode :slight_smile:

Thanks for pointing it out. Cheers!

1 Like