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");
|
||||
}
|
||||
|
||||
@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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+12
@@ -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 {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@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 {
|
||||
|
||||
+12
@@ -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 {
|
||||
|
||||
+12
@@ -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 {
|
||||
|
||||
+10
@@ -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");
|
||||
|
||||
+13
-6
@@ -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<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<*>, *>`.
|
||||
*/
|
||||
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))
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user