mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-05-09 00:21:47 +00:00
Change the treatment of default implementations on interfaces in JVM compatibility mode. Previously, the IR backend moved the actual default implementation to the DefaultImpls class, and then bridged to it from the interface default. The old backend did the reverse, at the cost of an additional accessor, in order to gain better binary compatibility properties. See #2612 for discussion. The accessor needs to call a specific implementation, so must be performed through an `invokespecial`. We trick the SyntheticAccessorLowering into doing this for us, by marking the bridging call as a super call. We do this in want of an explicit `invokespecial` Ir Node. InterfaceDefaultCallsPhase previously assumed the old behaviour of the IR backend (that calls to default implementations, e.g. `foo$default` should target `DefaultImpls.foo$default`). But now the bridge to foo$default resides on `DefaultImpls` already, causing that pass to create a recursive loop. We cut that loop with a simple check.
23 lines
453 B
Kotlin
Vendored
23 lines
453 B
Kotlin
Vendored
// !JVM_DEFAULT_MODE: compatibility
|
|
// JVM_TARGET: 1.8
|
|
|
|
interface KInterface {
|
|
@JvmDefault
|
|
fun test2(): String {
|
|
return "OK"
|
|
}
|
|
}
|
|
|
|
interface KInterface2 : KInterface {
|
|
@JvmDefault
|
|
abstract override fun test2(): String
|
|
}
|
|
|
|
// 1 INVOKESPECIAL KInterface.test2
|
|
// 0 INVOKESPECIAL KInterface2.test2
|
|
|
|
// 1 INVOKESTATIC KInterface.access\$test2\$
|
|
// +
|
|
// 0 INVOKESTATIC KInterface2.access\$test2\$
|
|
// =
|
|
// 1 INVOKESTATIC KInterface |