Why does Kotlin compiler let's this trap compile? ...
# stdlib
s
Why does Kotlin compiler let's this trap compile? I introduced an error in production today on my company because of this, I thought the compiler or the IDE would catch something like this, but apparently not.
Copy code
ConcurrentHashMap<Int, String>().getOrPut(1) { null } // compiles just fine, but it'll throw in runtime
mutableMapOf<Int, String>().getOrPut(1) { null } // compiler error: Null can not be a value of a non-null type String
I just found out that other people already had this issue before, long before actually. https://youtrack.jetbrains.com/issue/KT-39382 Why is that not fixed yet? I'm very surprised by that.
b
Because it's java class and java has no null safety guarantees?
s
But
getOrPut
is a Kotlin extension function of
stdlib
, not a method of
ConcurrentMap
interface, so that makes no sense. Here is its signature.
Copy code
public inline fun <K, V> java.util.concurrent.ConcurrentMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V { /* compiled code */ }
p
It's just a bug; sometimes bugs (if niche enough) don't get fixed promptly https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/src/kotlin/collections/MapsJVM.kt#L71 You could look into contributing a fix?
r
What is actually the difference between the signature of those two that would allow the former to compile? Is it the difference in implementation that leads to different compilation determinations?
Copy code
inline fun <K, V> ConcurrentMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V
inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V
https://github.com/JetBrains/kotlin/blob/1e378ed136e19d3c2d0026a8382fe5d2d24404a9/libraries/stdlib/jvm/src/kotlin/collections/MapsJVM.kt#L71 https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/collections/Maps.kt#L356
Nevermind, it seems like
V
from ConcurrentMap implicitly
Any!
whereas it's
Any
for MutableMap.
☝️ 1
I opened a PR to fix this: https://github.com/jetbrains/kotlin/pull/4689. It may be naive and not work for cases where people actually want
Any?
, but I wanted to start the ball rolling.