From 0d6764efc5f9272a7d0a24eb11274da0313ecb39 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Fri, 14 May 2021 18:57:59 +0300 Subject: [PATCH] Process raw types during erasion properly ^KT-46670 Fixed ^KT-46476 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 ++++ .../FirBlackBoxCodegenTestGenerated.java | 12 ++++++++ .../platformTypes/rawTypeWithNestedClass.kt | 17 +++++++++++ ...ComputingOnInterdependentTypeParameters.kt | 29 +++++++++++++++++++ ...omputingOnInterdependentTypeParameters.txt | 26 +++++++++++++++++ .../rawTypes/superTypeErasion.kt | 14 +++++++++ .../rawTypes/superTypeErasion.txt | 10 +++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 ++++++++ .../IrBlackBoxCodegenTestGenerated.java | 12 ++++++++ .../LightAnalysisModeTestGenerated.java | 10 +++++++ .../load/java/lazy/types/JavaTypeResolver.kt | 19 ++++++++---- .../org/jetbrains/kotlin/types/TypeUtils.kt | 2 +- 14 files changed, 174 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/codegen/box/platformTypes/rawTypeWithNestedClass.kt create mode 100644 compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.kt create mode 100644 compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.txt create mode 100644 compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.kt create mode 100644 compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.txt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index a50002db7ac..b2a02db78c3 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -21304,6 +21304,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/substituteSeveralOtherErasedTypeArguments.kt"); } + @Test + @TestMetadata("superTypeErasion.kt") + public void testSuperTypeErasion() throws Exception { + runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.kt"); + } + @Test @TestMetadata("typeEnhancement.kt") public void testTypeEnhancement() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 850fea75fe8..8b6a543b2b9 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -21304,6 +21304,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/substituteSeveralOtherErasedTypeArguments.kt"); } + @Test + @TestMetadata("superTypeErasion.kt") + public void testSuperTypeErasion() throws Exception { + runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.kt"); + } + @Test @TestMetadata("typeEnhancement.kt") public void testTypeEnhancement() throws Exception { 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 92d909fd1d1..b37e74ab774 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 @@ -27248,6 +27248,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/platformTypes/kt14989.kt"); } + @Test + @TestMetadata("rawTypeWithNestedClass.kt") + public void testRawTypeWithNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/rawTypeWithNestedClass.kt"); + } + @Test @TestMetadata("specializedMapFull.kt") public void testSpecializedMapFull() throws Exception { @@ -27260,6 +27266,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/platformTypes/specializedMapPut.kt"); } + @Test + @TestMetadata("stopComputingOnInterdependentTypeParameters.kt") + public void testStopComputingOnInterdependentTypeParameters() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.kt"); + } + @Test @TestMetadata("unsafeNullCheck.kt") public void testUnsafeNullCheck() throws Exception { diff --git a/compiler/testData/codegen/box/platformTypes/rawTypeWithNestedClass.kt b/compiler/testData/codegen/box/platformTypes/rawTypeWithNestedClass.kt new file mode 100644 index 00000000000..b2af264bf00 --- /dev/null +++ b/compiler/testData/codegen/box/platformTypes/rawTypeWithNestedClass.kt @@ -0,0 +1,17 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR + +// FILE: OCNewFileActionBase.java +public class OCNewFileActionBase.CreateFileDialogBase> { + public class CreateFileDialogBase { } + + static OCNewFileActionBase get() { return new OCNewFileActionBase(); } +} + +// FILE: main.kt +fun box(): String { + // Before changes in raw types computation: (OCNewFileActionBase.CreateFileDialogBase!>..OCNewFileActionBase.CreateFileDialogBase!>?) + // After that: raw (OCNewFileActionBase<*>..OCNewFileActionBase<*>?) + val x = OCNewFileActionBase.get() + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.kt b/compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.kt new file mode 100644 index 00000000000..4937323ecc5 --- /dev/null +++ b/compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.kt @@ -0,0 +1,29 @@ +// TARGET_BACKEND: JVM +// FILE: AbstractMessageLite.java + +public abstract class AbstractMessageLite< + MessageType extends AbstractMessageLite, +BuilderType extends AbstractMessageLite.Builder> +{ + public void writeDelimitedTo() {} + + public abstract static class Builder< + MessageType extends AbstractMessageLite, + BuilderType extends Builder> + {} +} + +// FILE: H.java +public class H extends AbstractMessageLite {} + +// FILE: test.kt + +fun f(h: H) { + h.writeDelimitedTo() +} + +fun box(): String { + f(H()) + return "OK" +} + diff --git a/compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.txt b/compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.txt new file mode 100644 index 00000000000..3d58be5e120 --- /dev/null +++ b/compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.txt @@ -0,0 +1,26 @@ +package + +public fun f(/*0*/ h: H): kotlin.Unit + +public abstract class AbstractMessageLite!, /*1*/ BuilderType : AbstractMessageLite.Builder!> { + public constructor AbstractMessageLite!, /*1*/ BuilderType : AbstractMessageLite.Builder!>() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public open fun writeDelimitedTo(): kotlin.Unit + + public abstract class Builder!, /*1*/ BuilderType : AbstractMessageLite.Builder!> { + public constructor Builder!, /*1*/ BuilderType : AbstractMessageLite.Builder!>() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public open class H : AbstractMessageLite<(raw) *, (raw) *> { + public constructor H() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public open override /*1*/ /*fake_override*/ fun writeDelimitedTo(): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.kt new file mode 100644 index 00000000000..6cb0e20130c --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.kt @@ -0,0 +1,14 @@ +// FIR_IDENTICAL +// FILE: Test.java +class BaseOperation> {} + +class Foo { } + +class Bar {} + +public class Test extends BaseOperation {} + +// FILE: main.kt +fun main() { + val x = Test() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.txt new file mode 100644 index 00000000000..d168eddcef7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.txt @@ -0,0 +1,10 @@ +package + +public fun main(): kotlin.Unit + +public open class Test : BaseOperation<(raw) Bar!, (raw) Foo!> { + public constructor Test() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} 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 dc346f04351..c22cdb60227 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 @@ -21310,6 +21310,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/substituteSeveralOtherErasedTypeArguments.kt"); } + @Test + @TestMetadata("superTypeErasion.kt") + public void testSuperTypeErasion() throws Exception { + runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/superTypeErasion.kt"); + } + @Test @TestMetadata("typeEnhancement.kt") public void testTypeEnhancement() 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 4bf8cfe3ba2..453e0872894 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 @@ -27224,6 +27224,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/platformTypes/kt14989.kt"); } + @Test + @TestMetadata("rawTypeWithNestedClass.kt") + public void testRawTypeWithNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/rawTypeWithNestedClass.kt"); + } + @Test @TestMetadata("specializedMapFull.kt") public void testSpecializedMapFull() throws Exception { @@ -27236,6 +27242,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/platformTypes/specializedMapPut.kt"); } + @Test + @TestMetadata("stopComputingOnInterdependentTypeParameters.kt") + public void testStopComputingOnInterdependentTypeParameters() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.kt"); + } + @Test @TestMetadata("unsafeNullCheck.kt") public void testUnsafeNullCheck() 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 a6f16e4b80f..cf566d3d86f 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 @@ -27248,6 +27248,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/platformTypes/kt14989.kt"); } + @Test + @TestMetadata("rawTypeWithNestedClass.kt") + public void testRawTypeWithNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/rawTypeWithNestedClass.kt"); + } + @Test @TestMetadata("specializedMapFull.kt") public void testSpecializedMapFull() throws Exception { @@ -27260,6 +27266,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/platformTypes/specializedMapPut.kt"); } + @Test + @TestMetadata("stopComputingOnInterdependentTypeParameters.kt") + public void testStopComputingOnInterdependentTypeParameters() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.kt"); + } + @Test @TestMetadata("unsafeNullCheck.kt") public void testUnsafeNullCheck() 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 ebd566c076f..cdf1b995ea8 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -23096,6 +23096,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/platformTypes/kt14989.kt"); } + @TestMetadata("rawTypeWithNestedClass.kt") + public void testRawTypeWithNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/rawTypeWithNestedClass.kt"); + } + @TestMetadata("specializedMapFull.kt") public void testSpecializedMapFull() throws Exception { runTest("compiler/testData/codegen/box/platformTypes/specializedMapFull.kt"); @@ -23106,6 +23111,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/platformTypes/specializedMapPut.kt"); } + @TestMetadata("stopComputingOnInterdependentTypeParameters.kt") + public void testStopComputingOnInterdependentTypeParameters() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/stopComputingOnInterdependentTypeParameters.kt"); + } + @TestMetadata("unsafeNullCheck.kt") public void testUnsafeNullCheck() throws Exception { runTest("compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt"); diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/JavaTypeResolver.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/JavaTypeResolver.kt index a505681b30b..df9534f6c72 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/JavaTypeResolver.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/types/JavaTypeResolver.kt @@ -315,6 +315,7 @@ data class JavaTypeAttributes( val upperBoundOfTypeParameter: TypeParameterDescriptor? = null ) { fun withFlexibility(flexibility: JavaTypeFlexibility) = copy(flexibility = flexibility) + fun withTypeParameter(upperBoundOfTypeParameter: TypeParameterDescriptor) = copy(upperBoundOfTypeParameter = upperBoundOfTypeParameter) } enum class JavaTypeFlexibility { @@ -346,6 +347,8 @@ internal fun TypeParameterDescriptor.getErasedUpperBound( ): KotlinType { if (this === typeAttr.upperBoundOfTypeParameter) return defaultValue() + val newTypeAttr = if (typeAttr.upperBoundOfTypeParameter == null) typeAttr.withTypeParameter(this) else typeAttr + /* * We should do erasure of containing type parameters with their erasure to avoid creating inconsistent types. * E.g. for `class Foo, B>`, we'd have erasure for lower bound: Foo, Any>, @@ -353,12 +356,16 @@ internal fun TypeParameterDescriptor.getErasedUpperBound( * So we should substitute erasure of the corresponding type parameter: `Foo, Any>` or `Foo, *>`. */ val erasedUpperBounds = defaultType.extractTypeParametersFromUpperBounds(typeAttr.upperBoundOfTypeParameter).associate { - it.typeConstructor to RawSubstitution.computeProjection( - this, - // if erasure happens due to invalid arguments number, use star projections instead - if (isRaw) typeAttr else typeAttr.withFlexibility(INFLEXIBLE), - it.getErasedUpperBound(isRaw, typeAttr) - ) + val boundProjection = if (it !== typeAttr.upperBoundOfTypeParameter) { + RawSubstitution.computeProjection( + it, + // if erasure happens due to invalid arguments number, use star projections instead + if (isRaw) typeAttr else typeAttr.withFlexibility(INFLEXIBLE), + if (it !== typeAttr.upperBoundOfTypeParameter) it.getErasedUpperBound(isRaw, newTypeAttr) else it.starProjectionType() + ) + } else makeStarProjection(it, typeAttr) + + it.typeConstructor to boundProjection } val erasedUpperBoundsSubstitutor = TypeSubstitutor.create(TypeConstructorSubstitution.createByConstructorsMap(erasedUpperBounds)) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt index ed0127acce3..2f0ba6066cb 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt @@ -232,7 +232,7 @@ private fun KotlinType.containsSelfTypeParameter( val typeParameters = (constructor.declarationDescriptor as? ClassifierDescriptorWithTypeParameters)?.declaredTypeParameters return arguments.withIndex().any { (i, argument) -> - val typeParameter = typeParameters?.get(i) + val typeParameter = typeParameters?.getOrNull(i) if ((typeParameter != null && typeParameter == upperBoundOfTypeParameter) || argument.isStarProjection) return@any false argument.type.containsSelfTypeParameter(baseConstructor, upperBoundOfTypeParameter) }