diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index 50b76f52d21..5f739b05b87 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -783,13 +783,15 @@ class CoroutineTransformerMethodVisitor( // See 'splitTryCatchBlocksContainingSuspensionPoint' val possibleTryCatchBlockStart = suspension.tryCatchBlocksContinuationLabel - // Remove NOP as it's unnecessary anymore + // Move NOP, which is inserted in `splitTryCatchBlocksContainingSuspentionPoint`, inside the try catch block, + // so the inliner can transform suspend lambdas during inlining assert(possibleTryCatchBlockStart.previous.opcode == Opcodes.NOP) { "NOP expected but ${possibleTryCatchBlockStart.previous.opcode} was found" } remove(possibleTryCatchBlockStart.previous) insert(possibleTryCatchBlockStart, withInstructionAdapter { + nop() generateResumeWithExceptionCheck(languageVersionSettings.isReleaseCoroutines(), dataIndex, exceptionIndex) // Load continuation argument just like suspending function returns it diff --git a/compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt b/compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt new file mode 100644 index 00000000000..fafeea1c713 --- /dev/null +++ b/compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt @@ -0,0 +1,50 @@ +// FILE: test.kt +// WITH_RUNTIME +// WITH_COROUTINES +// CHECK_STATE_MACHINE +// NO_CHECK_LAMBDA_INLINING + +import helpers.* +import kotlin.coroutines.* + +const val DEBUG = false +inline fun inlineFun(b: () -> Unit) { + if (DEBUG) { + inlineFunReal(b) + } +} + +inline fun inlineFunReal(b: () -> Unit) { + try { + b() + } finally { + } +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(CheckStateMachineContinuation) +} + +// FILE: box.kt +import helpers.* + +class Sample { + fun test() { + inlineFun { + builder { + inlineFun { + suspendFun() + suspendFun() + } + } + } + } + + suspend fun suspendFun() = StateMachineChecker.suspendHere() +} + +fun box(): String { + Sample().test() + StateMachineChecker.check(0, checkFinished = false) + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/coroutineTestUtil.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/coroutineTestUtil.kt index 2b8ccbeef22..71dea34368b 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/coroutineTestUtil.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/coroutineTestUtil.kt @@ -94,7 +94,7 @@ fun createTextForHelpers(isReleaseCoroutines: Boolean, checkStateMachine: Boolea proceed = { c.resume(Unit) } } - fun check(numberOfSuspensions: Int) { + fun check(numberOfSuspensions: Int, checkFinished: Boolean = true) { for (i in 1..numberOfSuspensions) { if (counter != i) error("Wrong state-machine generated: suspendHere should be called exactly once in one state. Expected " + i + ", got " + counter) proceed() @@ -103,7 +103,7 @@ fun createTextForHelpers(isReleaseCoroutines: Boolean, checkStateMachine: Boolea error("Wrong state-machine generated: wrong number of overall suspensions. Expected " + numberOfSuspensions + ", got " + counter) if (finished) error("Wrong state-machine generated: it is finished early") proceed() - if (!finished) error("Wrong state-machine generated: it is not finished yet") + if (checkFinished && !finished) error("Wrong state-machine generated: it is not finished yet") } } val StateMachineChecker = StateMachineCheckerClass() diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index d302c41b8f5..9415e7831f9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -4089,6 +4089,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); } + @TestMetadata("lambdaTransformation.kt") + public void testLambdaTransformation() throws Exception { + runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 64fd496b5c4..33985182dac 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -4089,6 +4089,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); } + @TestMetadata("lambdaTransformation.kt") + public void testLambdaTransformation() throws Exception { + runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index 59da71a0256..a5f339617d3 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -3879,6 +3879,11 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); } + @TestMetadata("lambdaTransformation.kt") + public void testLambdaTransformation() throws Exception { + runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index 9423f89a1e4..d3e5024f815 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -3879,6 +3879,11 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); } + @TestMetadata("lambdaTransformation.kt") + public void testLambdaTransformation() throws Exception { + runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java index 527d88209b6..b38eed6c39d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java @@ -329,6 +329,11 @@ public class IrInlineSuspendTestsGenerated extends AbstractIrInlineSuspendTests runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); } + @TestMetadata("lambdaTransformation.kt") + public void testLambdaTransformation() throws Exception { + runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java index c036b30bfbe..bccff50baf5 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java @@ -529,6 +529,11 @@ public class InlineSuspendTestsGenerated extends AbstractInlineSuspendTests { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); } + @TestMetadata("lambdaTransformation.kt") + public void testLambdaTransformation() throws Exception { + runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental");