Compiler does not pick the most specific method?

I have class with a generic type and a method. I. then create an extension function for this class with the same name but some nested generic types. When I then try to call the extension function, the compiler picks the regular method. Is this a bug, feature request or known? Here is sample code:

class Mono<T>(
    val variable: T
) {
    fun <T2> map(mapper: (T) -> T2): Mono<T2> {
        println("Using original")
        return Mono(mapper(variable))
    }
}

data class SomeWrapper<T>(
    val wrappedVariable: T
)

fun <T1, T2> Mono<SomeWrapper<T1>>.map(mapper: (SomeWrapper<T1>) -> T2): Mono<SomeWrapper<T2>> {
    println("Using extension func")
    return Mono(SomeWrapper(mapper(variable)))
}

fun main() {
    val mono: Mono<SomeWrapper<String>> = Mono(SomeWrapper("Hey!"))
    val mappedValue = mono.map { it.wrappedVariable + "foo" }

    println(mappedValue.variable)
}

In this example, the program prints “Using original”. However, the extension function is more specific and a better matc.

As far as I know member functions have “higher priority” than extensions, if there’s a way to call a member function that will be called.
Note that if that weren’t the case, you’d be able to change the behaviour of some external class by defining some extension that matches the method better, nobody wants that.

If that’s the case(which makes sense), should the extension function generate compile error? Since it won’t ever be used?

You can use it if you import it with a different name (and then call it with that name).

1 Like