1

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.

pkamb
  • 33,281
  • 23
  • 160
  • 191
user614273
  • 74
  • 10
  • Please first tell what you want to do; what JSON do you want do decode? – meaning-matters Oct 21 '18 at 20:13
  • 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` 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`. – user614273 Oct 21 '18 at 20:42
  • Probably a duplicate of https://stackoverflow.com/questions/33112559/protocol-doesnt-conform-to-itself – matt Oct 21 '18 at 23:04

1 Answers1

2

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

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Nice to have some clarity, I accepted your answer. Now since this worked fine in previous versions (and I mean the code didn't just compile, it worked in runtime), there should be some simple solution to get to the same behaviour? – user614273 Oct 21 '18 at 23:23
  • I'll add a little explanation of that to my answer. – matt Oct 21 '18 at 23:34