I have the following class structure:
protocol DoSomething { init()}
class ClassA: DoSomething { required init() {} }
class ClassB: DoSomething { required init() {} }
class ClassC<T:DoSomething> {
var val:T
init() { val = T() }
func doSomething() { print("default called.") }
}
extension ClassC where T:ClassA {
func doSomething() {
print("ClassC[ClassA].doSomething")
}
}
extension ClassC where T:ClassB {
func doSomething() {
print("ClassC[ClassB].doSomething")
}
}Where the extensions provide specialization of ClassC depending on the generic called. The following works:
let a = ClassC<ClassA>()
let b = ClassC<ClassB>()
a.doSomething() // got: "ClassC[ClassA].doSomething" (correct function called)
b.doSomething() // got: "ClassC[ClassB].doSomething" (correct function called)Because `doSomething` is defined as a method in class C, Swift can dynamically dispatch to the correct function defined in the extension. However, If try to define a class that uses `ClassC`, things stop working:
class ClassD<T:DoSomething> {
func apply(val:ClassC<T>) {
val.doSomething()
}
}
let d_a = ClassD<ClassA>()
let d_b = ClassD<ClassB>()
d_a.apply(val: a) // got: "default called." (incorrect function called)
d_b.apply(val: b) // got: "default called." (incorrect function called)Which would seem to indicate that in `apply` the function `doSomething is no longer dynamically dispatched. Is this expected behavior, and will Swift not do a vtable lookup when the call does not originate from a method within the class or is this a bug?
Thanks!