diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java index 070cd0ebbef..e3cdf592664 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java @@ -1500,6 +1500,12 @@ public class FirLightTreeBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated e runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxInlineCodegenWithIrInlinerTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxInlineCodegenWithIrInlinerTestGenerated.java index 172bc72e67c..de6a0f1f764 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxInlineCodegenWithIrInlinerTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxInlineCodegenWithIrInlinerTestGenerated.java @@ -1500,6 +1500,12 @@ public class FirLightTreeBlackBoxInlineCodegenWithIrInlinerTestGenerated extends runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java index 7b852be5e75..012c33be6cc 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1500,6 +1500,12 @@ public class FirLightTreeSerializeCompileKotlinAgainstInlineKotlinTestGenerated runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java index 768e12ffede..f879f554bc5 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java @@ -1500,6 +1500,12 @@ public class FirPsiBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated extends runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxInlineCodegenWithIrInlinerTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxInlineCodegenWithIrInlinerTestGenerated.java index 2a6a160ffdd..09ae6fece93 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxInlineCodegenWithIrInlinerTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxInlineCodegenWithIrInlinerTestGenerated.java @@ -1500,6 +1500,12 @@ public class FirPsiBlackBoxInlineCodegenWithIrInlinerTestGenerated extends Abstr runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java index b03f4a15f82..1503562bcfc 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1500,6 +1500,12 @@ public class FirPsiSerializeCompileKotlinAgainstInlineKotlinTestGenerated extend runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt index 1dccf4dc86a..bd3c298d560 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt @@ -726,23 +726,42 @@ class FunctionInlining( } // In short this is needed for `kt44429` test. We need to get original generic type to trick type system on JVM backend. + // Probably this it is relevant only for numeric types in JVM. private fun IrValueParameter.getOriginalType(): IrType { if (this.parent !is IrFunction) return type - val callee = this.parent as IrFunction - val original = callee.originalFunction + val copy = this.parent as IrFunction // contains substituted type parameters with corresponding type arguments + val original = copy.originalFunction // contains original unsubstituted type parameters + + // Note 1: the following method will replace super types fow the owner type parameter. So in every other IrSimpleType that + // refers this type parameter we will see substituted values. This should not be a problem because earlier we replace all type + // parameters with corresponding type arguments. + // Note 2: this substitution can be dropped if we will learn how to copy IR function and leave its type parameters as they are. + // But this sounds a little complicated. + fun IrType.substituteSuperTypes(): IrType { + val typeClassifier = this.classifierOrNull?.owner as? IrTypeParameter ?: return this + typeClassifier.superTypes = original.typeParameters[typeClassifier.index].superTypes.map { + val superTypeClassifier = it.classifierOrNull?.owner as? IrTypeParameter ?: return@map it + copy.typeParameters[superTypeClassifier.index].defaultType.substituteSuperTypes() + } + return this + } fun IrValueParameter?.getTypeIfFromTypeParameter(): IrType? { val typeClassifier = this?.type?.classifierOrNull?.owner as? IrTypeParameter ?: return null if (typeClassifier.parent != this.parent) return null - return callee.typeParameters[typeClassifier.index].defaultType + + // We take type parameter from copied callee and not from original because we need an actual copy. Without this copy, + // in case of recursive call, we can get a situation there the same type parameter will be mapped on different type arguments. + // (see compiler/testData/codegen/boxInline/complex/use.kt test file) + return copy.typeParameters[typeClassifier.index].defaultType.substituteSuperTypes() } return when (this) { - callee.dispatchReceiverParameter -> original.dispatchReceiverParameter?.getTypeIfFromTypeParameter() - ?: callee.dispatchReceiverParameter!!.type - callee.extensionReceiverParameter -> original.extensionReceiverParameter?.getTypeIfFromTypeParameter() - ?: callee.extensionReceiverParameter!!.type - else -> callee.valueParameters.first { it == this }.let { valueParameter -> + copy.dispatchReceiverParameter -> original.dispatchReceiverParameter?.getTypeIfFromTypeParameter() + ?: copy.dispatchReceiverParameter!!.type + copy.extensionReceiverParameter -> original.extensionReceiverParameter?.getTypeIfFromTypeParameter() + ?: copy.extensionReceiverParameter!!.type + else -> copy.valueParameters.first { it == this }.let { valueParameter -> original.valueParameters[valueParameter.index].getTypeIfFromTypeParameter() ?: valueParameter.type } diff --git a/compiler/testData/codegen/boxInline/complex/kt44429.kt b/compiler/testData/codegen/boxInline/complex/kt44429.kt index 9caba471659..950194e484b 100644 --- a/compiler/testData/codegen/boxInline/complex/kt44429.kt +++ b/compiler/testData/codegen/boxInline/complex/kt44429.kt @@ -5,6 +5,10 @@ package test inline fun takeT(t: T) {} +inline fun takeTSuperAny(t: T) {} +inline fun takeU(u: U) {} +inline fun takeR(r: R) {} +inline fun >> takeTWithMap(t: T) {} // FILE: 2.kt import test.* @@ -12,5 +16,14 @@ import test.* fun box(): String { val f = { null } as () -> Int takeT(f()) + // Without fix we are going to get following instructions + // CHECKCAST java/lang/Number + // INVOKEVIRTUAL java/lang/Number.intValue ()I // <- this one leads to NPE + takeTSuperAny(f()) + takeU(f()) + takeR(f()) + + val g = { null } as () -> Map> + takeTWithMap(g()) return "OK" } diff --git a/compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt b/compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt new file mode 100644 index 00000000000..cf2ee01be13 --- /dev/null +++ b/compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt @@ -0,0 +1,29 @@ +// TARGET_BACKEND: JVM +// NO_CHECK_LAMBDA_INLINING +// FILE: 1.kt +package test + +// Following examples expected to fail +inline fun takeTFail(t: T) {} +inline fun takeUSuperInt(u: U) {} + +// FILE: 2.kt +import test.* + +inline fun assertThrows(block: () -> Unit) { + try { + block.invoke() + } catch (t: Throwable) { + if (t is T) return + throw t + } + throw AssertionError("Exception was expected") +} + +fun box(): String { + val f = { null } as () -> Int + + assertThrows { takeTFail(f()) } + assertThrows { takeUSuperInt(f()) } + return "OK" +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java index f0ef560a663..0047e419aa2 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -1476,6 +1476,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 86d4be32a3b..8782b4357ef 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1476,6 +1476,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java index 5fec7762103..ead57a67ba2 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated.java @@ -1500,6 +1500,12 @@ public class IrBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated extends Abs runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenWithIrInlinerTestGenerated.java index f443f05a958..3d167c5f1e8 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenWithIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenWithIrInlinerTestGenerated.java @@ -1500,6 +1500,12 @@ public class IrBlackBoxInlineCodegenWithIrInlinerTestGenerated extends AbstractI runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index b862bb147a5..070ab002587 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1500,6 +1500,12 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java index f4ece48c213..23940c5c30b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrSerializeCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1500,6 +1500,12 @@ public class IrSerializeCompileKotlinAgainstInlineKotlinTestGenerated extends Ab runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java index 125413e23cb..342db44029c 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java @@ -1500,6 +1500,12 @@ public class JvmIrAgainstOldBoxInlineTestGenerated extends AbstractJvmIrAgainstO runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java index b9c8ff492bc..b88338c8a03 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java @@ -1476,6 +1476,12 @@ public class JvmOldAgainstIrBoxInlineTestGenerated extends AbstractJvmOldAgainst runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt"); } + @Test + @TestMetadata("kt44429MustFail.kt") + public void testKt44429MustFail() throws Exception { + runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt"); + } + @Test @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception {