I have put together a (slightly complicated) protocol hierarchy whose dispatch behavior is still puzzling me so I decided to share it in the hope that someone could explain the rationale behind it.
Here is the code (sorry for the obfuscation and the length, this is the minimal set that still reproduces the issue):
protocol Base: Foo {
var baseProp: Int { get }
}
protocol Foo {
func doFoo()
}
protocol SpecialFoo: Foo {}
extension SpecialFoo where Self : Base, Self : Bar {
func doFoo() {
_ = self.baseProp
self.doBar()
}
}
protocol Bar {
func doBar()
}
protocol Qux {
var quxProp: Int { get }
}
extension Bar where Self : Base, Self : Qux {
func doBar() {
_ = self.baseProp
_ = self.quxProp
print("default impl for Qux")
}
}
extension Bar {
func doBar() {
print("default impl")
}
}
class Generic<T>: Base, SpecialFoo, Bar {
var baseProp: Int { get { return 0 } }
}
class Derived: Generic<Int>, Qux {
var quxProp: Int { get { return 0 } }
}
let d = Derived()
d.doFoo()
If you paste this in a playground, you'll see that it will print "default impl", whereas my expectation was "default impl for Qux". My reasoning was that since "d" is a Derived, when I call doFoo() the SpecialFoo's implementation is hit (so far this is the case), which in turn would call the doBar() implemented in the more specialized extension (given that Derived in fact implements Qux). But it's not what happens, and I can't figure out why.
Could anyone give me some insights?