I'm a bit confused why the following doesn't compile:
import UIKit
import Foundation
protocol Foo {}
protocol Bar {}
class Test: UIViewController & Foo & Bar {}
protocol Qux {
var test: UIViewController & Foo & Bar { get }
}
class Zag: Qux { // compiler error! Protocol requires property `test`
// with type `UIViewController & Bar & Foo`
var test: Test // Candidate has non-matching type `Test`
init(test: Test) {
self.test = test
}
}
Meanwhile the compiler is perfectly happy if we do this:
class Zag: Qux {
var test: Test
init(test: Test) {
self.test = test
}
}
func doSomething(with thing: UIViewController & Foo & Bar) {
print("something")
}
let mytest = Test()
let zag = Zag(test: mytest)
doSomething(with: zag.test)
It does not seem that class Zag
can conform to Qux
on the basis of test: Test
even though below we see that class Test
meets all the requirements: UIViewController & Foo & Bar
.
Meanwhile in the case of func do(with:)
, it seems that covariance holds for an instance of Test
being used as a UIViewController & Foo & Bar
, without explicit casting or generics.
Just curious what the rationale for this might be, or if this is an area in which Swift is planned to have future support but currently it doesn't. Thanks
PS—I'd note that, counterintuitively, the following does compile:
class Zag: Qux {
var test: Test
init(test: Test) {
self.test = test
}
}
extension Qux where Self: Zag {
var test: UIViewController & Foo & Bar {
self.test as UIViewController & Foo & Bar
}
}
This makes me think that there was probably a decision made to not auto-synthesize this kind of extension for covariance, so I'm curious the reasons.