Unable to cast Array to Codable

Given that Array conforms to Codable I assume that an array of Codable i.e [Codable] should definately be castable to a Codable.

I’ve made a simple example with just the Decodable part. And just to verify:

// Attempt to conform Array to Decodable
extension Array : Decodable { }

This causes warning:

Conformance of ‘Array’ to protocol ‘Decodable’ conflicts with that stated in the type’s module ‘Swift’ and will be ignored; there cannot be more than one conformance, even with different conditional bounds

Which makes sense since Array conforms to Decodable already.

// Totally decodable array
var array: [Decodable] = ["Decodable", "strings"]

// Attempt to cast the decodable array
var decodable: Decodable = array

This causes compiler error:

Value of type [Decodable] does not conform to specified type ‘Decodable’

And a FixIt: Insert 'as! Decodable'

Applying FixIt causes runtime error:

Could not cast value of type ‘Swift.Array<Swift.Decodable>’ (0x11f84dd08) to ‘Swift.Decodable’ (0x11f84db18).

I’m using Xcode 10 on macOS 10.14.

So what am I doing wrong here?

I just tried with Xcode 9.2 and the same example works fine. So question becomes why does this no longer work on Xcode 10 and what am I expected to do instead? I can’t find any reference to this change anywhere.

  • Please first tell what you want to do; what JSON do you want do decode?

    – 




  • 1

    @meaning-matters That would in this case be the strings “Decodable” and “strings”. The point isn’t that. I already know what the decoded data will be. You can replace every occurrence of Decodable in the example with Encodable and get the same errors. The point is the code won’t compile. @vadian [Decodable] means Array<Decodable> which means Array where Element is Decodable. The extension was just to demonstrate that Array indeed already conforms to Decodable, a requirement of which as you point out is that its Element generic conforms to Decodable.

    – 




  • Probably a duplicate of stackoverflow.com/questions/33112559/…

    – 

In accordance with the laws of conditional conformance that went into effect in Swift 4.2:

  • An array of some type (class, struct, or enum) that conforms to Decodable is decodable.

  • An array of the protocol Decodable is not, because a protocol does not conform to itself.

(What was happening before Swift 4.2 was that conditional conformance didn’t exist and we were just getting a kind of universal pass; you could treat any array as decodable and you wouldn’t hit a problem until runtime if you were wrong. Now, with conditional conformance, the compiler actually looks at the element type.)

Leave a Comment