Search code examples
kotlingenericsoverload-resolution

kotlin overload resolution ambiguity when generic type is bound to Any


Consider this code:

fun main() {
    class A<T> {
        fun m(t: T): Unit {
            print("T")
        }
        fun m(t: List<T>): Unit {
            print("List<T>")
        }
    }
    
    val a: A<Any> = A()
    val l: List<Any> = listOf()
    a.m(l)
}

The a.m(l) call seems to be ambiguous with the following error:

Overload resolution ambiguity: public final fun m(t: Any): Unit defined in main.A public final fun m(t: List<Any>): Unit defined in main.A

My intuition tells me that the m(t: List<T>) overload should be more specific, but my intuition was already wrong once in the past, when I had a similar case in Java.

I can call the "wrong" overload like this:

a.m(l as Any)

But how can I explicitly call the desired m(t: List<T>) overload? Casting a.m(l as List<Any>) doesn't work.


Solution

  • An auxiliary function can help:

    fun <T> A<T>.mList(l: List<T>) {
        this.m(l);
    }
    a.mList(l)
    

    Still curious about an alternative that doesn't involve any indirection like this