Search code examples
kotlininterfacecastingtype-inferencetype-deduction

Type deduction fails for array of enum interface


In the following minimal example useFoos(a) is totally fine, but useFoos(b) gives a compiler error.

interface FooInterface

fun useFoos(foos: Array<FooInterface>) {}

enum class FooEnum : FooInterface

fun main() {
    val a = FooEnum.values()
    useFoos(a as Array<FooInterface>)
    useFoos(a)

    val b = FooEnum.values()
    useFoos(b) // Error: Type mismatch: inferred type is Array<FooEnum> but Array<FooInterface> was expected
    useFoos(b as Array<FooInterface>)
}

And idea why this is? And if it's not a compiler bug, but intended behavior instead, could somebody point me to the place where this behavior is specified/explained?


Solution

  • As explained by @IR42 in a comment, it's because of smart casts.

    Using the out keyword helps to make it work without casting.

    Corrected code:

    interface FooInterface
    
    fun useFoos(foos: Array<out FooInterface>) {}
    
    enum class FooEnum : FooInterface
    
    fun main() {
        val a = FooEnum.values()
        useFoos(a as Array<FooInterface>)
        useFoos(a)
    
        val b = FooEnum.values()
        useFoos(b)
        useFoos(b as Array<FooInterface>)
    }