[FE 1.0] Create captured star projection for self types by replacing type arguments deeply

^KT-49752 Fixed
This commit is contained in:
Victor Petukhov
2021-11-19 14:42:41 +03:00
parent 6474a90555
commit 61d40403e7
12 changed files with 139 additions and 2 deletions
@@ -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 {
@@ -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,
@@ -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<IrTypeParameter> {
+51
View File
@@ -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<IS, TS, SELF>
where IS : Interpreter.Intermediary<SELF>,
TS : Interpreter.Terminal<SELF>,
SELF : Interpreter<IS, TS, SELF> {
sealed interface Step<INTERPRETER>
where INTERPRETER : Interpreter<out Intermediary<INTERPRETER>, out Terminal<INTERPRETER>, INTERPRETER>
interface Intermediary<INTERPRETER> : Step<INTERPRETER>
where INTERPRETER : Interpreter<out Intermediary<INTERPRETER>, out Terminal<INTERPRETER>, INTERPRETER>
interface Terminal<INTERPRETER> : Step<INTERPRETER>
where INTERPRETER : Interpreter<out Intermediary<INTERPRETER>, out Terminal<INTERPRETER>, INTERPRETER>
abstract fun next(currentStep: IS): () -> Step<SELF>
}
sealed interface BaseTerminal<I : Interpreter<*, out BaseTerminal<I>, I>> : Interpreter.Terminal<I> {
data class Success<I : Interpreter<*, out BaseTerminal<I>, I>>(
val result: Int
) : BaseTerminal<I>
}
class CountingInterpreter : Interpreter<CountingInterpreter.Intermediary, BaseTerminal.Success<CountingInterpreter>, CountingInterpreter>() {
sealed interface Intermediary : Interpreter.Intermediary<CountingInterpreter> {
data class KeepCounting(
val togo: Int
) : Intermediary
}
var count = 0
override fun next(
currentStep: Intermediary
): () -> Step<CountingInterpreter> = {
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> = CountingInterpreter.Intermediary.KeepCounting(1)
while (step is CountingInterpreter.Intermediary) {
step = interpreter.next(step).invoke()
}
return if ((step as BaseTerminal.Success<CountingInterpreter>).result == 1) "OK" else "NOK"
}
@@ -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 {
@@ -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 {
@@ -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");
@@ -177,7 +177,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
fun SimpleTypeMarker.replaceArguments(newArguments: List<TypeArgumentMarker>): 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
@@ -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()
@@ -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 {
@@ -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 {
@@ -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");