alllex
04/13/2021, 7:56 PMclass Holder<out T>(val make: () -> T)
fun <T> Holder<T>.test(value: T) = check(value == make())
fun main() {
val h: Holder<Int> = Holder { 10 }
h.test("what?") // intuitively, should not compile
}
I would expect that this code does not type-check, because I am trying to compare Int and String.
However, in the call to test , T is inferred to Any. Which actually allows you to pass any argument whatsoever, and it will compile.
The problem is that Holder class is a library class, that I cannot modify. However, the test function I can modify, but without changing its signature.
Is there a way to make the test function check that T is actually the same at the call-site without explicit typing? (h.test<Int>("what?"))
P.S. Removing out modifier from the Holder signature solves the problem, but unfortunately, the Holder class comes from a dependency.mkrussel
04/13/2021, 8:02 PMout is there, `Holder<int> isa `Holder<Any>`Since Holder<Any> contains an extension function that can take a String everything works.
This shouldn't cause any problems. Since T can only be used as an out anything that test does with the T will be limited to Any? so the type inference choice should not cause any runtime problems.
It might be nice for this to be broken, but I think this behavior is what is desired most of the time.alllex
04/13/2021, 8:16 PMHolder<Any>.
I guess not much harm is done, because as soon as you try to use the type inferred to Any, you start getting compile-time errors. E.g. if test would return value .