0
votes

These all compile fine:

fun f1(): Array<Any> {
    return arrayOf(1)
}

fun f2(): Collection<Any> {
    return listOf(1)
}

fun f3(): Collection<Collection<Any>> {
    return listOf(listOf(1))
}

But this one gives the error below:

fun f4(): Array<Array<Any>> {
    return arrayOf(arrayOf(1)) // compilation error here
}

Error:(22, 16) Kotlin: Type inference failed. Expected type mismatch: inferred type is Array<Array<Int>> but Array<Array<Any>> was expected

Why?

2

2 Answers

3
votes

In your f4() you're using invariance:

Array<Array<Any>>

Array<Any> and Array<Int> are different types, and are not interchangeable.

If you only return the type, you can use covariance:

fun f4(): Array<Array<out Any>> {
   return arrayOf(arrayOf(1)) // works
}

Since Int is subtype of Any

1
votes

arrayOf signature:

inline fun <reified T> arrayOf(vararg elements: T): Array<T> (source)

It works on methods that directly return the array because type is inferred from return type. But it cannot do "nested" inference as you imagine.

This becomes much clearer if you break down your return statement:

val arr = arrayOf(1)  // this is an Array<Int> of course
return arrayOf(arr)

Now there is no reason why arr assignment would be marked as an error would it?

So if you don't want to infer Int, you have to provide returned type of nested array yourself:

return arrayOf(arrayOf<Any>(1))