I’m aware of many workarounds to this, like using different arg names, but I’m wondering if this is a BUG or not. If not, may I ask why it’s designed like this?
code here for easier copy and experiment:
class Instance<in K,in V:Number>{
fun method(arg:K)=Unit
fun method(arg:V)=Unit
}
fun main(args:Array<String>){
Instance<Any,Int>().method(1 as Number)
Instance<Any,Int>().method(1)
}
I don’t think different arg names would help
Interesting problem. Even more interesting is that if you remove the second call to method you can see that Instance<Any, Int>().method(1 as Number) calls the method taking Any as an argument.
Yes I think this is a bug. I guess both parts of it. I would think that you should be able to call the method just passing an int and I would definitely expect it to call the version taking a Number as an argument.
That is because of the way that JVM generics work using type erasure. Generic type checking is all at compile time and any generic variable or parameter at runtime is just Object (in Java) or Any in Kotlin. So both generated methods would both have the same type of parameter. Even if you did not have this limitation what do you expect the compiler to do for an Instance<Number, Number>?
Actually I don’t think this is the case, type erasure, if I remember it correctly, erases to the upper bound. So there are two different methods, one method(Any) and one method(Number). And Instance<Number,Number> is just a Instance<Any,Number> at runtime. At compile-time, I think Kotlin should be able to distinguish them.
If more people think this is a BUG, I’ll file an issue