From 2f0f4e570f1ca2cdb5f879bcc0e7324e7c01e344 Mon Sep 17 00:00:00 2001 From: pyos Date: Mon, 23 Dec 2019 14:32:13 +0100 Subject: [PATCH] JVM_IR: do not remap locals in contexts nested inside lambdas The only case where this code is reachable at all is objects in lambdas that use reified type parameters of the outer inline function. Since the type parameters are declared outside the inlining root, regenerating the object is actually pointless, and remapping its captures even more so (not to mention that the code under the condition uses the captures of the lambda, not of the method it's currently transforming). --- .../kotlin/codegen/inline/MethodInliner.kt | 2 +- .../reified/nonCapturingObjectInLambda.kt | 19 +++++++++++++++++++ .../BlackBoxInlineCodegenTestGenerated.java | 5 +++++ ...otlinAgainstInlineKotlinTestGenerated.java | 5 +++++ .../IrBlackBoxInlineCodegenTestGenerated.java | 5 +++++ ...otlinAgainstInlineKotlinTestGenerated.java | 5 +++++ 6 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index b83616cc7cc..127b6fe047b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -911,7 +911,7 @@ class MethodInliner( return } - if (inliningContext.isInliningLambda && inliningContext.lambdaInfo is IrExpressionLambda) { + if (inliningContext.isInliningLambda && inliningContext.lambdaInfo is IrExpressionLambda && !inliningContext.parent!!.isInliningLambda) { val capturedVars = inliningContext.lambdaInfo.capturedVars var offset = parameters.realParametersSizeOnStack val map = capturedVars.map { diff --git a/compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt b/compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt new file mode 100644 index 00000000000..5a19cee2ef5 --- /dev/null +++ b/compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt @@ -0,0 +1,19 @@ +// FILE: 1.kt +package test + +inline fun myRun(g: () -> R) = g() + +// FILE: 2.kt +import test.* + +inline fun Any?.complicatedCast() = + myRun { // 1. Inline function call with a lambda + object { // 2. Anonymous object inside a lambda + fun f(x: Any?): A { // 3. Anonymous object uses a reified type parameter + val y = x // 4. A method in that object uses locals + return y as A + } + }.f(this) // 5. The lambda captures more values than the object + } + +fun box() = "OK".complicatedCast() diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index 8646e2263a6..48acede9975 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -2880,6 +2880,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt"); } + @TestMetadata("nonCapturingObjectInLambda.kt") + public void testNonCapturingObjectInLambda() throws Exception { + runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt"); + } + @TestMetadata("packages.kt") public void testPackages() throws Exception { runTest("compiler/testData/codegen/boxInline/reified/packages.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 58468ce4322..3520d9a146a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -2880,6 +2880,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt"); } + @TestMetadata("nonCapturingObjectInLambda.kt") + public void testNonCapturingObjectInLambda() throws Exception { + runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt"); + } + @TestMetadata("packages.kt") public void testPackages() throws Exception { runTest("compiler/testData/codegen/boxInline/reified/packages.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index 02ee3ea33ce..0ae113306b6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -2880,6 +2880,11 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt"); } + @TestMetadata("nonCapturingObjectInLambda.kt") + public void testNonCapturingObjectInLambda() throws Exception { + runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt"); + } + @TestMetadata("packages.kt") public void testPackages() throws Exception { runTest("compiler/testData/codegen/boxInline/reified/packages.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index 2401d19e945..0fe1a12ee31 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -2880,6 +2880,11 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt"); } + @TestMetadata("nonCapturingObjectInLambda.kt") + public void testNonCapturingObjectInLambda() throws Exception { + runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt"); + } + @TestMetadata("packages.kt") public void testPackages() throws Exception { runTest("compiler/testData/codegen/boxInline/reified/packages.kt");