From c71e87068a97894763bf0e15b0434a3fce0c2e78 Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Tue, 11 Feb 2020 17:57:06 +0300 Subject: [PATCH] JVM_IR: in InheritedDefaultMethodsOnClassesLowering, skip bridges when resolving overrides --- ...nheritedDefaultMethodsOnClassesLowering.kt | 13 +++++++++++-- .../org/jetbrains/kotlin/ir/util/IrUtils.kt | 10 +++++----- .../codegen/box/traits/doubleDiamond.kt | 19 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 +++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../ir/FirBlackBoxCodegenTestGenerated.java | 5 +++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 +++++ .../IrJsCodegenBoxTestGenerated.java | 5 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++++ 9 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/codegen/box/traits/doubleDiamond.kt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt index 5e9c8f4d85d..eee457e70ab 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.ir.createDelegatingCallWithPlaceholderTypeArguments import org.jetbrains.kotlin.backend.jvm.ir.createPlaceholderAnyNType @@ -219,15 +220,23 @@ private class InterfaceObjectCallsLowering(val context: JvmBackendContext) : IrE * interface implementation should be generated into the class containing the fake override; or null if the given function is not a fake * override of any interface implementation or such method was already generated into the superclass or is a method from Any. */ +private fun isDefaultImplsBridge(f: IrSimpleFunction) = + f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE || + f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC + internal fun IrSimpleFunction.findInterfaceImplementation(): IrSimpleFunction? { if (!isFakeOverride) return null parent.let { if (it is IrClass && it.isJvmInterface) return null } - val implementation = resolveFakeOverride() ?: return null + val implementation = resolveFakeOverride(toSkip = ::isDefaultImplsBridge) ?: return null // Only generate interface delegation for functions immediately inherited from an interface. // (Otherwise, delegation will be present in the parent class) - if (overriddenSymbols.any { !it.owner.parentAsClass.isInterface && it.owner.modality != Modality.ABSTRACT && it.owner.resolveFakeOverride() == implementation }) { + if (overriddenSymbols.any { + !it.owner.parentAsClass.isInterface && + it.owner.modality != Modality.ABSTRACT && + it.owner.resolveFakeOverride(toSkip = ::isDefaultImplsBridge) == implementation + }) { return null } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt index 7f17f59b825..abf4b22e0d9 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt @@ -260,8 +260,8 @@ fun IrClass.isSubclassOf(ancestor: IrClass): Boolean { return this.hasAncestorInSuperTypes() } -fun IrSimpleFunction.collectRealOverrides(): Set { - if (isReal) return setOf(this) +fun IrSimpleFunction.collectRealOverrides(toSkip: (IrSimpleFunction) -> Boolean = { false }): Set { + if (isReal && !toSkip(this)) return setOf(this) val visited = mutableSetOf() val realOverrides = mutableSetOf() @@ -269,7 +269,7 @@ fun IrSimpleFunction.collectRealOverrides(): Set { fun collectRealOverrides(func: IrSimpleFunction) { if (!visited.add(func)) return - if (func.isReal) { + if (func.isReal && !toSkip(func)) { realOverrides += func } else { func.overriddenSymbols.forEach { collectRealOverrides(it.owner) } @@ -295,8 +295,8 @@ fun IrSimpleFunction.collectRealOverrides(): Set { // This implementation is from kotlin-native // TODO: use this implementation instead of any other -fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction? { - return collectRealOverrides().singleOrNull { it.modality != Modality.ABSTRACT } +fun IrSimpleFunction.resolveFakeOverride(toSkip: (IrSimpleFunction) -> Boolean = { false }): IrSimpleFunction? { + return collectRealOverrides(toSkip).singleOrNull { it.modality != Modality.ABSTRACT } } fun IrSimpleFunction.isOrOverridesSynthesized(): Boolean { diff --git a/compiler/testData/codegen/box/traits/doubleDiamond.kt b/compiler/testData/codegen/box/traits/doubleDiamond.kt new file mode 100644 index 00000000000..60a83a7de16 --- /dev/null +++ b/compiler/testData/codegen/box/traits/doubleDiamond.kt @@ -0,0 +1,19 @@ +// IGNORE_BACKEND_FIR: JVM_IR + +interface A { + val result: String get() = "Fail" +} + +interface B : A + +abstract class AImpl : A + +abstract class BImpl : AImpl(), B + +interface C : B { + override val result: String get() = "OK" +} + +object CImpl : BImpl(), C + +fun box(): String = CImpl.result diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index c491dbbfebc..f27ed97c869 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -28052,6 +28052,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/traits/diamondPropertyAccessors.kt"); } + @TestMetadata("doubleDiamond.kt") + public void testDoubleDiamond() throws Exception { + runTest("compiler/testData/codegen/box/traits/doubleDiamond.kt"); + } + @TestMetadata("genericMethod.kt") public void testGenericMethod() throws Exception { runTest("compiler/testData/codegen/box/traits/genericMethod.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 9b7316fb06a..94e8ffa336c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -26869,6 +26869,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/traits/diamondPropertyAccessors.kt"); } + @TestMetadata("doubleDiamond.kt") + public void testDoubleDiamond() throws Exception { + runTest("compiler/testData/codegen/box/traits/doubleDiamond.kt"); + } + @TestMetadata("genericMethod.kt") public void testGenericMethod() throws Exception { runTest("compiler/testData/codegen/box/traits/genericMethod.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index c0c17f90744..71ab01c75f5 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -26556,6 +26556,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/traits/diamondPropertyAccessors.kt"); } + @TestMetadata("doubleDiamond.kt") + public void testDoubleDiamond() throws Exception { + runTest("compiler/testData/codegen/box/traits/doubleDiamond.kt"); + } + @TestMetadata("genericMethod.kt") public void testGenericMethod() throws Exception { runTest("compiler/testData/codegen/box/traits/genericMethod.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index cb4568ba59a..9ceaeacb58a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -26556,6 +26556,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/traits/diamondPropertyAccessors.kt"); } + @TestMetadata("doubleDiamond.kt") + public void testDoubleDiamond() throws Exception { + runTest("compiler/testData/codegen/box/traits/doubleDiamond.kt"); + } + @TestMetadata("genericMethod.kt") public void testGenericMethod() throws Exception { runTest("compiler/testData/codegen/box/traits/genericMethod.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 6e832061441..1576ececfe0 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -21567,6 +21567,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/traits/diamondPropertyAccessors.kt"); } + @TestMetadata("doubleDiamond.kt") + public void testDoubleDiamond() throws Exception { + runTest("compiler/testData/codegen/box/traits/doubleDiamond.kt"); + } + @TestMetadata("genericMethod.kt") public void testGenericMethod() throws Exception { runTest("compiler/testData/codegen/box/traits/genericMethod.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index f966b8bcfb6..23d167d5ef3 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -21627,6 +21627,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/traits/diamondPropertyAccessors.kt"); } + @TestMetadata("doubleDiamond.kt") + public void testDoubleDiamond() throws Exception { + runTest("compiler/testData/codegen/box/traits/doubleDiamond.kt"); + } + @TestMetadata("genericMethod.kt") public void testGenericMethod() throws Exception { runTest("compiler/testData/codegen/box/traits/genericMethod.kt");