From 61d40403e72e9541616ebea90c98505a58fd1145 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Fri, 19 Nov 2021 14:42:41 +0300 Subject: [PATCH] [FE 1.0] Create captured star projection for self types by replacing type arguments deeply ^KT-49752 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 +++ .../kotlin/fir/types/ConeTypeContext.kt | 12 +++++ .../kotlin/ir/types/IrTypeSystemContext.kt | 3 ++ .../testData/codegen/box/sealed/kt49752.kt | 51 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++ .../LightAnalysisModeTestGenerated.java | 5 ++ .../kotlin/types/model/TypeSystemContext.kt | 29 ++++++++++- .../types/checker/ClassicTypeSystemContext.kt | 6 +++ .../js/test/JsCodegenBoxTestGenerated.java | 6 +++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 6 +++ .../IrCodegenBoxWasmTestGenerated.java | 5 ++ 12 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/sealed/kt49752.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index d91a48d2434..59de9a6e910 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -41740,6 +41740,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/sealed/delegatingConstructor.kt"); } + @Test + @TestMetadata("kt49752.kt") + public void testKt49752() throws Exception { + runTest("compiler/testData/codegen/box/sealed/kt49752.kt"); + } + @Test @TestMetadata("multipleFiles_enabled.kt") public void testMultipleFiles_enabled() throws Exception { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index 16f90030b5a..503b7367e05 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -210,6 +210,18 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty return this.type } + override fun TypeArgumentMarker.replaceType(newType: KotlinTypeMarker): TypeArgumentMarker { + require(this is ConeKotlinTypeProjection) + require(newType is ConeKotlinType) + return when (this) { + is ConeKotlinType -> newType + is ConeStarProjection -> ConeStarProjection + is ConeKotlinTypeProjectionOut -> ConeKotlinTypeProjectionOut(newType) + is ConeKotlinTypeProjectionIn -> ConeKotlinTypeProjectionIn(newType) + is ConeKotlinTypeConflictingProjection -> ConeKotlinTypeConflictingProjection(newType) + } + } + override fun TypeConstructorMarker.parametersCount(): Int { return when (this) { is ConeTypeParameterLookupTag, diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index 045d2933c15..f20cb9db70a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -131,6 +131,9 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun TypeArgumentMarker.getVariance(): TypeVariance = (this as? IrTypeProjection)?.variance?.convertVariance() ?: TypeVariance.OUT + override fun TypeArgumentMarker.replaceType(newType: KotlinTypeMarker): TypeArgumentMarker = + IrTypeProjectionImpl(newType as IrType, (this as IrTypeProjection).variance) + override fun TypeArgumentMarker.getType() = (this as IrTypeProjection).type private fun getTypeParameters(typeConstructor: TypeConstructorMarker): List { diff --git a/compiler/testData/codegen/box/sealed/kt49752.kt b/compiler/testData/codegen/box/sealed/kt49752.kt new file mode 100644 index 00000000000..4660d3ed040 --- /dev/null +++ b/compiler/testData/codegen/box/sealed/kt49752.kt @@ -0,0 +1,51 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// FIR status: a new FE 1.0 test, failed with FIR, need to review + +abstract class Interpreter + where IS : Interpreter.Intermediary, + TS : Interpreter.Terminal, + SELF : Interpreter { + sealed interface Step + where INTERPRETER : Interpreter, out Terminal, INTERPRETER> + interface Intermediary : Step + where INTERPRETER : Interpreter, out Terminal, INTERPRETER> + interface Terminal : Step + where INTERPRETER : Interpreter, out Terminal, INTERPRETER> + abstract fun next(currentStep: IS): () -> Step +} + +sealed interface BaseTerminal, I>> : Interpreter.Terminal { + data class Success, I>>( + val result: Int + ) : BaseTerminal +} + +class CountingInterpreter : Interpreter, CountingInterpreter>() { + sealed interface Intermediary : Interpreter.Intermediary { + data class KeepCounting( + val togo: Int + ) : Intermediary + } + var count = 0 + override fun next( + currentStep: Intermediary + ): () -> Step = { + when (currentStep) { + is Intermediary.KeepCounting -> if (currentStep.togo == 0) { + BaseTerminal.Success(count) + } else { + count++ + Intermediary.KeepCounting(currentStep.togo - 1) + } + } + } +} + +fun box(): String { + val interpreter = CountingInterpreter() + var step: Interpreter.Step = CountingInterpreter.Intermediary.KeepCounting(1) + while (step is CountingInterpreter.Intermediary) { + step = interpreter.next(step).invoke() + } + return if ((step as BaseTerminal.Success).result == 1) "OK" else "NOK" +} 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 5b5d781ca79..bac602227b5 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 @@ -41338,6 +41338,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/sealed/delegatingConstructor.kt"); } + @Test + @TestMetadata("kt49752.kt") + public void testKt49752() throws Exception { + runTest("compiler/testData/codegen/box/sealed/kt49752.kt"); + } + @Test @TestMetadata("multipleFiles_enabled.kt") public void testMultipleFiles_enabled() 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 0c5b6f099eb..2096da6d2e7 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 @@ -41740,6 +41740,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/sealed/delegatingConstructor.kt"); } + @Test + @TestMetadata("kt49752.kt") + public void testKt49752() throws Exception { + runTest("compiler/testData/codegen/box/sealed/kt49752.kt"); + } + @Test @TestMetadata("multipleFiles_enabled.kt") public void testMultipleFiles_enabled() 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 50313639d3b..2b4f9bd3d60 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -33233,6 +33233,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/sealed/delegatingConstructor.kt"); } + @TestMetadata("kt49752.kt") + public void testKt49752() throws Exception { + runTest("compiler/testData/codegen/box/sealed/kt49752.kt"); + } + @TestMetadata("multipleFiles_enabled.kt") public void testMultipleFiles_enabled() throws Exception { runTest("compiler/testData/codegen/box/sealed/multipleFiles_enabled.kt"); diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index 406968454cf..d5a0f1e92d1 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -177,7 +177,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui fun SimpleTypeMarker.replaceArguments(newArguments: List): SimpleTypeMarker fun SimpleTypeMarker.replaceArguments(replacement: (TypeArgumentMarker) -> TypeArgumentMarker): SimpleTypeMarker - fun KotlinTypeMarker.replaceArguments(replacement: (TypeArgumentMarker) -> TypeArgumentMarker) = + fun KotlinTypeMarker.replaceArguments(replacement: (TypeArgumentMarker) -> TypeArgumentMarker): KotlinTypeMarker = when (this) { is SimpleTypeMarker -> replaceArguments(replacement) is FlexibleTypeMarker -> createFlexibleType( @@ -187,6 +187,30 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui else -> error("sealed") } + fun SimpleTypeMarker.replaceArgumentsDeeply(replacement: (TypeArgumentMarker) -> TypeArgumentMarker): SimpleTypeMarker { + return replaceArguments { + if (it.isStarProjection()) return@replaceArguments it + + val type = it.getType() + val newProjection = if (type.argumentsCount() > 0) { + it.replaceType(type.replaceArgumentsDeeply(replacement)) + } else it + + replacement(newProjection) + } + } + + fun KotlinTypeMarker.replaceArgumentsDeeply(replacement: (TypeArgumentMarker) -> TypeArgumentMarker): KotlinTypeMarker { + return when (this) { + is SimpleTypeMarker -> replaceArgumentsDeeply(replacement) + is FlexibleTypeMarker -> createFlexibleType( + lowerBound().replaceArgumentsDeeply(replacement), + upperBound().replaceArgumentsDeeply(replacement) + ) + else -> error("sealed") + } + } + fun KotlinTypeMarker.hasExactAnnotation(): Boolean fun KotlinTypeMarker.hasNoInferAnnotation(): Boolean @@ -270,7 +294,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui val starProjection = createStarProjection(typeParameter) val superType = intersectTypes( typesForRecursiveTypeParameters.map { type -> - type.replaceArguments { + type.replaceArgumentsDeeply { val constructor = it.getType().typeConstructor() if (constructor is TypeVariableTypeConstructorMarker && constructor == typeVariable) starProjection else it } @@ -342,6 +366,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext { fun TypeArgumentMarker.isStarProjection(): Boolean fun TypeArgumentMarker.getVariance(): TypeVariance fun TypeArgumentMarker.getType(): KotlinTypeMarker + fun TypeArgumentMarker.replaceType(newType: KotlinTypeMarker): TypeArgumentMarker fun TypeConstructorMarker.parametersCount(): Int fun TypeConstructorMarker.getParameter(index: Int): TypeParameterMarker diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index e2406a7cec2..e32e9a01c02 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -203,6 +203,12 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return this.projectionKind.convertVariance() } + override fun TypeArgumentMarker.replaceType(newType: KotlinTypeMarker): TypeArgumentMarker { + require(this is TypeProjection, this::errorMessage) + require(newType is KotlinType, this::errorMessage) + return this.replaceType(newType) + } + override fun TypeArgumentMarker.getType(): KotlinTypeMarker { require(this is TypeProjection, this::errorMessage) return this.type.unwrap() 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 25a21609070..8bfa02838ff 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 @@ -29820,6 +29820,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/sealed/delegatingConstructor.kt"); } + @Test + @TestMetadata("kt49752.kt") + public void testKt49752() throws Exception { + runTest("compiler/testData/codegen/box/sealed/kt49752.kt"); + } + @Test @TestMetadata("multipleFiles_enabled.kt") public void testMultipleFiles_enabled() 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 da8d8a83759..2c11bc448a3 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 @@ -29922,6 +29922,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/sealed/delegatingConstructor.kt"); } + @Test + @TestMetadata("kt49752.kt") + public void testKt49752() throws Exception { + runTest("compiler/testData/codegen/box/sealed/kt49752.kt"); + } + @Test @TestMetadata("multipleFiles_enabled.kt") public void testMultipleFiles_enabled() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 97bdc01b427..a72857d5000 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -24842,6 +24842,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/sealed/delegatingConstructor.kt"); } + @TestMetadata("kt49752.kt") + public void testKt49752() throws Exception { + runTest("compiler/testData/codegen/box/sealed/kt49752.kt"); + } + @TestMetadata("multipleFiles_enabled.kt") public void testMultipleFiles_enabled() throws Exception { runTest("compiler/testData/codegen/box/sealed/multipleFiles_enabled.kt");