Process raw types during erasion properly
^KT-46670 Fixed ^KT-46476 Fixed
This commit is contained in:
+6
@@ -21304,6 +21304,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/substituteSeveralOtherErasedTypeArguments.kt");
|
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
|
@Test
|
||||||
@TestMetadata("typeEnhancement.kt")
|
@TestMetadata("typeEnhancement.kt")
|
||||||
public void testTypeEnhancement() throws Exception {
|
public void testTypeEnhancement() throws Exception {
|
||||||
|
|||||||
+6
@@ -21304,6 +21304,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/substituteSeveralOtherErasedTypeArguments.kt");
|
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
|
@Test
|
||||||
@TestMetadata("typeEnhancement.kt")
|
@TestMetadata("typeEnhancement.kt")
|
||||||
public void testTypeEnhancement() throws Exception {
|
public void testTypeEnhancement() throws Exception {
|
||||||
|
|||||||
+12
@@ -27248,6 +27248,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/platformTypes/kt14989.kt");
|
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
|
@Test
|
||||||
@TestMetadata("specializedMapFull.kt")
|
@TestMetadata("specializedMapFull.kt")
|
||||||
public void testSpecializedMapFull() throws Exception {
|
public void testSpecializedMapFull() throws Exception {
|
||||||
@@ -27260,6 +27266,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/platformTypes/specializedMapPut.kt");
|
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
|
@Test
|
||||||
@TestMetadata("unsafeNullCheck.kt")
|
@TestMetadata("unsafeNullCheck.kt")
|
||||||
public void testUnsafeNullCheck() throws Exception {
|
public void testUnsafeNullCheck() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
|
||||||
|
// FILE: OCNewFileActionBase.java
|
||||||
|
public class OCNewFileActionBase<T extends OCNewFileActionBase<T>.CreateFileDialogBase> {
|
||||||
|
public class CreateFileDialogBase { }
|
||||||
|
|
||||||
|
static OCNewFileActionBase get() { return new OCNewFileActionBase(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
fun box(): String {
|
||||||
|
// Before changes in raw types computation: (OCNewFileActionBase<OCNewFileActionBase<*>.CreateFileDialogBase!>..OCNewFileActionBase<out OCNewFileActionBase<*>.CreateFileDialogBase!>?)
|
||||||
|
// After that: raw (OCNewFileActionBase<*>..OCNewFileActionBase<*>?)
|
||||||
|
val x = OCNewFileActionBase.get()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// FILE: AbstractMessageLite.java
|
||||||
|
|
||||||
|
public abstract class AbstractMessageLite<
|
||||||
|
MessageType extends AbstractMessageLite<MessageType, BuilderType>,
|
||||||
|
BuilderType extends AbstractMessageLite.Builder<MessageType, BuilderType>>
|
||||||
|
{
|
||||||
|
public void writeDelimitedTo() {}
|
||||||
|
|
||||||
|
public abstract static class Builder<
|
||||||
|
MessageType extends AbstractMessageLite<MessageType, BuilderType>,
|
||||||
|
BuilderType extends Builder<MessageType, BuilderType>>
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: H.java
|
||||||
|
public class H extends AbstractMessageLite {}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
fun f(h: H) {
|
||||||
|
h.writeDelimitedTo()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
f(H())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
Vendored
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun f(/*0*/ h: H): kotlin.Unit
|
||||||
|
|
||||||
|
public abstract class AbstractMessageLite</*0*/ MessageType : AbstractMessageLite<MessageType!, BuilderType!>!, /*1*/ BuilderType : AbstractMessageLite.Builder<MessageType!, BuilderType!>!> {
|
||||||
|
public constructor AbstractMessageLite</*0*/ MessageType : AbstractMessageLite<MessageType!, BuilderType!>!, /*1*/ BuilderType : AbstractMessageLite.Builder<MessageType!, BuilderType!>!>()
|
||||||
|
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</*0*/ MessageType : AbstractMessageLite<MessageType!, BuilderType!>!, /*1*/ BuilderType : AbstractMessageLite.Builder<MessageType!, BuilderType!>!> {
|
||||||
|
public constructor Builder</*0*/ MessageType : AbstractMessageLite<MessageType!, BuilderType!>!, /*1*/ BuilderType : AbstractMessageLite.Builder<MessageType!, BuilderType!>!>()
|
||||||
|
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
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// FILE: Test.java
|
||||||
|
class BaseOperation<T extends Bar, L extends Foo<T>> {}
|
||||||
|
|
||||||
|
class Foo<E extends Bar> { }
|
||||||
|
|
||||||
|
class Bar {}
|
||||||
|
|
||||||
|
public class Test extends BaseOperation {}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
fun main() {
|
||||||
|
val x = Test()
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(): kotlin.Unit
|
||||||
|
|
||||||
|
public open class Test : BaseOperation<(raw) Bar!, (raw) Foo<Bar!>!> {
|
||||||
|
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
|
||||||
|
}
|
||||||
Generated
+6
@@ -21310,6 +21310,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/substituteSeveralOtherErasedTypeArguments.kt");
|
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
|
@Test
|
||||||
@TestMetadata("typeEnhancement.kt")
|
@TestMetadata("typeEnhancement.kt")
|
||||||
public void testTypeEnhancement() throws Exception {
|
public void testTypeEnhancement() throws Exception {
|
||||||
|
|||||||
+12
@@ -27224,6 +27224,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/platformTypes/kt14989.kt");
|
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
|
@Test
|
||||||
@TestMetadata("specializedMapFull.kt")
|
@TestMetadata("specializedMapFull.kt")
|
||||||
public void testSpecializedMapFull() throws Exception {
|
public void testSpecializedMapFull() throws Exception {
|
||||||
@@ -27236,6 +27242,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/platformTypes/specializedMapPut.kt");
|
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
|
@Test
|
||||||
@TestMetadata("unsafeNullCheck.kt")
|
@TestMetadata("unsafeNullCheck.kt")
|
||||||
public void testUnsafeNullCheck() throws Exception {
|
public void testUnsafeNullCheck() throws Exception {
|
||||||
|
|||||||
+12
@@ -27248,6 +27248,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/platformTypes/kt14989.kt");
|
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
|
@Test
|
||||||
@TestMetadata("specializedMapFull.kt")
|
@TestMetadata("specializedMapFull.kt")
|
||||||
public void testSpecializedMapFull() throws Exception {
|
public void testSpecializedMapFull() throws Exception {
|
||||||
@@ -27260,6 +27266,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/platformTypes/specializedMapPut.kt");
|
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
|
@Test
|
||||||
@TestMetadata("unsafeNullCheck.kt")
|
@TestMetadata("unsafeNullCheck.kt")
|
||||||
public void testUnsafeNullCheck() throws Exception {
|
public void testUnsafeNullCheck() throws Exception {
|
||||||
|
|||||||
+10
@@ -23096,6 +23096,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/platformTypes/kt14989.kt");
|
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")
|
@TestMetadata("specializedMapFull.kt")
|
||||||
public void testSpecializedMapFull() throws Exception {
|
public void testSpecializedMapFull() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/platformTypes/specializedMapFull.kt");
|
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");
|
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")
|
@TestMetadata("unsafeNullCheck.kt")
|
||||||
public void testUnsafeNullCheck() throws Exception {
|
public void testUnsafeNullCheck() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt");
|
runTest("compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt");
|
||||||
|
|||||||
+13
-6
@@ -315,6 +315,7 @@ data class JavaTypeAttributes(
|
|||||||
val upperBoundOfTypeParameter: TypeParameterDescriptor? = null
|
val upperBoundOfTypeParameter: TypeParameterDescriptor? = null
|
||||||
) {
|
) {
|
||||||
fun withFlexibility(flexibility: JavaTypeFlexibility) = copy(flexibility = flexibility)
|
fun withFlexibility(flexibility: JavaTypeFlexibility) = copy(flexibility = flexibility)
|
||||||
|
fun withTypeParameter(upperBoundOfTypeParameter: TypeParameterDescriptor) = copy(upperBoundOfTypeParameter = upperBoundOfTypeParameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class JavaTypeFlexibility {
|
enum class JavaTypeFlexibility {
|
||||||
@@ -346,6 +347,8 @@ internal fun TypeParameterDescriptor.getErasedUpperBound(
|
|||||||
): KotlinType {
|
): KotlinType {
|
||||||
if (this === typeAttr.upperBoundOfTypeParameter) return defaultValue()
|
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.
|
* We should do erasure of containing type parameters with their erasure to avoid creating inconsistent types.
|
||||||
* E.g. for `class Foo<T: Foo<B>, B>`, we'd have erasure for lower bound: Foo<Foo<*>, Any>,
|
* E.g. for `class Foo<T: Foo<B>, B>`, we'd have erasure for lower bound: Foo<Foo<*>, Any>,
|
||||||
@@ -353,12 +356,16 @@ internal fun TypeParameterDescriptor.getErasedUpperBound(
|
|||||||
* So we should substitute erasure of the corresponding type parameter: `Foo<Foo<Any>, Any>` or `Foo<Foo<*>, *>`.
|
* So we should substitute erasure of the corresponding type parameter: `Foo<Foo<Any>, Any>` or `Foo<Foo<*>, *>`.
|
||||||
*/
|
*/
|
||||||
val erasedUpperBounds = defaultType.extractTypeParametersFromUpperBounds(typeAttr.upperBoundOfTypeParameter).associate {
|
val erasedUpperBounds = defaultType.extractTypeParametersFromUpperBounds(typeAttr.upperBoundOfTypeParameter).associate {
|
||||||
it.typeConstructor to RawSubstitution.computeProjection(
|
val boundProjection = if (it !== typeAttr.upperBoundOfTypeParameter) {
|
||||||
this,
|
RawSubstitution.computeProjection(
|
||||||
// if erasure happens due to invalid arguments number, use star projections instead
|
it,
|
||||||
if (isRaw) typeAttr else typeAttr.withFlexibility(INFLEXIBLE),
|
// if erasure happens due to invalid arguments number, use star projections instead
|
||||||
it.getErasedUpperBound(isRaw, typeAttr)
|
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))
|
val erasedUpperBoundsSubstitutor = TypeSubstitutor.create(TypeConstructorSubstitution.createByConstructorsMap(erasedUpperBounds))
|
||||||
|
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ private fun KotlinType.containsSelfTypeParameter(
|
|||||||
|
|
||||||
val typeParameters = (constructor.declarationDescriptor as? ClassifierDescriptorWithTypeParameters)?.declaredTypeParameters
|
val typeParameters = (constructor.declarationDescriptor as? ClassifierDescriptorWithTypeParameters)?.declaredTypeParameters
|
||||||
return arguments.withIndex().any { (i, argument) ->
|
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
|
if ((typeParameter != null && typeParameter == upperBoundOfTypeParameter) || argument.isStarProjection) return@any false
|
||||||
argument.type.containsSelfTypeParameter(baseConstructor, upperBoundOfTypeParameter)
|
argument.type.containsSelfTypeParameter(baseConstructor, upperBoundOfTypeParameter)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user