From ee1608ec99767976d307b605120f93fce03d3720 Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Mon, 15 May 2023 15:01:22 +0200 Subject: [PATCH] [PL] Make call an exception in case of several inherited implementations ^KT-57701 --- .../IrUnimplementedOverridesStrategy.kt | 7 +- .../ir/linkage/partial/PartialLinkageCase.kt | 7 + .../PartiallyLinkedDeclarationOrigin.kt | 3 + .../kotlin/ir/overrides/IrOverridingUtil.kt | 7 +- .../IrUnimplementedOverridesStrategy.kt | 53 ++++++- .../partial/PartialLinkageErrorMessages.kt | 9 ++ .../partial/PartiallyLinkedIrTreePatcher.kt | 1 + .../testData/klibABI/__utils__/__utils__.kt | 7 +- .../lib1/l1.kt.0 | 25 ++++ .../lib1/l1.kt.1 | 38 +++++ .../lib1/module.info | 8 + .../lib2/l2.kt | 50 +++++++ .../lib2/module.info | 2 + .../severalInheritedImplementations/main/m.kt | 137 ++++++++++++++++++ .../main/module.info | 2 + .../project.info | 7 + ...JsPartialLinkageNoICTestCaseGenerated.java | 6 + ...artialLinkageNoICES6TestCaseGenerated.java | 6 + ...JsPartialLinkageNoICTestCaseGenerated.java | 6 + ...PartialLinkageWithICTestCaseGenerated.java | 6 + .../FirNativePartialLinkageTestGenerated.java | 6 + .../NativePartialLinkageTestGenerated.java | 6 + 22 files changed, 386 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/klibABI/severalInheritedImplementations/lib1/l1.kt.0 create mode 100644 compiler/testData/klibABI/severalInheritedImplementations/lib1/l1.kt.1 create mode 100644 compiler/testData/klibABI/severalInheritedImplementations/lib1/module.info create mode 100644 compiler/testData/klibABI/severalInheritedImplementations/lib2/l2.kt create mode 100644 compiler/testData/klibABI/severalInheritedImplementations/lib2/module.info create mode 100644 compiler/testData/klibABI/severalInheritedImplementations/main/m.kt create mode 100644 compiler/testData/klibABI/severalInheritedImplementations/main/module.info create mode 100644 compiler/testData/klibABI/severalInheritedImplementations/project.info diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/IrUnimplementedOverridesStrategy.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/IrUnimplementedOverridesStrategy.kt index 0f095e43193..ec1934fbf83 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/IrUnimplementedOverridesStrategy.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/IrUnimplementedOverridesStrategy.kt @@ -8,7 +8,9 @@ package org.jetbrains.kotlin.ir.linkage.partial import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrOverridableDeclaration import org.jetbrains.kotlin.ir.declarations.IrOverridableMember +import org.jetbrains.kotlin.ir.symbols.IrSymbol interface IrUnimplementedOverridesStrategy { class Customization(val origin: IrDeclarationOrigin?, val modality: Modality?) { @@ -17,9 +19,10 @@ interface IrUnimplementedOverridesStrategy { } } - fun computeCustomization(overridableMember: T, parent: IrClass): Customization + fun > computeCustomization(overridableMember: T, parent: IrClass): Customization + fun > postProcessGeneratedFakeOverride(overridableMember: T, parent: IrClass) {} object ProcessAsFakeOverrides : IrUnimplementedOverridesStrategy { - override fun computeCustomization(overridableMember: T, parent: IrClass) = Customization.NO + override fun > computeCustomization(overridableMember: T, parent: IrClass) = Customization.NO } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartialLinkageCase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartialLinkageCase.kt index 9e60622298d..6c7af37d60b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartialLinkageCase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartialLinkageCase.kt @@ -172,4 +172,11 @@ sealed interface PartialLinkageCase { val annotationConstructorSymbol: IrConstructorSymbol, val holderDeclarationSymbol: IrSymbol ) : PartialLinkageCase + + /** + * Callable, which is not implemented, but inherited several implementations from super interfaces. + * + * Applicable to: Declarations (functions, properties). + */ + class AmbiguousNonOverriddenCallable(val callable: IrOverridableDeclaration<*>) : PartialLinkageCase } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartiallyLinkedDeclarationOrigin.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartiallyLinkedDeclarationOrigin.kt index 01f76a881b6..d27a265f42c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartiallyLinkedDeclarationOrigin.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartiallyLinkedDeclarationOrigin.kt @@ -15,6 +15,9 @@ enum class PartiallyLinkedDeclarationOrigin : IrDeclarationOrigin { /** The abstract callable member that needs to be implemented in non-abstract class */ UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER, + /** The callable member is not implemented and inherit several implementations from interfaces, but no implementation from class */ + AMBIGUOUS_NON_OVERRIDDEN_CALLABLE_MEMBER, + /** Auxiliary declaration generated by [PartiallyLinkedIrTreePatcher] */ AUXILIARY_GENERATED_DECLARATION; } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt index 9e16cca48c3..1f74e400f00 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt @@ -25,9 +25,13 @@ abstract class FakeOverrideBuilderStrategy( private val friendModules: Map>, private val unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy ) { - open fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember = + fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember = buildFakeOverrideMember(superType, member, clazz, friendModules, unimplementedOverridesStrategy) + fun postProcessGeneratedFakeOverride(fakeOverride: IrOverridableMember, clazz: IrClass) { + unimplementedOverridesStrategy.postProcessGeneratedFakeOverride(fakeOverride as IrOverridableDeclaration<*>, clazz) + } + fun linkFakeOverride(fakeOverride: IrOverridableMember, compatibilityMode: Boolean) { when (fakeOverride) { is IrFunctionWithLateBinding -> linkFunctionFakeOverride(fakeOverride, compatibilityMode) @@ -437,6 +441,7 @@ class IrOverridingUtil( addedFakeOverrides.add(fakeOverride) fakeOverrideBuilder.linkFakeOverride(fakeOverride, compatibilityMode) + fakeOverrideBuilder.postProcessGeneratedFakeOverride(fakeOverride, currentClass) } private fun isVisibilityMoreSpecific( diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/IrUnimplementedOverridesStrategy.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/IrUnimplementedOverridesStrategy.kt index eedbd4dad4e..df914659715 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/IrUnimplementedOverridesStrategy.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/IrUnimplementedOverridesStrategy.kt @@ -6,23 +6,22 @@ package org.jetbrains.kotlin.backend.common.linkage.partial import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin -import org.jetbrains.kotlin.ir.declarations.IrField -import org.jetbrains.kotlin.ir.declarations.IrOverridableMember +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.linkage.partial.IrUnimplementedOverridesStrategy import org.jetbrains.kotlin.ir.linkage.partial.PartiallyLinkedDeclarationOrigin +import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.isNothing +import org.jetbrains.kotlin.ir.util.collectRealOverrides +import org.jetbrains.kotlin.ir.util.isInterface internal class ImplementAsErrorThrowingStubs( private val partialLinkageSupport: PartialLinkageSupportForLinker ) : IrUnimplementedOverridesStrategy { - override fun computeCustomization(overridableMember: T, parent: IrClass) = + override fun > computeCustomization(overridableMember: T, parent: IrClass) = if (overridableMember.isAbstract && parent.isConcrete - && !parent.isExternal + && parent.isEligibleForPartialLinkage() && !parent.delegatesToNothing - && !partialLinkageSupport.shouldBeSkipped(parent) ) { IrUnimplementedOverridesStrategy.Customization( origin = PartiallyLinkedDeclarationOrigin.UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER, @@ -30,6 +29,46 @@ internal class ImplementAsErrorThrowingStubs( ) } else IrUnimplementedOverridesStrategy.Customization.NO + override fun > postProcessGeneratedFakeOverride(overridableMember: T, parent: IrClass) { + if (parent.isEligibleForPartialLinkage() && overridableMember.isAmbiguous()) { + fun IrOverridableDeclaration<*>.mark() { + if (isFakeOverride) { + origin = PartiallyLinkedDeclarationOrigin.AMBIGUOUS_NON_OVERRIDDEN_CALLABLE_MEMBER + isFakeOverride = false + } + } + overridableMember.mark() + if (overridableMember is IrProperty) { + overridableMember.getter?.mark() + overridableMember.setter?.mark() + } + } + } + + /** + * The function returns if fake override has unique implementation in super classes to be chosen on call + * + * Candidates is a list of real functions we override, which are not overridden themselves + * by any other function in the list. + * + * If there is a **real** super-class function in the list, it must be unique. + * In that case it is preferred over functions coming from default implementation in interfaces. + * + * If there is no such function, but there are several interface function - it is an incompatible change. + * + * This is done to mimic jvm behaviour. + */ + private fun > T.isAmbiguous(): Boolean { + val candidates = collectRealOverrides().filter { !it.isAbstract } + if (candidates.any { ((it.symbol.owner as IrDeclaration).parent as? IrClass)?.isInterface == false }) { + return false + } + return candidates.size > 1 + } + + private fun IrClass.isEligibleForPartialLinkage() = !isExternal && !partialLinkageSupport.shouldBeSkipped(this) + + private val IrOverridableMember.isAbstract: Boolean get() = modality == Modality.ABSTRACT diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageErrorMessages.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageErrorMessages.kt index bda308bfa94..9cf440a7577 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageErrorMessages.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageErrorMessages.kt @@ -79,6 +79,8 @@ internal fun PartialLinkageCase.renderLinkageError(): String = buildString { is UnimplementedAbstractCallable -> unimplementedAbstractCallable(callable) is UnusableAnnotation -> unusableAnnotation(annotationConstructorSymbol, holderDeclarationSymbol) + + is AmbiguousNonOverriddenCallable -> ambiguousNonOverriddenCallable(callable) } } @@ -588,6 +590,13 @@ private fun Appendable.unusableAnnotation(annotationConstructorSymbol: IrConstru append("Unusable annotation ").declarationName(annotationConstructorSymbol) .append(" has been removed from ").declarationKindName(holderDeclarationSymbol, capitalized = false) +private fun Appendable.ambiguousNonOverriddenCallable(callable: IrOverridableDeclaration<*>): Appendable = + declarationKindName(callable.symbol, capitalized = true) + .append(" in ") + .declarationKindName(callable.parentAsClass.symbol, capitalized = false) + .append(" inherits more than one default implementation") + + private fun Appendable.appendCapitalized(text: String, capitalized: Boolean): Appendable { if (capitalized && text.isNotEmpty()) { val firstChar = text[0] diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt index fdccbea6928..0e9c6714c39 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt @@ -265,6 +265,7 @@ internal class PartiallyLinkedIrTreePatcher( // Compute the linkage case. val partialLinkageCase = when (declaration.origin) { PartiallyLinkedDeclarationOrigin.UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER -> UnimplementedAbstractCallable(declaration) + PartiallyLinkedDeclarationOrigin.AMBIGUOUS_NON_OVERRIDDEN_CALLABLE_MEMBER -> AmbiguousNonOverriddenCallable(declaration) PartiallyLinkedDeclarationOrigin.MISSING_DECLARATION -> MissingDeclaration(declaration.symbol) else -> unusableClassifierInSignature?.let { DeclarationWithUnusableClassifier(declaration.symbol, it) } } diff --git a/compiler/testData/klibABI/__utils__/__utils__.kt b/compiler/testData/klibABI/__utils__/__utils__.kt index 2cf7dd417d4..99ec544d233 100644 --- a/compiler/testData/klibABI/__utils__/__utils__.kt +++ b/compiler/testData/klibABI/__utils__/__utils__.kt @@ -24,15 +24,16 @@ sealed interface FailurePattern private typealias Block = () -> T -enum class TestMode(val isJs: Boolean = false, val isNative: Boolean = false) { +enum class TestMode(val isJs: Boolean = false, val isNative: Boolean = false, val hasCachesEnabled: Boolean = false) { JS_NO_IC(isJs = true), JS_WITH_IC(isJs = true), NATIVE_CACHE_NO(isNative = true), - NATIVE_CACHE_STATIC_ONLY_DIST(isNative = true), - NATIVE_CACHE_STATIC_EVERYWHERE(isNative = true); + NATIVE_CACHE_STATIC_ONLY_DIST(isNative = true, hasCachesEnabled = true), + NATIVE_CACHE_STATIC_EVERYWHERE(isNative = true, hasCachesEnabled = true); init { check(isJs xor isNative) + check(isNative || !hasCachesEnabled) } } diff --git a/compiler/testData/klibABI/severalInheritedImplementations/lib1/l1.kt.0 b/compiler/testData/klibABI/severalInheritedImplementations/lib1/l1.kt.0 new file mode 100644 index 00000000000..29ce9ddb36b --- /dev/null +++ b/compiler/testData/klibABI/severalInheritedImplementations/lib1/l1.kt.0 @@ -0,0 +1,25 @@ +package lib1 + +interface I { +} + +interface J { +} + +interface Default { + fun foo(): String = "Default v1" + val bar: String get() = "Default v1" +} + +interface RemovedDefault { + fun foo(): String = "RemovedDefault v1" + val bar: String get() = "RemovedDefault v1" +} + +open class Unrelated + +abstract class AbstractUnrelated + +open class WithFakeOverride : I + +open class WithRealOverride : I \ No newline at end of file diff --git a/compiler/testData/klibABI/severalInheritedImplementations/lib1/l1.kt.1 b/compiler/testData/klibABI/severalInheritedImplementations/lib1/l1.kt.1 new file mode 100644 index 00000000000..219a069eef9 --- /dev/null +++ b/compiler/testData/klibABI/severalInheritedImplementations/lib1/l1.kt.1 @@ -0,0 +1,38 @@ +package lib1 + +interface I { + fun foo(): String = "I v2" + val bar: String get() = "I v2" +} + +interface J { + fun foo(): String = "J v2" + val bar: String get() = "J v2" +} + +interface Default { + fun foo(): String = "Default v2" + val bar: String get() = "Default v2" +} + +interface RemovedDefault { + fun foo(): String + val bar: String +} + +open class Unrelated { + fun foo(): String = "Unrelated v2" + val bar: String = "Unrelated v2" +} + +abstract class AbstractUnrelated { + abstract fun foo(): String + abstract val bar: String +} + +open class WithFakeOverride : I + +open class WithRealOverride : I { + override fun foo() = "WithRealOverride v2" + override val bar = "WithRealOverride v2" +} diff --git a/compiler/testData/klibABI/severalInheritedImplementations/lib1/module.info b/compiler/testData/klibABI/severalInheritedImplementations/lib1/module.info new file mode 100644 index 00000000000..937de1ea063 --- /dev/null +++ b/compiler/testData/klibABI/severalInheritedImplementations/lib1/module.info @@ -0,0 +1,8 @@ +STEP 0: + dependencies: stdlib + modifications: + U : l1.kt.0 -> l1.kt +STEP 1: + dependencies: stdlib + modifications: + U : l1.kt.1 -> l1.kt diff --git a/compiler/testData/klibABI/severalInheritedImplementations/lib2/l2.kt b/compiler/testData/klibABI/severalInheritedImplementations/lib2/l2.kt new file mode 100644 index 00000000000..f2e6ca3d532 --- /dev/null +++ b/compiler/testData/klibABI/severalInheritedImplementations/lib2/l2.kt @@ -0,0 +1,50 @@ +package lib2 + +import lib1.* + +class I_Default : I, Default +class Default_I : Default, I +class I_RemovedDefault : I, RemovedDefault +class RemovedDefault_I : RemovedDefault, I +class I_J_Default : I, J, Default +class Default_J_I : Default, I, J +class I_J_RemovedDefault : I, J, RemovedDefault +class RemovedDefault_J_I : RemovedDefault, I, J + + +class Unrelated_I_Default : Unrelated(), I, Default +class Unrelated_Default_I : Unrelated(), Default, I +class Unrelated_I_RemovedDefault : Unrelated(), I, RemovedDefault +class Unrelated_RemovedDefault_I : Unrelated(), RemovedDefault, I +class Unrelated_I_J_Default : Unrelated(), I, J, Default +class Unrelated_Default_J_I : Unrelated(), Default, I, J +class Unrelated_I_J_RemovedDefault : Unrelated(), I, J, RemovedDefault +class Unrelated_RemovedDefault_J_I : Unrelated(), RemovedDefault, I, J + +class AbstractUnrelated_I_Default : AbstractUnrelated(), I, Default +class AbstractUnrelated_Default_I : AbstractUnrelated(), Default, I +class AbstractUnrelated_I_RemovedDefault : AbstractUnrelated(), I, RemovedDefault +class AbstractUnrelated_RemovedDefault_I : AbstractUnrelated(), RemovedDefault, I +class AbstractUnrelated_I_J_Default : AbstractUnrelated(), I, J, Default +class AbstractUnrelated_Default_J_I : AbstractUnrelated(), Default, I, J +class AbstractUnrelated_I_J_RemovedDefault : AbstractUnrelated(), I, J, RemovedDefault +class AbstractUnrelated_RemovedDefault_J_I : AbstractUnrelated(), RemovedDefault, I, J + + +class WithFakeOverride_I_Default : WithFakeOverride(), I, Default +class WithFakeOverride_Default_I : WithFakeOverride(), Default, I +class WithFakeOverride_I_RemovedDefault : WithFakeOverride(), I, RemovedDefault +class WithFakeOverride_RemovedDefault_I : WithFakeOverride(), RemovedDefault, I +class WithFakeOverride_I_J_Default : WithFakeOverride(), I, J, Default +class WithFakeOverride_Default_J_I : WithFakeOverride(), Default, I, J +class WithFakeOverride_I_J_RemovedDefault : WithFakeOverride(), I, J, RemovedDefault +class WithFakeOverride_RemovedDefault_J_I : WithFakeOverride(), RemovedDefault, I, J + +class WithRealOverride_I_Default : WithRealOverride(), I, Default +class WithRealOverride_Default_I : WithRealOverride(), Default, I +class WithRealOverride_I_RemovedDefault : WithRealOverride(), I, RemovedDefault +class WithRealOverride_RemovedDefault_I : WithRealOverride(), RemovedDefault, I +class WithRealOverride_I_J_Default : WithRealOverride(), I, J, Default +class WithRealOverride_Default_J_I : WithRealOverride(), Default, I, J +class WithRealOverride_I_J_RemovedDefault : WithRealOverride(), I, J, RemovedDefault +class WithRealOverride_RemovedDefault_J_I : WithRealOverride(), RemovedDefault, I, J diff --git a/compiler/testData/klibABI/severalInheritedImplementations/lib2/module.info b/compiler/testData/klibABI/severalInheritedImplementations/lib2/module.info new file mode 100644 index 00000000000..391aab979a6 --- /dev/null +++ b/compiler/testData/klibABI/severalInheritedImplementations/lib2/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1 \ No newline at end of file diff --git a/compiler/testData/klibABI/severalInheritedImplementations/main/m.kt b/compiler/testData/klibABI/severalInheritedImplementations/main/m.kt new file mode 100644 index 00000000000..a8ff061ba08 --- /dev/null +++ b/compiler/testData/klibABI/severalInheritedImplementations/main/m.kt @@ -0,0 +1,137 @@ +import abitestutils.* +import lib1.* +import lib2.* + +private fun TestBuilder.fe(className: String) = linkage("Function 'foo' in class '${className}' inherits more than one default implementation") +private fun TestBuilder.pe(className: String) = linkage("Property accessor 'bar.' in class '${className}' inherits more than one default implementation") + +fun box() = abiTest { + // For now it's not working with caches, because of incorrect lazy-IR usage. + // Check KT-54019 for details. + if (testMode.hasCachesEnabled) { + expectSuccess("OK") { "OK" } + return@abiTest + } + val instance_I_Default = I_Default() + val instance_Default_I = Default_I() + val instance_I_RemovedDefault = I_RemovedDefault() + val instance_RemovedDefault_I = RemovedDefault_I() + val instance_I_J_Default = I_J_Default() + val instance_Default_J_I = Default_J_I() + val instance_I_J_RemovedDefault = I_J_RemovedDefault() + val instance_RemovedDefault_J_I = RemovedDefault_J_I() + val instance_Unrelated_I_Default = Unrelated_I_Default() + val instance_Unrelated_Default_I = Unrelated_Default_I() + val instance_Unrelated_I_RemovedDefault = Unrelated_I_RemovedDefault() + val instance_Unrelated_RemovedDefault_I = Unrelated_RemovedDefault_I() + val instance_Unrelated_I_J_Default = Unrelated_I_J_Default() + val instance_Unrelated_Default_J_I = Unrelated_Default_J_I() + val instance_Unrelated_I_J_RemovedDefault = Unrelated_I_J_RemovedDefault() + val instance_Unrelated_RemovedDefault_J_I = Unrelated_RemovedDefault_J_I() + val instance_AbstractUnrelated_I_Default = AbstractUnrelated_I_Default() + val instance_AbstractUnrelated_Default_I = AbstractUnrelated_Default_I() + val instance_AbstractUnrelated_I_RemovedDefault = AbstractUnrelated_I_RemovedDefault() + val instance_AbstractUnrelated_RemovedDefault_I = AbstractUnrelated_RemovedDefault_I() + val instance_AbstractUnrelated_I_J_Default = AbstractUnrelated_I_J_Default() + val instance_AbstractUnrelated_Default_J_I = AbstractUnrelated_Default_J_I() + val instance_AbstractUnrelated_I_J_RemovedDefault = AbstractUnrelated_I_J_RemovedDefault() + val instance_AbstractUnrelated_RemovedDefault_J_I = AbstractUnrelated_RemovedDefault_J_I() + val instance_WithFakeOverride_I_Default = WithFakeOverride_I_Default() + val instance_WithFakeOverride_Default_I = WithFakeOverride_Default_I() + val instance_WithFakeOverride_I_RemovedDefault = WithFakeOverride_I_RemovedDefault() + val instance_WithFakeOverride_RemovedDefault_I = WithFakeOverride_RemovedDefault_I() + val instance_WithFakeOverride_I_J_Default = WithFakeOverride_I_J_Default() + val instance_WithFakeOverride_Default_J_I = WithFakeOverride_Default_J_I() + val instance_WithFakeOverride_I_J_RemovedDefault = WithFakeOverride_I_J_RemovedDefault() + val instance_WithFakeOverride_RemovedDefault_J_I = WithFakeOverride_RemovedDefault_J_I() + val instance_WithRealOverride_I_Default = WithRealOverride_I_Default() + val instance_WithRealOverride_Default_I = WithRealOverride_Default_I() + val instance_WithRealOverride_I_RemovedDefault = WithRealOverride_I_RemovedDefault() + val instance_WithRealOverride_RemovedDefault_I = WithRealOverride_RemovedDefault_I() + val instance_WithRealOverride_I_J_Default = WithRealOverride_I_J_Default() + val instance_WithRealOverride_Default_J_I = WithRealOverride_Default_J_I() + val instance_WithRealOverride_I_J_RemovedDefault = WithRealOverride_I_J_RemovedDefault() + val instance_WithRealOverride_RemovedDefault_J_I = WithRealOverride_RemovedDefault_J_I() + + expectFailure(fe("I_Default")) { instance_I_Default.foo() } + expectFailure(fe("Default_I")) { instance_Default_I.foo() } + expectSuccess("I v2") { instance_I_RemovedDefault.foo() } + expectSuccess("I v2") { instance_RemovedDefault_I.foo() } + expectFailure(fe("I_J_Default")) { instance_I_J_Default.foo() } + expectFailure(fe("Default_J_I")) { instance_Default_J_I.foo() } + expectFailure(fe("I_J_RemovedDefault")) { instance_I_J_RemovedDefault.foo() } + expectFailure(fe("RemovedDefault_J_I")) { instance_RemovedDefault_J_I.foo() } + expectSuccess("Unrelated v2") { instance_Unrelated_I_Default.foo() } + expectSuccess("Unrelated v2") { instance_Unrelated_Default_I.foo() } + expectSuccess("Unrelated v2") { instance_Unrelated_I_RemovedDefault.foo() } + expectSuccess("Unrelated v2") { instance_Unrelated_RemovedDefault_I.foo() } + expectSuccess("Unrelated v2") { instance_Unrelated_I_J_Default.foo() } + expectSuccess("Unrelated v2") { instance_Unrelated_Default_J_I.foo() } + expectSuccess("Unrelated v2") { instance_Unrelated_I_J_RemovedDefault.foo() } + expectSuccess("Unrelated v2") { instance_Unrelated_RemovedDefault_J_I.foo() } + expectFailure(fe("AbstractUnrelated_I_Default")) { instance_AbstractUnrelated_I_Default.foo() } + expectFailure(fe("AbstractUnrelated_Default_I")) { instance_AbstractUnrelated_Default_I.foo() } + expectSuccess("I v2") { instance_AbstractUnrelated_I_RemovedDefault.foo() } + expectSuccess("I v2") { instance_AbstractUnrelated_RemovedDefault_I.foo() } + expectFailure(fe("AbstractUnrelated_I_J_Default")) { instance_AbstractUnrelated_I_J_Default.foo() } + expectFailure(fe("AbstractUnrelated_Default_J_I")) { instance_AbstractUnrelated_Default_J_I.foo() } + expectFailure(fe("AbstractUnrelated_I_J_RemovedDefault")) { instance_AbstractUnrelated_I_J_RemovedDefault.foo() } + expectFailure(fe("AbstractUnrelated_RemovedDefault_J_I")) { instance_AbstractUnrelated_RemovedDefault_J_I.foo() } + expectFailure(fe("WithFakeOverride_I_Default")) { instance_WithFakeOverride_I_Default.foo() } + expectFailure(fe("WithFakeOverride_Default_I")) { instance_WithFakeOverride_Default_I.foo() } + expectSuccess("I v2") { instance_WithFakeOverride_I_RemovedDefault.foo() } + expectSuccess("I v2") { instance_WithFakeOverride_RemovedDefault_I.foo() } + expectFailure(fe("WithFakeOverride_I_J_Default")) { instance_WithFakeOverride_I_J_Default.foo() } + expectFailure(fe("WithFakeOverride_Default_J_I")) { instance_WithFakeOverride_Default_J_I.foo() } + expectFailure(fe("WithFakeOverride_I_J_RemovedDefault")) { instance_WithFakeOverride_I_J_RemovedDefault.foo() } + expectFailure(fe("WithFakeOverride_RemovedDefault_J_I")) { instance_WithFakeOverride_RemovedDefault_J_I.foo() } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_Default.foo() } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_Default_I.foo() } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_RemovedDefault.foo() } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_RemovedDefault_I.foo() } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_J_Default.foo() } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_Default_J_I.foo() } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_J_RemovedDefault.foo() } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_RemovedDefault_J_I.foo() } + + expectFailure(pe("I_Default")) { instance_I_Default.bar } + expectFailure(pe("Default_I")) { instance_Default_I.bar } + expectSuccess("I v2") { instance_I_RemovedDefault.bar } + expectSuccess("I v2") { instance_RemovedDefault_I.bar } + expectFailure(pe("I_J_Default")) { instance_I_J_Default.bar } + expectFailure(pe("Default_J_I")) { instance_Default_J_I.bar } + expectFailure(pe("I_J_RemovedDefault")) { instance_I_J_RemovedDefault.bar } + expectFailure(pe("RemovedDefault_J_I")) { instance_RemovedDefault_J_I.bar } + expectSuccess("Unrelated v2") { instance_Unrelated_I_Default.bar } + expectSuccess("Unrelated v2") { instance_Unrelated_Default_I.bar } + expectSuccess("Unrelated v2") { instance_Unrelated_I_RemovedDefault.bar } + expectSuccess("Unrelated v2") { instance_Unrelated_RemovedDefault_I.bar } + expectSuccess("Unrelated v2") { instance_Unrelated_I_J_Default.bar } + expectSuccess("Unrelated v2") { instance_Unrelated_Default_J_I.bar } + expectSuccess("Unrelated v2") { instance_Unrelated_I_J_RemovedDefault.bar } + expectSuccess("Unrelated v2") { instance_Unrelated_RemovedDefault_J_I.bar } + expectFailure(pe("AbstractUnrelated_I_Default")) { instance_AbstractUnrelated_I_Default.bar } + expectFailure(pe("AbstractUnrelated_Default_I")) { instance_AbstractUnrelated_Default_I.bar } + expectSuccess("I v2") { instance_AbstractUnrelated_I_RemovedDefault.bar } + expectSuccess("I v2") { instance_AbstractUnrelated_RemovedDefault_I.bar } + expectFailure(pe("AbstractUnrelated_I_J_Default")) { instance_AbstractUnrelated_I_J_Default.bar } + expectFailure(pe("AbstractUnrelated_Default_J_I")) { instance_AbstractUnrelated_Default_J_I.bar } + expectFailure(pe("AbstractUnrelated_I_J_RemovedDefault")) { instance_AbstractUnrelated_I_J_RemovedDefault.bar } + expectFailure(pe("AbstractUnrelated_RemovedDefault_J_I")) { instance_AbstractUnrelated_RemovedDefault_J_I.bar } + expectFailure(pe("WithFakeOverride_I_Default")) { instance_WithFakeOverride_I_Default.bar } + expectFailure(pe("WithFakeOverride_Default_I")) { instance_WithFakeOverride_Default_I.bar } + expectSuccess("I v2") { instance_WithFakeOverride_I_RemovedDefault.bar } + expectSuccess("I v2") { instance_WithFakeOverride_RemovedDefault_I.bar } + expectFailure(pe("WithFakeOverride_I_J_Default")) { instance_WithFakeOverride_I_J_Default.bar } + expectFailure(pe("WithFakeOverride_Default_J_I")) { instance_WithFakeOverride_Default_J_I.bar } + expectFailure(pe("WithFakeOverride_I_J_RemovedDefault")) { instance_WithFakeOverride_I_J_RemovedDefault.bar } + expectFailure(pe("WithFakeOverride_RemovedDefault_J_I")) { instance_WithFakeOverride_RemovedDefault_J_I.bar } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_Default.bar } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_Default_I.bar } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_RemovedDefault.bar } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_RemovedDefault_I.bar } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_J_Default.bar } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_Default_J_I.bar } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_I_J_RemovedDefault.bar } + expectSuccess("WithRealOverride v2") { instance_WithRealOverride_RemovedDefault_J_I.bar } +} \ No newline at end of file diff --git a/compiler/testData/klibABI/severalInheritedImplementations/main/module.info b/compiler/testData/klibABI/severalInheritedImplementations/main/module.info new file mode 100644 index 00000000000..c086bdb447b --- /dev/null +++ b/compiler/testData/klibABI/severalInheritedImplementations/main/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1, lib2 diff --git a/compiler/testData/klibABI/severalInheritedImplementations/project.info b/compiler/testData/klibABI/severalInheritedImplementations/project.info new file mode 100644 index 00000000000..2147306d715 --- /dev/null +++ b/compiler/testData/klibABI/severalInheritedImplementations/project.info @@ -0,0 +1,7 @@ +MODULES: lib1, lib2, main + +STEP 0: + libs: lib1, lib2, main + +STEP 1: + libs: lib1 \ No newline at end of file diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/FirJsPartialLinkageNoICTestCaseGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/FirJsPartialLinkageNoICTestCaseGenerated.java index 5d5d21ab82e..17f8d67ff8c 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/FirJsPartialLinkageNoICTestCaseGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/FirJsPartialLinkageNoICTestCaseGenerated.java @@ -145,6 +145,12 @@ public class FirJsPartialLinkageNoICTestCaseGenerated extends AbstractFirJsParti runTest("compiler/testData/klibABI/replaceCallableReturnType/"); } + @Test + @TestMetadata("severalInheritedImplementations") + public void testSeveralInheritedImplementations() throws Exception { + runTest("compiler/testData/klibABI/severalInheritedImplementations/"); + } + @Test @TestMetadata("typeAliasChanges") public void testTypeAliasChanges() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageNoICES6TestCaseGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageNoICES6TestCaseGenerated.java index 31ed73458a8..5d9ae8d444c 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageNoICES6TestCaseGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageNoICES6TestCaseGenerated.java @@ -145,6 +145,12 @@ public class JsPartialLinkageNoICES6TestCaseGenerated extends AbstractJsPartialL runTest("compiler/testData/klibABI/replaceCallableReturnType/"); } + @Test + @TestMetadata("severalInheritedImplementations") + public void testSeveralInheritedImplementations() throws Exception { + runTest("compiler/testData/klibABI/severalInheritedImplementations/"); + } + @Test @TestMetadata("typeAliasChanges") public void testTypeAliasChanges() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageNoICTestCaseGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageNoICTestCaseGenerated.java index 8ce8c9a715e..dc2017d5e74 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageNoICTestCaseGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageNoICTestCaseGenerated.java @@ -145,6 +145,12 @@ public class JsPartialLinkageNoICTestCaseGenerated extends AbstractJsPartialLink runTest("compiler/testData/klibABI/replaceCallableReturnType/"); } + @Test + @TestMetadata("severalInheritedImplementations") + public void testSeveralInheritedImplementations() throws Exception { + runTest("compiler/testData/klibABI/severalInheritedImplementations/"); + } + @Test @TestMetadata("typeAliasChanges") public void testTypeAliasChanges() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageWithICTestCaseGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageWithICTestCaseGenerated.java index 8b6341d8707..fe3429bcef1 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageWithICTestCaseGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/JsPartialLinkageWithICTestCaseGenerated.java @@ -145,6 +145,12 @@ public class JsPartialLinkageWithICTestCaseGenerated extends AbstractJsPartialLi runTest("compiler/testData/klibABI/replaceCallableReturnType/"); } + @Test + @TestMetadata("severalInheritedImplementations") + public void testSeveralInheritedImplementations() throws Exception { + runTest("compiler/testData/klibABI/severalInheritedImplementations/"); + } + @Test @TestMetadata("typeAliasChanges") public void testTypeAliasChanges() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativePartialLinkageTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativePartialLinkageTestGenerated.java index 3c7a1156af8..79bb0be130d 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativePartialLinkageTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativePartialLinkageTestGenerated.java @@ -148,6 +148,12 @@ public class FirNativePartialLinkageTestGenerated extends AbstractNativePartialL runTest("compiler/testData/klibABI/replaceCallableReturnType/"); } + @Test + @TestMetadata("severalInheritedImplementations") + public void testSeveralInheritedImplementations() throws Exception { + runTest("compiler/testData/klibABI/severalInheritedImplementations/"); + } + @Test @TestMetadata("typeAliasChanges") public void testTypeAliasChanges() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativePartialLinkageTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativePartialLinkageTestGenerated.java index ea8f4200abf..0d46949e7ae 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativePartialLinkageTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativePartialLinkageTestGenerated.java @@ -144,6 +144,12 @@ public class NativePartialLinkageTestGenerated extends AbstractNativePartialLink runTest("compiler/testData/klibABI/replaceCallableReturnType/"); } + @Test + @TestMetadata("severalInheritedImplementations") + public void testSeveralInheritedImplementations() throws Exception { + runTest("compiler/testData/klibABI/severalInheritedImplementations/"); + } + @Test @TestMetadata("typeAliasChanges") public void testTypeAliasChanges() throws Exception {