Heyho, I run into a stack overflow with this one. ...
# server
b
Heyho, I run into a stack overflow with this one. We loop with “Some logic here”. Do you know why?
Copy code
fun main() {
    val a = Baz()
    a.remove("test")
}

class Baz : Bar() {
    override fun remove(key: String): Boolean {
        println("Some logic here")
        return super.remove(key)
    }
}

abstract class Bar : Foo<String>()

abstract class Foo<K> : MutableList<K> {
    override fun remove(key: K) : Boolean {
        println("This is never executed")
        return true
    }

    // other MutableList Impls with TODO()
}
d
Looks like a bug in Kotlin itself.
☝️ 1
BTW, an actual compilable example:
Copy code
fun main() {
    Impl().remove("test")
}

class Impl : Parent() {
    override fun remove(key: String): Boolean {
        println("Some logic here")
        return super.remove(key)
    }
}

abstract class Parent : Grandparent<String>() {
//    override fun remove(key: String): Boolean {
//        return super.remove(key)
//    }
}

abstract class Grandparent<K> : MutableList<K> by mutableListOf() {
    override fun remove(key: K): Boolean {
        println("This is never executed")
        return true
    }
}
If I uncomment those lines in the middle class, it runs fine.
Might be a work around.
Having said that, it's almost never the right thing to implement your own MutableList, you might be making your life more difficult.
This also looks like it specifically a problem with MutableList. If I create a different interface, it also runs fine.
s
I think it's related to the use of generics. Kotlin generates bridging methods for the generic types, and the bug is in those.
d
Hmm, I'm not sure its the use of generics, given that a non MutableList class works fine.
Anyway, @Björn Mayer, hopefully that gives you what you need.
s
I think this is the bad bytecode, in `Bar`:
Copy code
public final bridge remove(Ljava/lang/Object;)Z
   L0
    LINENUMBER 13 L0
    ALOAD 1
    INSTANCEOF java/lang/String
    IFNE L1
    ICONST_0
    IRETURN
   L1
   FRAME SAME
    ALOAD 0
    ALOAD 1
    CHECKCAST java/lang/String
    INVOKEVIRTUAL Bar.remove (Ljava/lang/String;)Z
    IRETURN
    MAXSTACK = 2
    MAXLOCALS = 2
Bar.remove(Object)
is calling
Bar.remove(String)
, which is the one that's actually overridden 😬. It should probably just be calling
Foo.remove(Object)
instead.
Anyway there's nothing that can be done about it other than raising a ticket, or as @Daniel Pitts suggested, just not trying to implement
MutableList
😄
b
This example is more simple than the real world. There we have a store, implementing MutableMap by delegation
d
Yeah, you will need to use that work around.
b
Will do. I reported it here: https://youtrack.jetbrains.com/issue/KT-64458/Super-invokes-itself-leading-to-Stackoverflow-Error Thank you folks, for looking into it
🐕 1
👍 1