Swift generics and overloading issue

I'm working on implementing a set of protocols and a helper class for Visitor pattern in Swift. Unfortunatelly, instead of finishing that and publishing that code I ran into a compiler issue (I think) that prevents any kind of elegant automation of double-dispatching. I have submitted the issue to Apple (issue #17297399)

Here's the full code example that illustrates the problem:

class Base {}
class Derived : Base {}

class Dispatcher {

    func dispatch<T: Base>(t: T) {
        accept(t)
    }

    func accept(t: Base) {
        println("accept(Base)")
    }
    func accept(t: Derived) {
        println("accept(Derived)")
    }

}

var base = Base()
var derived = Derived()
var dispatcher = Dispatcher()
dispatcher.dispatch(base)
dispatcher.dispatch(derived)

According to me this should print out:

accept(Base)
accept(Derived)

Yet it prints out:

accept(Base)
accept(Base)

So why do I believe that the compiler should recognized t to be Derived in the 2nd invocation of dispatch? I believe this because dispatch is a generic function that doesn't accept Base instances but instances of Base and fully typed instances of types derived from Base. So this should be resolved during compile time at which time compiler knows that the 2nd invocation of dispatch is not dispatch(Base) but dispatch(Derived). And if dispatch(Derived) is being invoked then overloading should resolve accept to accept(Derived).

To illustrate this further, imagine if I wrote dispatch like this:

func dispatch(t: Base) {
    accept(t)
}

In that case I'm explicitly stating that I don't care about the actual type of t and that I want to treat it as if it was Base. This is classical OOP - treat derived classes as their superclass, let inheritance mechanism perform the differentiation if any.

But what I was trying to do instead is something else: I was trying to preserve the type information through the use of generics and perform the differentiation through overloading.

UPDATE 2014-06-18: This is still an issue in Xcode 6 Beta 2.

Author

Ivan Erceg

Software shipper, successful technical co-founder, $1M Salesforce Hackathon 2014 winner