Type projection: inherently broken?


Here’s an excerpt from the reference:

fun copy(from: Array<out Any>, to: Array<Any>) {
 // ...

What has happened here is called type projection: we said that from is not simply an array, but a restricted (projected) one: we can only call those methods that return the type parameter T, in this case it means that we can only call get().

But if I slightly modify the example:

fun copy(from: MutableList<out Any>, to: MutableList<Any>) {
    // ...

then I’m able to execute both these statements in its body:

to.addAll(from) // ok
from.addAll(to) // SHOULD BE PROHIBITED!

Why Kotlin allowed me to do this?
Now some “funny” things become possible:

val from: ArrayList<String> = arrayListOf("a", "b", "c")
val to: ArrayList<Any> = arrayListOf(1, 2, 3)
copy(from, to)
println(from) // [a, b, c, 1, 2, 3] <--- only strings are supposed to be here!


Hi, we’re aware of this problem with type projections and have already fixed it in master (1.0.0-beta-5160).
Thanks for drawing our attention.