AbstractMethodError with covariant val override in a data class

I’m trying to implement a custom map using a custom set for keys, and it throws AbstractMethodError, even though the code compiles fine, which is something that shouldn’t happen I think. The simplest (albeit silly) example I could come up with to demonstrate the issue is this:

data class MySet(val impl: Set<Int>): Set<Int> by impl

sealed class MyMap<T>: Map<Int, T> {

    companion object {
        @JvmStatic fun <T> of(keys: MySet, impl: Map<Int, T>): MyMap<T> =
        	MyMapImpl(keys, impl)
    }

    private data class MyMapImpl<T>(
        override val keys: MySet,
        val impl: Map<Int, T>
    ) : MyMap<T>(), Map<Int, T> by impl
}

fun main() {
    MyMap.of(MySet(setOf(1)), mapOf(1 to 1)).keys
}

Replacing MySet in the override with Set<Int> works just fine, so the covariant override seems to be the culprit here.

1 Like

Hmmmm I think you’ve ran into some corner case here. I tried making MyMapImpl not implement MyMap and that worked, so after a bit of trial-and-error I figured out that it must be because the sealed class also implements Map, and so if you redefine val keys in the sealed class and then override it normally in MyMapImpl then everything works like this:

data class MySet(val impl: Set<Int>): Set<Int> by impl

sealed class MyMap<out T>: Map<Int, T> {
	abstract override val keys: Set<Int>
    companion object {
        @JvmStatic fun <T> of(keys: MySet, impl: Map<Int, T>): MyMap<T> =
        	MyMapImpl(keys, impl)
    }

    private data class MyMapImpl<out T>(
        override val keys: MySet,
        val impl: Map<Int, T>
    ) : MyMap<T>(), Map<Int, T> by impl
}

fun main() {
    println(MyMap.of(MySet(setOf(1)), mapOf(1 to 1)).keys)
}

Thanks, that’s a viable workaround. Yet, is this a bug? If so, should I report it?