Am I not understanding type inference correctly?

Here is some example code relevant to my problem (I am creating a DSL for an RPG)

class Thing<T>(private val things: List<T>) {
    fun getThing(): T = things.random()
}

class ThingBuilder<T> {
    private val things: MutableList<T> = mutableListOf()
    fun add(thing: T) = things.add(thing)
    fun build(): Thing<T> = Thing(things.toList())
}

fun <T> buildThing(bldr: ThingBuilder<T>.() -> Unit) = ThingBuilder<T>().apply(bldr).build()

However when I

val thing = buildThing { // this: ThingBuilder<???>
    add(1)
}

I am expecting the ThingBuilder lambda to be inferred as ThingBuilder<Int>, as I use an Int in the add function, and to me that would logically lead to the ThingBuilder using Int as T, thus causing buildThing to use Int for T because ThingBuilder<T> is ThingBuilder<Int>

I can explicitly type thing and it would work fine, though that kind of defeats the purpose of type inference, right?

If I remember corectly this used to be possible by using an internal annotation of the standard library.

Now you can enable this by using the BuilderInference annotation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-builder-inference/index.html
You need to enable the new type inference for it to work.

1 Like