Ambiguous overload resolution, when invoke extension function with overload and generic

class A<T> {
    fun <T> test2(p2: T) {}

    fun <T> test2(p2: () -> T) {}
}

fun <T> A<T>.test3(p2: T) {}
fun <T> A<T>.test3(p2: () -> T) {}

fun <T> test1(p2: T) {}
fun <T> test1(p2: () -> T) {}

fun main() {
    val a = A<Int>()
    a.test2 { 2 }
    test1 { 2 }
    a.test3 { 2 } //Overload resolution ambiguity. All these functions match.

}

Why does IntelliJ IDEA suggest "Overload resolution ambiguity. " at the call site of test3? Examining the decompiled Java code, test3 doesn’t appear to have any notable distinctions from the other two methods, except for an extra receiver parameter.

I hesitate to say this, because I know someone’s gonna come in here and prove me wrong. :stuck_out_tongue: But it kind of feels like a compiler bug? I can understand the ambiguity of test3, because T could be () -> Any, at which point, are you calling test3(p2: T) or test3(p2: () -> T)? It could be either, and the compiler might not know which one you want to call. That said, because val a should have the type of A<Int>, I feel like the compiler should understand that you’re calling test3(p2: () -> T), since test3(p2: T) can’t be right, as we know T is an Int and not () → Int.

1 Like