From 1b24b95cde9b065a3b2781e0e602f0449ba0523c Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 16 Jun 2023 17:35:01 +0300 Subject: [PATCH] [FIR] Check for subtyping during actualization of supertypes of expect class ^KT-59356 Fixed --- ...DiagnosticsWithLightTreeTestGenerated.java | 6 ++ ...endMPPDiagnosticsWithPsiTestGenerated.java | 6 ++ ...LightTreeBlackBoxCodegenTestGenerated.java | 12 ++++ .../FirPsiBlackBoxCodegenTestGenerated.java | 12 ++++ .../mpp/FirExpectActualMatchingContext.kt | 21 ++++++- .../IrExpectActualMatchingContext.kt | 29 +++++++++- ...bstractExpectActualCompatibilityChecker.kt | 58 +++++++++++++++---- .../calls/mpp/ExpectActualMatchingContext.kt | 14 +++++ .../ClassicExpectActualMatchingContext.kt | 8 +++ .../transitiveSuperclassActualization.kt | 31 ++++++++++ .../transitiveSuperclassActualization_java.kt | 39 +++++++++++++ .../supertypeActualizationWithAny.kt | 8 +++ .../test/runners/DiagnosticTestGenerated.java | 6 ++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++ .../IrBlackBoxCodegenTestGenerated.java | 12 ++++ ...kBoxCodegenWithIrInlinerTestGenerated.java | 12 ++++ .../LightAnalysisModeTestGenerated.java | 5 ++ .../js/test/JsCodegenBoxTestGenerated.java | 6 ++ .../fir/FirJsCodegenBoxTestGenerated.java | 6 ++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 6 ++ .../ir/IrJsES6CodegenBoxTestGenerated.java | 6 ++ .../FirNativeCodegenBoxTestGenerated.java | 6 ++ .../FirNativeCodegenBoxTestNoPLGenerated.java | 6 ++ .../NativeCodegenBoxTestGenerated.java | 6 ++ .../NativeCodegenBoxTestNoPLGenerated.java | 6 ++ .../test/IrCodegenBoxWasmTestGenerated.java | 5 ++ 26 files changed, 323 insertions(+), 15 deletions(-) create mode 100644 compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt create mode 100644 compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization_java.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/supertypeActualizationWithAny.kt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java index 07b548729b6..4ee466ef3eb 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java @@ -169,6 +169,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst runTest("compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt"); } + @Test + @TestMetadata("supertypeActualizationWithAny.kt") + public void testSupertypeActualizationWithAny() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/supertypeActualizationWithAny.kt"); + } + @Test @TestMetadata("varSetterVisibility.kt") public void testVarSetterVisibility() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java index 7e3ff29c19d..6a035574ef4 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java @@ -169,6 +169,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi runTest("compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt"); } + @Test + @TestMetadata("supertypeActualizationWithAny.kt") + public void testSupertypeActualizationWithAny() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/supertypeActualizationWithAny.kt"); + } + @Test @TestMetadata("varSetterVisibility.kt") public void testVarSetterVisibility() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index 5b35dc20f8f..6ba67554b76 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -33669,6 +33669,18 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + + @Test + @TestMetadata("transitiveSuperclassActualization_java.kt") + public void testTransitiveSuperclassActualization_java() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization_java.kt"); + } + @Test @TestMetadata("valueClasses.kt") public void testValueClasses() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index ca7a1d9f988..61e21d8e902 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -33669,6 +33669,18 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + + @Test + @TestMetadata("transitiveSuperclassActualization_java.kt") + public void testTransitiveSuperclassActualization_java() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization_java.kt"); + } + @Test @TestMetadata("valueClasses.kt") public void testValueClasses() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContext.kt index 782e749872b..f6bae90a4cf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatchingContext.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.types.TypeCheckerState import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.utils.addIfNotNull @@ -43,6 +44,9 @@ class FirExpectActualMatchingContext( override val allowClassActualizationWithWiderVisibility: Boolean get() = true + override val allowTransitiveSupertypesActualization: Boolean + get() = true + private fun CallableSymbolMarker.asSymbol(): FirCallableSymbol<*> = this as FirCallableSymbol<*> private fun FunctionSymbolMarker.asSymbol(): FirFunctionSymbol<*> = this as FirFunctionSymbol<*> private fun PropertySymbolMarker.asSymbol(): FirPropertySymbol = this as FirPropertySymbol @@ -144,6 +148,9 @@ class FirExpectActualMatchingContext( override val RegularClassSymbolMarker.superTypes: List get() = asSymbol().resolvedSuperTypes + override val RegularClassSymbolMarker.defaultType: KotlinTypeMarker + get() = asSymbol().defaultType() + override fun RegularClassSymbolMarker.collectAllMembers(isActualDeclaration: Boolean): List> { val symbol = asSymbol() val session = when (isActualDeclaration) { @@ -256,12 +263,24 @@ class FirExpectActualMatchingContext( if (actualType == null) return false return AbstractTypeChecker.equalTypes( - actualSession.typeContext.newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = false), + createTypeCheckerState(), expectType, actualType ) } + override fun actualTypeIsSubtypeOfExpectType(expectType: KotlinTypeMarker, actualType: KotlinTypeMarker): Boolean { + return AbstractTypeChecker.isSubtypeOf( + createTypeCheckerState(), + subType = actualType, + superType = expectType + ) + } + + private fun createTypeCheckerState(): TypeCheckerState { + return actualSession.typeContext.newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = false) + } + override fun RegularClassSymbolMarker.isNotSamInterface(): Boolean { val type = asSymbol().defaultType() val isSam = FirSamResolver(actualSession, scopeSession).isSamType(type) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt index f470a06755a..7434e627ded 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/IrExpectActualMatchingContext.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.types.TypeCheckerState import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction @@ -36,6 +37,9 @@ internal abstract class IrExpectActualMatchingContext( override val allowClassActualizationWithWiderVisibility: Boolean get() = true + override val allowTransitiveSupertypesActualization: Boolean + get() = true + private inline fun CallableSymbolMarker.processIr( onFunction: (IrFunction) -> R, onProperty: (IrProperty) -> R, @@ -161,6 +165,9 @@ internal abstract class IrExpectActualMatchingContext( override val RegularClassSymbolMarker.superTypes: List get() = asIr().superTypes + override val RegularClassSymbolMarker.defaultType: KotlinTypeMarker + get() = asIr().defaultType + override val CallableSymbolMarker.isExpect: Boolean get() = processIr( onFunction = { it.isExpect }, @@ -312,15 +319,31 @@ internal abstract class IrExpectActualMatchingContext( * When we match return types of (1) and (2) they both will have original type `S`, but from * perspective of module `platform` it should be replaced with `String` */ - val actualizedExpectType = actualizingSubstitutor.substitute(expectType as IrType) - val actualizedActualType = actualizingSubstitutor.substitute(actualType as IrType) + val actualizedExpectType = expectType.actualize() + val actualizedActualType = actualType.actualize() return AbstractTypeChecker.equalTypes( - typeContext.newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = false), + createTypeCheckerState(), actualizedExpectType, actualizedActualType ) } + private fun createTypeCheckerState(): TypeCheckerState { + return typeContext.newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = false) + } + + override fun actualTypeIsSubtypeOfExpectType(expectType: KotlinTypeMarker, actualType: KotlinTypeMarker): Boolean { + return AbstractTypeChecker.isSubtypeOf( + createTypeCheckerState(), + subType = actualType.actualize(), + superType = expectType.actualize() + ) + } + + private fun KotlinTypeMarker.actualize(): IrType { + return actualizingSubstitutor.substitute(this as IrType) + } + private val actualizingSubstitutor = ActualizingSubstitutor() private inner class ActualizingSubstitutor : AbstractIrTypeSubstitutor() { diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualCompatibilityChecker.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualCompatibilityChecker.kt index 9c0f815bb8c..70b0667919d 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualCompatibilityChecker.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/AbstractExpectActualCompatibilityChecker.kt @@ -122,17 +122,7 @@ object AbstractExpectActualCompatibilityChecker { } } - // Subtract kotlin.Any from supertypes because it's implicitly added if no explicit supertype is specified, - // and not added if an explicit supertype _is_ specified - val expectSupertypes = expectClassSymbol.superTypes.filterNot { it.typeConstructor().isAnyConstructor() } - val actualSupertypes = actualClass.superTypes.filterNot { it.typeConstructor().isAnyConstructor() } - if ( - expectSupertypes.map { substitutor.safeSubstitute(it) }.any { expectSupertype -> - actualSupertypes.none { actualSupertype -> - areCompatibleExpectActualTypes(expectSupertype, actualSupertype) - } - } - ) { + if (!areCompatibleSupertypes(expectClassSymbol, actualClass, substitutor)) { return Incompatible.Supertypes } @@ -145,6 +135,52 @@ object AbstractExpectActualCompatibilityChecker { return ExpectActualCompatibility.Compatible } + context(ExpectActualMatchingContext<*>) + private fun areCompatibleSupertypes( + expectClassSymbol: RegularClassSymbolMarker, + actualClassSymbol: RegularClassSymbolMarker, + substitutor: TypeSubstitutorMarker, + ): Boolean { + return when (allowTransitiveSupertypesActualization) { + false -> areCompatibleSupertypesOneByOne(expectClassSymbol, actualClassSymbol, substitutor) + true -> areCompatibleSupertypesTransitive(expectClassSymbol, actualClassSymbol, substitutor) + } + } + + context(ExpectActualMatchingContext<*>) + private fun areCompatibleSupertypesOneByOne( + expectClassSymbol: RegularClassSymbolMarker, + actualClassSymbol: RegularClassSymbolMarker, + substitutor: TypeSubstitutorMarker, + ): Boolean { + // Subtract kotlin.Any from supertypes because it's implicitly added if no explicit supertype is specified, + // and not added if an explicit supertype _is_ specified + val expectSupertypes = expectClassSymbol.superTypes.filterNot { it.typeConstructor().isAnyConstructor() } + val actualSupertypes = actualClassSymbol.superTypes.filterNot { it.typeConstructor().isAnyConstructor() } + return expectSupertypes.all { expectSupertype -> + val substitutedExpectType = substitutor.safeSubstitute(expectSupertype) + actualSupertypes.any { actualSupertype -> + areCompatibleExpectActualTypes(substitutedExpectType, actualSupertype) + } + } + } + + context(ExpectActualMatchingContext<*>) + private fun areCompatibleSupertypesTransitive( + expectClassSymbol: RegularClassSymbolMarker, + actualClassSymbol: RegularClassSymbolMarker, + substitutor: TypeSubstitutorMarker, + ): Boolean { + val expectSupertypes = expectClassSymbol.superTypes.filterNot { it.typeConstructor().isAnyConstructor() } + val actualType = actualClassSymbol.defaultType + return expectSupertypes.all { expectSupertype -> + actualTypeIsSubtypeOfExpectType( + expectType = substitutor.safeSubstitute(expectSupertype), + actualType = actualType + ) + } + } + context(ExpectActualMatchingContext<*>) private fun areCompatibleClassScopes( expectClassSymbol: RegularClassSymbolMarker, diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt index e52f4f5918c..3d53f1f3696 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/mpp/ExpectActualMatchingContext.kt @@ -50,6 +50,14 @@ interface ExpectActualMatchingContext : TypeSystemC val allowClassActualizationWithWiderVisibility: Boolean get() = false + /** + * This flag determines strategy for matching supertypes between expect and actual class + * - `false` means that expect and actual supertypes are matched one by one + * - `true` means that type of actual class should be subtype of each expect supertype of the expect class + */ + val allowTransitiveSupertypesActualization: Boolean + get() = false + val RegularClassSymbolMarker.classId: ClassId val TypeAliasSymbolMarker.classId: ClassId val CallableSymbolMarker.callableId: CallableId @@ -74,6 +82,7 @@ interface ExpectActualMatchingContext : TypeSystemC val CallableSymbolMarker.visibility: Visibility val RegularClassSymbolMarker.superTypes: List + val RegularClassSymbolMarker.defaultType: KotlinTypeMarker val CallableSymbolMarker.isExpect: Boolean val CallableSymbolMarker.isInline: Boolean @@ -125,6 +134,11 @@ interface ExpectActualMatchingContext : TypeSystemC actualType: KotlinTypeMarker?, ): Boolean + fun actualTypeIsSubtypeOfExpectType( + expectType: KotlinTypeMarker, + actualType: KotlinTypeMarker + ): Boolean + fun RegularClassSymbolMarker.isNotSamInterface(): Boolean /* diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt index f943a8c1659..8a25e913765 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ClassicExpectActualMatchingContext.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction import org.jetbrains.kotlin.utils.addToStdlib.castAll +import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled import org.jetbrains.kotlin.utils.keysToMap class ClassicExpectActualMatchingContext(val platformModule: ModuleDescriptor) : ExpectActualMatchingContext, @@ -212,6 +213,13 @@ class ClassicExpectActualMatchingContext(val platformModule: ModuleDescriptor) : } } + override val RegularClassSymbolMarker.defaultType: KotlinTypeMarker + get() = asDescriptor().defaultType + + override fun actualTypeIsSubtypeOfExpectType(expectType: KotlinTypeMarker, actualType: KotlinTypeMarker): Boolean { + shouldNotBeCalled("Checking for subtyping is used only in FIR and IR implementations") + } + @OptIn(TypeRefinement::class) private fun areCompatibleTypesViaTypeRefinement(a: KotlinType, b: KotlinType): Boolean { val typeRefinerForPlatformModule = platformModule.getKotlinTypeRefiner().let { moduleRefiner -> diff --git a/compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt b/compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt new file mode 100644 index 00000000000..56abf16f66a --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt @@ -0,0 +1,31 @@ +// IGNORE_BACKEND_K1: ANY +// IGNORE_REASON: new rules for supertypes matching are implemented only in K2 +// IGNORE_BACKEND_K2: JS_IR +// IGNORE_REASON: `JsName` in js.translator/testData/_commonFiles/testUtils.kt is invisible for some reason +// IGNORE_BACKEND: WASM +// IGNORE_REASON: wasm tests don't support IGNORE_BACKEND_K1 directive +// LANGUAGE: +MultiPlatformProjects +// ISSUE: KT-59356 + +// MODULE: common +// FILE: common.kt +open class A { + open fun foo(): String = "Fail" +} +expect class C() : A + +fun commonBox(): String { + return C().foo() +} + +// MODULE: platform-jvm()()(common) +// FILE: main.kt +open class B : A() { + override fun foo(): String = "OK" +} + +actual class C actual constructor() : B() + +fun box(): String { + return commonBox() +} diff --git a/compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization_java.kt b/compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization_java.kt new file mode 100644 index 00000000000..aadbd800558 --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization_java.kt @@ -0,0 +1,39 @@ +// TARGET_BACKEND: JVM_IR +// IGNORE_BACKEND_K1: ANY +// IGNORE_REASON: new rules for supertypes matching are implemented only in K2 +// LANGUAGE: +MultiPlatformProjects +// ISSUE: KT-59356 + +// MODULE: common +open class A { + open fun foo(): String = "Fail" +} +expect class C1() : A +expect class C2() : A + +fun commonBox(): String { + return C1().foo() + C2().foo() +} + +// MODULE: platform-jvm()()(common) +// FILE: A_J.java +public class A_J {} + +// FILE: B_J.java +public class B_J extends A_J { + public String foo() { return "O"; } +} + +// FILE: C2_J.java +public class C2_J extends B_J { + public String foo() { return "K"; } +} + +// FILE: main.kt +actual typealias A = A_J +actual class C1 : B_J() +actual typealias C2 = C2_J + +fun box(): String { + return commonBox() +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/supertypeActualizationWithAny.kt b/compiler/testData/diagnostics/tests/multiplatform/supertypeActualizationWithAny.kt new file mode 100644 index 00000000000..ce5a3179e70 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/supertypeActualizationWithAny.kt @@ -0,0 +1,8 @@ +// FIR_IDENTICAL +// MODULE: m1-common +expect open class A +expect class B : A + +// MODULE: m1-jvm()()(m1-common) +actual typealias A = Any +actual class B diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 26696a55094..79913db4bf7 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -22558,6 +22558,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt"); } + @Test + @TestMetadata("supertypeActualizationWithAny.kt") + public void testSupertypeActualizationWithAny() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/supertypeActualizationWithAny.kt"); + } + @Test @TestMetadata("varSetterVisibility.kt") public void testVarSetterVisibility() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index b883a21882f..1a7d6c71504 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -32085,6 +32085,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @Test @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 51fa747ec36..e339435d9be 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -33669,6 +33669,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + + @Test + @TestMetadata("transitiveSuperclassActualization_java.kt") + public void testTransitiveSuperclassActualization_java() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization_java.kt"); + } + @Test @TestMetadata("valueClasses.kt") public void testValueClasses() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java index 94cf84b605b..c52142841ea 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java @@ -33669,6 +33669,18 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + + @Test + @TestMetadata("transitiveSuperclassActualization_java.kt") + public void testTransitiveSuperclassActualization_java() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization_java.kt"); + } + @Test @TestMetadata("valueClasses.kt") public void testValueClasses() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 0d6fd02b594..c4ed1d3f06c 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -27360,6 +27360,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/multiplatform/k2/basic/nonExternalEquals.kt"); } + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/k2/basic/widerVisibilityInActualClassifier.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index 3ec95b3e9ec..e292edc2a73 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java @@ -23439,6 +23439,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @Test @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java index 22e84659b82..4486457af7e 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java @@ -23607,6 +23607,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest { runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @Test @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index d250703c2a8..6aee51877a1 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -23607,6 +23607,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @Test @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java index 5a1e7434844..f5e8bc5fe31 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java @@ -23607,6 +23607,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @Test @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java index d101bc541ca..e505a18c234 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestGenerated.java @@ -26673,6 +26673,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @Test @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestNoPLGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestNoPLGenerated.java index d88448a2511..2ce466c63b0 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestNoPLGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCodegenBoxTestNoPLGenerated.java @@ -27279,6 +27279,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @Test @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index 5788cdb6ce3..2abe332621c 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -26371,6 +26371,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @Test @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestNoPLGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestNoPLGenerated.java index 8227298e564..4a35d652ce7 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestNoPLGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestNoPLGenerated.java @@ -26674,6 +26674,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @Test + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @Test @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { diff --git a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java index f2f0f3ffc83..8f14db402f2 100644 --- a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java +++ b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java @@ -20968,6 +20968,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/multiplatform/k2/basic/removeExpectDeclarationsFromMetadata.kt"); } + @TestMetadata("transitiveSuperclassActualization.kt") + public void testTransitiveSuperclassActualization() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/k2/basic/transitiveSuperclassActualization.kt"); + } + @TestMetadata("widerVisibilityInActualClassifier.kt") public void testWiderVisibilityInActualClassifier() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/k2/basic/widerVisibilityInActualClassifier.kt");