arraysswiftcodableswift4.2

Unable to cast Array<Codable> 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.


Solution

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

    (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.)