Properly check default kind on inheriting from old DefaultImpls scheme

This commit is contained in:
Mikhael Bogdanov
2020-10-06 13:10:50 +02:00
parent 714d17ac63
commit 5048471835
9 changed files with 67 additions and 6 deletions
@@ -1679,7 +1679,8 @@ public class FunctionCodegen {
assert isInterface(containingDeclaration) : "'processInterfaceMethod' method should be called only for interfaces, but: " +
containingDeclaration;
if (JvmAnnotationUtilKt.isCompiledToJvmDefault(memberDescriptor, mode)) {
// Fake overrides in interfaces should be expanded to implementation to make proper default check
if (JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(memberDescriptor, mode)) {
return (kind != OwnerKind.DEFAULT_IMPLS && !isSynthetic) ||
(kind == OwnerKind.DEFAULT_IMPLS &&
(isSynthetic || //TODO: move synthetic method generation into interface
@@ -563,6 +563,11 @@ public class FirCompileKotlinAgainstKotlinTestGenerated extends AbstractFirCompi
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes2Compatibility.kt");
}
@TestMetadata("newAndOldSchemes3.kt")
public void testNewAndOldSchemes3() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes3.kt");
}
@TestMetadata("newSchemeWithJvmDefault.kt")
public void testNewSchemeWithJvmDefault() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newSchemeWithJvmDefault.kt");
@@ -61,7 +61,7 @@ fun CallableMemberDescriptor.isCompiledToJvmDefault(jvmDefault: JvmDefaultMode):
return JvmProtoBufUtil.isNewPlaceForBodyGeneration(clazz.classProto)
}
fun FunctionDescriptor.checkIsImplementationCompiledToJvmDefault(jvmDefaultMode: JvmDefaultMode): Boolean {
fun CallableMemberDescriptor.checkIsImplementationCompiledToJvmDefault(jvmDefaultMode: JvmDefaultMode): Boolean {
val actualImplementation =
(if (kind.isReal) this else findImplementationFromInterface(this))
?: error("Can't find actual implementation for $this")
@@ -16,16 +16,21 @@ interface KInterface2 : KInterface {
override fun superCall() = super.superCall()
}
class Foo: KInterface2 {
fun superCall2() = super<KInterface2>.superCall()
interface KInterface3 : KInterface2 {
}
class Foo: KInterface3 {
fun superCall2() = super<KInterface3>.superCall()
}
fun box(): String {
var result = Foo().call()
if (result[1] != "KInterface\$DefaultImpls.call") return "fail 1: ${result[1]}"
if (result[2] != "KInterface2\$DefaultImpls.call") return "fail 2: ${result[2]}"
if (result[3] != "Foo.call") return "fail 3: ${result[3]}"
if (result[4] != "MainKt.box") return "fail 4: ${result[4]}"
if (result[3] != "KInterface3\$DefaultImpls.call") return "fail 3: ${result[3]}"
if (result[4] != "Foo.call") return "fail 4: ${result[4]}"
if (result[5] != "MainKt.box") return "fail 5: ${result[5]}"
result = Foo().superCall2()
if (result[1] != "KInterface\$DefaultImpls.superCall") return "fail 1: ${result[1]}"
@@ -0,0 +1,30 @@
// IGNORE_BACKEND_FIR: JVM_IR
// FULL_JDK
// FILE: 1.kt
// !JVM_DEFAULT_MODE: disable
interface KInterface {
fun call(): List<String> {
return Thread.currentThread().getStackTrace().map { it.className + "." + it.methodName }
}
}
// FILE: main.kt
// !JVM_DEFAULT_MODE: all
// JVM_TARGET: 1.8
interface KInterface2 : KInterface {
}
class Foo: KInterface2 {
}
fun box(): String {
var result = Foo().call()
if (result[1] != "KInterface\$DefaultImpls.call") return "fail 1: ${result[1]}"
if (result[2] != "KInterface2\$DefaultImpls.call") return "fail 2: ${result[2]}"
if (result[3] != "Foo.call") return "fail 3: ${result[3]}"
if (result[4] != "MainKt.box") return "fail 4: ${result[4]}"
return "OK"
}
@@ -568,6 +568,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes2Compatibility.kt");
}
@TestMetadata("newAndOldSchemes3.kt")
public void testNewAndOldSchemes3() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes3.kt");
}
@TestMetadata("newSchemeWithJvmDefault.kt")
public void testNewSchemeWithJvmDefault() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newSchemeWithJvmDefault.kt");
@@ -563,6 +563,11 @@ public class IrCompileKotlinAgainstKotlinTestGenerated extends AbstractIrCompile
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes2Compatibility.kt");
}
@TestMetadata("newAndOldSchemes3.kt")
public void testNewAndOldSchemes3() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes3.kt");
}
@TestMetadata("newSchemeWithJvmDefault.kt")
public void testNewSchemeWithJvmDefault() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newSchemeWithJvmDefault.kt");
@@ -563,6 +563,11 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes2Compatibility.kt");
}
@TestMetadata("newAndOldSchemes3.kt")
public void testNewAndOldSchemes3() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes3.kt");
}
@TestMetadata("newSchemeWithJvmDefault.kt")
public void testNewSchemeWithJvmDefault() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newSchemeWithJvmDefault.kt");
@@ -563,6 +563,11 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes2Compatibility.kt");
}
@TestMetadata("newAndOldSchemes3.kt")
public void testNewAndOldSchemes3() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newAndOldSchemes3.kt");
}
@TestMetadata("newSchemeWithJvmDefault.kt")
public void testNewSchemeWithJvmDefault() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvm8/defaults/interop/newSchemeWithJvmDefault.kt");