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