poohbar
12/09/2019, 6:17 PMfun main() {
var value: Any? = "hello"
if (value != null) {
for (i in 1..10) {
value = nonNullFoo(value) // smart casting fails
}
}
}
fun nonNullFoo(obj: Any): Any {
return "World"
}
LeoColman
12/09/2019, 6:18 PMvalue
might have been changed and the compiler can't guarantee it wasn't!!
poohbar
12/09/2019, 6:19 PMvalue
is only every assigned the result of nonNullFoo
which is Any
LeoColman
12/09/2019, 6:19 PMthe compiler just can't see that farI believe that's exactly it
value
inside the for, I thinkpoohbar
12/09/2019, 6:20 PMnikolaymetchev
12/09/2019, 6:22 PMvalue?.let {...}
LeoColman
12/09/2019, 6:23 PMlet
will mask the fact that value
can never be null. It will give the obvious possibility that it is null sometimeshallvard
12/09/2019, 7:16 PMvalue
is being changed by another thread somewhere else in the code? Or even from some included dependency library? Contracts is the way to solve this.poohbar
12/09/2019, 7:21 PMvalue
be changed by another thread when it's a local variable?LeoColman
12/09/2019, 7:21 PMhallvard
12/09/2019, 7:38 PMvalue
... I decompiled the code to take a look at the generated bytecode, and am now just as stumped as you are. My only explanation for this is that the compiler must be as blind as I was, and/or didn't dare insert a Contract
all by itself.Any
, not Any?
. So it's the nonNullFoo function that should have had the red underlining, in my opinion ...tseisel
12/10/2019, 2:11 PMvar
properties, what version of Kotlin are you using ?