Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin generics fail when deduced from lambda argument

Today I encountered strange behavior while creating some Kotlin generics. Code below illustrates the problem.

MCVE

class Generic<T>(private val initial: T? = null, private val source: (T)->Unit) {
    fun test(value: T) = source(value)
}

fun <T> createGeneric(initial: T? = null, source: (T)->Unit) = Generic(initial, source)

fun test() {
    val generic = createGeneric(null) { arg: Int -> println(arg) }
    generic.test(42) 
}

The line generic.test(42) produces error:

The integral literal does not conform to the expected type Nothing

Question: How can T be deduced as Nothing, since I pass { arg: Int -> println(arg) } lambda, which is (Int)->Unit?. I double-checked type of variable generic, and it's deduced as Generic<Nothing>.

Also, if the type is deduced as Nothing, why it allows to pass lambda of type (Int)->Unit as second argument?

Kotlin Playground Example

like image 532
xinaiz Avatar asked Apr 09 '26 15:04

xinaiz


1 Answers

Because functions are contravariant in their argument, (Int) -> Unit is a subtype of (Nothing) -> Unit. So both arguments are acceptable for T=Nothing and that's what gets inferred.

Yes, they are also both acceptable for T=Int, but Kotlin chooses the more specific type.

like image 178
Alexey Romanov Avatar answered Apr 12 '26 10:04

Alexey Romanov



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!