(Resolved) Creating a generic extension is behavin...
# compiler
a
(Resolved) Creating a generic extension is behaving weirdly. I have a boolean list and its allowing me to add a integer, no compilation issue (line 15). What am I missing here? Kotlin playground link: https://pl.kotl.in/eSKHXxqzq
y
List is declared with
<out T>
, and so the add call upcasts
List<Boolean>
to
List<Any>
and hence allows the addition. Solution here is kinda complex. Either you just use
MutableList
, or you can rely on an internal compiler annotation like so (playground):
Copy code
fun main() {
    val list: List<Boolean> = mutableListOf(false)
    list.add(1) // Compiler error: The integer literal does not conform to the expected type Boolean
    println(list)
}

// NoInfer prevents the type of [item] from affecting the inferred type of T
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
fun <T> List<T>.add(item: @kotlin.internal.NoInfer T) {
    if(this is MutableList) {
        add(item)
    } else {
        error("Not a mutable list.")
    }
}
You can also define the NoInfer annotation in your own project so that there's no need for the suppression
a
Thanks @Youssef Shoaib [MOD] for the clarification, this was very helpful.
LMK if this should be removed, as this doesn't really concern about compiler.
y
Hmm, type inference is part of the compiler frontend, so I think it fits? I don't know if there's anywhere else it'd fit. It seems like, scrolling up, that people do ask questions here related to resolution and inference, so this question seems to be on topic.
o
You are basically cheating to the compiler. A list is a list and can contain any object, technically. Generics are always gone after compilation. And because your generic fun accepts any type T and then just assures it's seeing a MutableList, it happily adds an object of type Any to it.