You have to handle the null case, because the type of the variable is still nullable outside of the if block. Inside the block is the smart cast from Bar? to Bar effective.
Sure it would work inside the block (as demonstrated by maybeNull.someUnacceptableCondition). But static analysis would tell you that the variable is always assigned a non-nullable type even though it starts out nullable.
I don’t think the compiler is quite as smart as you think it is.
According to the documentation, smart casting for a local nullable variable only works if the variable has not been modified between the nullity check and the point it is used.
In this case the variable is modified after it is checked for nullness and, even though it has been assigned a non-null value, the compiler doesn’t seem to realise this.
Consequently, the variable is still assumed to be nullable outside the ‘if’ statement and you have to deal with it accordingly.
So the compiler is not doing full static analysis? Okay that explains it. Thanks. I do remember reading somewhere that the smart casts are only partially smart. Is there a link to that information?
Which version of Kotlin are you using? I use the latest stable and it tells me the throw is not needed:
If you can’t upgrade, then you can use this:
fun foo() =
// Note: No "?." before "let"
someNullableFun().let { bar ->
if (bar == null) {
Log("some stuff")
Bar("default")
} else {
if (bar.someUnacceptableCondition) {
Log("some other stuff")
throw Exception()
}
bar
}
}
As one of the aims of Kotlin is to compile quickly, I think it’s unlikely that the compiler will ever be able to do a full static analysis of these situations.
Here is the link to what I said in my previous post under the ‘Checking for null in conditions’ section.
However, I made that post without actually trying to compile the code and. following @jstuyts post, I’ve just done that using the current stable version (1.1.3-2) with the same result as he obtained.
So it appears that the compiler has either become smarter since the documentation was written or it doesn’t tell the whole story.