From 58bac6882dadb435a92ded6f6aefd86e931725aa Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Fri, 23 Mar 2018 19:57:20 +0300 Subject: [PATCH] Fix transforming of coroutine's create when it is suspend lambda with receiver Unlike ordinary lambdas suspend lambdas has create method which invokes the constructor of the lambda object (continuation). The inliner could not cope with this. The previous change fixed the case of suspend lambda without receiver. This change adds support of suspend lambdas with receiver. #KT-21605: Fixed --- .../kotlin/codegen/inline/MethodInliner.kt | 4 +-- .../codegen/box/coroutines/kt21605.kt | 33 +++++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 ++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++ .../LightAnalysisModeTestGenerated.java | 6 ++++ .../semantics/JsCodegenBoxTestGenerated.java | 6 ++++ 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/coroutines/kt21605.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 718568ecd75..2b1d142659f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ @@ -291,7 +291,7 @@ class MethodInliner( } val isContinuationCreate = isContinuation && oldInfo != null && resultNode.name == "create" && - resultNode.desc.startsWith("(" + CONTINUATION_ASM_TYPE.descriptor) + resultNode.desc.endsWith(")" + CONTINUATION_ASM_TYPE.descriptor) for (capturedParamDesc in info.allRecapturedParameters) { if (capturedParamDesc.fieldName == THIS && isContinuationCreate) { diff --git a/compiler/testData/codegen/box/coroutines/kt21605.kt b/compiler/testData/codegen/box/coroutines/kt21605.kt new file mode 100644 index 00000000000..8ebd0f0d656 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/kt21605.kt @@ -0,0 +1,33 @@ +// WITH_RUNTIME +// WITH_COROUTINES + +import helpers.* +import kotlin.coroutines.experimental.* + +interface Consumer { fun consume(s: String) } + +inline fun crossInlineBuilder(crossinline block: (String) -> Unit) = object : Consumer { + override fun consume(s: String) { + block(s) + } +} + +fun builder(block: suspend Unit.() -> Unit) { + block.startCoroutine(Unit, EmptyContinuation) +} + +class Container { + var y: String = "FAIL" + + val consumer = crossInlineBuilder { s -> + builder { + y = s + } + } +} + +fun box(): String { + val container = Container() + container.consumer.consume("OK") + return container.y +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 7eede3c52c3..6855b264b92 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5930,6 +5930,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("kt21605.kt") + public void testKt21605() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/kt21605.kt"); + doTest(fileName); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index b8679901eb2..1656e2d424e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5930,6 +5930,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt21605.kt") + public void testKt21605() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/kt21605.kt"); + doTest(fileName); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 2031e0b3986..4244bf6adb4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -5930,6 +5930,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("kt21605.kt") + public void testKt21605() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/kt21605.kt"); + doTest(fileName); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 184c6d24a3e..47bbe38e1d1 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -7249,6 +7249,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("kt21605.kt") + public void testKt21605() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/kt21605.kt"); + doTest(fileName); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt");