Dynamic dispatch with generics

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!

I've run into the same problem. Did you ever resolve whether this is intended behaviour? Did you find any way around it (other than a complete redesign). Thanks!

Edit: I found your post at <https://stackoverflow.com/q/41980001/668253> which provides good insights. Thanks for that.

It is, in effect, the currently intended behavior. That is, the Swift team is aware of the objection to this behavior, but I don't think there's any plan to fix it any time soon.


Part of the problem is an implementation question, part of the problem is that it's not really clear how inheritance and protocols should interact. My bug report about this (marked as a duplicate of #21141185) is still open after 2 years and 5 months.

Dynamic dispatch with generics
 
 
Q