diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index c8003444dce..55e5413c3af 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -1735,6 +1735,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/regressions/typeAliasCtorForGenericClass.kt"); } + @TestMetadata("typeParametersInImplicitCast.kt") + public void testTypeParametersInImplicitCast() throws Exception { + runTest("compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.kt"); + } + @TestMetadata("compiler/testData/ir/irText/regressions/newInference") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index 4f3d6297395..45778d8518e 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -36,6 +36,8 @@ import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.coerceToUnit import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.psi2ir.containsNull import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext @@ -64,19 +66,37 @@ internal class InsertImplicitCasts( ) : IrElementTransformerVoid() { private val expectedFunctionExpressionReturnType = hashMapOf() - private val returnExpressionsToBePostprocessed = arrayListOf() fun run(element: IrElement) { element.transformChildrenVoid(this) - for (irReturn in returnExpressionsToBePostprocessed) { - postprocessReturnExpression(irReturn) - } + postprocessReturnExpressions(element) } - private fun postprocessReturnExpression(irReturn: IrReturn) { - val returnTarget = irReturn.returnTarget - val expectedReturnType = expectedFunctionExpressionReturnType[returnTarget] ?: return - irReturn.value = irReturn.value.cast(expectedReturnType) + private fun postprocessReturnExpressions(element: IrElement) { + // We need to re-create type parameter context for casts of postprocessed return values. + element.acceptChildrenVoid(object : IrElementVisitorVoid { + override fun visitReturn(expression: IrReturn) { + super.visitReturn(expression) + val expectedReturnType = expectedFunctionExpressionReturnType[expression.returnTarget] ?: return + expression.value = expression.value.cast(expectedReturnType) + } + + override fun visitClass(declaration: IrClass) { + typeTranslator.buildWithScope(declaration) { + super.visitClass(declaration) + } + } + + override fun visitFunction(declaration: IrFunction) { + typeTranslator.buildWithScope(declaration) { + super.visitFunction(declaration) + } + } + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + }) } private fun KotlinType.toIrType() = typeTranslator.translateType(this) @@ -172,9 +192,6 @@ internal class InsertImplicitCasts( } else { val returnTargetDescriptor = expression.returnTarget val isLambdaReturnValue = returnTargetDescriptor is AnonymousFunctionDescriptor - if (isLambdaReturnValue) { - returnExpressionsToBePostprocessed.add(expression) - } value.cast(returnTargetDescriptor.returnType, isLambdaReturnValue = isLambdaReturnValue) } } diff --git a/compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.fir.txt b/compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.fir.txt new file mode 100644 index 00000000000..ba120065e3f --- /dev/null +++ b/compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.fir.txt @@ -0,0 +1,18 @@ +FILE fqName: fileName:/typeParametersInImplicitCast.kt + FUN name:problematic visibility:public modality:FINAL (lss:kotlin.collections.List.problematic>>) returnType:kotlin.collections.List.problematic> + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:lss index:0 type:kotlin.collections.List.problematic>> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun problematic (lss: kotlin.collections.List.problematic>>): kotlin.collections.List.problematic> declared in ' + CALL 'public final fun flatMap (transform: kotlin.Function1>): kotlin.collections.List [inline] declared in kotlin.collections' type=kotlin.collections.List.problematic> origin=null + : kotlin.collections.List.problematic> + : T of .problematic + $receiver: GET_VAR 'lss: kotlin.collections.List.problematic>> declared in .problematic' type=kotlin.collections.List.problematic>> origin=null + transform: FUN_EXPR type=kotlin.Function1.problematic>, kotlin.collections.Iterable.problematic>> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.collections.List.problematic>) returnType:kotlin.collections.Iterable.problematic> + VALUE_PARAMETER name:it index:0 type:kotlin.collections.List.problematic> + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.collections.List.problematic>): kotlin.collections.Iterable.problematic> declared in .problematic' + CALL 'public/*package*/ open fun id (v: kotlin.collections.List.ListId.id?>?): kotlin.collections.List.ListId.id?> declared in .ListId' type=kotlin.collections.List.problematic?> origin=null + : T of .problematic? + v: GET_VAR 'it: kotlin.collections.List.problematic> declared in .problematic.' type=kotlin.collections.List.problematic> origin=null diff --git a/compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.kt b/compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.kt new file mode 100644 index 00000000000..89b2403d796 --- /dev/null +++ b/compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME +// FILE: ListId.java +import java.util.List; +import org.jetbrains.annotations.NotNull; + +class ListId { + @NotNull + static List id(List v) { + return v; + } +} + +// FILE: typeParametersInImplicitCast.kt + +fun problematic(lss: List>): List = lss.flatMap { ListId.id(it) } diff --git a/compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.txt b/compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.txt new file mode 100644 index 00000000000..1fc9ec34a5b --- /dev/null +++ b/compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.txt @@ -0,0 +1,19 @@ +FILE fqName: fileName:/typeParametersInImplicitCast.kt + FUN name:problematic visibility:public modality:FINAL (lss:kotlin.collections.List.problematic>>) returnType:kotlin.collections.List.problematic> + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:lss index:0 type:kotlin.collections.List.problematic>> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun problematic (lss: kotlin.collections.List.problematic>>): kotlin.collections.List.problematic> declared in ' + CALL 'public final fun flatMap (transform: kotlin.Function1>): kotlin.collections.List [inline] declared in kotlin.collections' type=kotlin.collections.List.problematic?> origin=null + : kotlin.collections.List.problematic> + : T of .problematic? + $receiver: GET_VAR 'lss: kotlin.collections.List.problematic>> declared in .problematic' type=kotlin.collections.List.problematic>> origin=null + transform: FUN_EXPR type=kotlin.Function1.problematic>, kotlin.collections.Iterable.problematic?>> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.collections.List.problematic>) returnType:kotlin.collections.Iterable.problematic?> + VALUE_PARAMETER name:it index:0 type:kotlin.collections.List.problematic> + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.collections.List.problematic>): kotlin.collections.Iterable.problematic?> declared in .problematic' + TYPE_OP type=kotlin.collections.List.problematic?> origin=IMPLICIT_NOTNULL typeOperand=kotlin.collections.List.problematic?> + CALL 'public/*package*/ open fun id (v: kotlin.collections.List.ListId.id?>?): kotlin.collections.List.ListId.id?> declared in .ListId' type=kotlin.collections.List.problematic?> origin=null + : T of .problematic? + v: GET_VAR 'it: kotlin.collections.List.problematic> declared in .problematic.' type=kotlin.collections.List.problematic> origin=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 8796f093a1a..008897fe206 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1734,6 +1734,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/regressions/typeAliasCtorForGenericClass.kt"); } + @TestMetadata("typeParametersInImplicitCast.kt") + public void testTypeParametersInImplicitCast() throws Exception { + runTest("compiler/testData/ir/irText/regressions/typeParametersInImplicitCast.kt"); + } + @TestMetadata("compiler/testData/ir/irText/regressions/newInference") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)