I'm hitting the wall in Swift 4.1 at this moment. I have a few places where I used dynamic casts (via switch
and as?
) to cast an existential to a protocol which it conforms to but only via a conditional conformance.
Are there known good strategies for that?
Let's have a hypothetical example:
protocol P {}
protocol Q {}
struct Foo : P {}
struct Generic<Value> {}
extension Generic : P where Value : P {}
extension Generic : Q where Value : P {}
func test(_ value: P) {
switch value {
case let q as Q: // this will fail
print("works", q)
default:
print("fails")
}
}
test(Generic<Foo>())
I think I can workaround a few situations by providing an exact overload of the function where I otherwise would have used a dynamic cast, but there are other situations where it's super tedious to workaround because it requires to predict every possible dynamic type instead of the conditional protocol the type conforms to.
By the way, is this a bug? It was a bug in Swift 4.1 but is fixed in Swift 4.2.
func test(_ value: Q) {
switch value {
case let q as Q: // warning: 'as' test is always true
print("works", q)
default:
print("fails")
}
}
test(Generic<Foo>() as Q) // pints "fails"