Fun with invoke operator


#1

trying to develop a DSL I stumbled over the following seeming bug(s):

interface A {
    fun foo() {
        println("foooo")
    }
}

interface B : A {
    fun hoo() {
        println("hoooo")
    }
}

fun<T:A> doer(init:()->T) : T = init()

class Z {
    operator fun<T:A> invoke(init:Z.()->T) : T = init()
    infix fun<T:A> doer(init:Z.()->T) : T = init()

}

interface  ARoot<T> {
    val self : T
    infix fun<U:A> consume(init: T.() -> U) : U = self.init()
    operator fun<U:A> invoke(init:T.()->U) : U = self.init()
}

class Y : ARoot<Y> {
    override val self: Y
        get() = this
}

calling the following works:

    doer {
        object : B {}
    }.hoo()
    val z = Z()
    val y = Y()
    z.doer { object : B {} }.hoo()

but

    y.consume {
        z {
            object : B {}
        }
    }.hoo()

and

y {
    z {
        object : B {}
    }
}.hoo()

fails with:

Error:(49, 7) Kotlin: [Internal Error] org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Error type encountered: [ERROR : Unsubstituted type for ] (ErrorTypeImpl).
Cause: Error type encountered: [ERROR : Unsubstituted type for ] (ErrorTypeImpl).

same error occurs for:

z {
    object : B {}
}.foo()

z {
    object : B {}
}.hoo()

Am I doing something wrong or is this a bug?


#2

It’s a bug indeed (the compiler should not be throwing internal errors), please report it to the issue tracker.


#3

done https://youtrack.jetbrains.com/issue/KT-10822