Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension method, when called on a null object, is called on the wrong type

fun main() {
    val set: Set<Int>?
    set = null
    val emptySet: Set<Int> = set.orEmpty()
}

Can't figure out why even when explicitly typing the set variable as Set <Int>? the compiler considers that in the extension method set.orEmpty () set - is a string and, accordingly, crashes with an error:

Kotlin: Type mismatch: inferred type is String but Set was expected

But when declaring and initializing in one line, everything happens correctly:

fun main() {
    val set: Set<Int>? = null
    val emptySet: Set<Int> = set.orEmpty()
}
like image 490
JluoH Avatar asked Jun 01 '26 04:06

JluoH


1 Answers

The behavior you're observing can be explained by the interaction of two Kotlin features:

  • first, the type of set variable is narrowed to Nothing? as a result of a smart cast after the assignment of null value to it. The smart cast after an assignment can be useful in cases when it narrows variable type to a more specific type, but narrowing to Nothing? does more harm than good.
  • second, among all overloads of orEmpty function available for a value of type Nothing?, the non-generic one String?.orEmpty() is chosen due to the specific rule of Kotlin overload resolution: a non-generic candidate is preferred to generic ones.

This behavior indeed can be puzzling, so I've reported this problem as KT-50661.

like image 96
Ilya Avatar answered Jun 02 '26 19:06

Ilya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!