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
.