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 abf5ff660f7..1406f4491a4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -94,6 +94,8 @@ class CoroutineTransformerMethodVisitor( continuationIndex = methodNode.maxLocals++ prepareMethodNodePreludeForNamedFunction(methodNode) + } else { + ReturnUnitMethodTransformer.cleanUpReturnsUnitMarkers(methodNode, ReturnUnitMethodTransformer.findReturnsUnitMarks(methodNode)) } for (suspensionPoint in suspensionPoints) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/ReturnUnitMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/ReturnUnitMethodTransformer.kt index 13886c84bb1..76a223edf15 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/ReturnUnitMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/ReturnUnitMethodTransformer.kt @@ -124,10 +124,10 @@ object ReturnUnitMethodTransformer : MethodTransformer() { private fun findReturnUnitSequences(methodNode: MethodNode): Collection = methodNode.instructions.asSequence().filter { it.isUnitInstance() && it.next?.opcode == Opcodes.ARETURN }.toList() - private fun findReturnsUnitMarks(methodNode: MethodNode): Collection = + internal fun findReturnsUnitMarks(methodNode: MethodNode): Collection = methodNode.instructions.asSequence().filter(::isReturnsUnitMarker).toList() - private fun cleanUpReturnsUnitMarkers(methodNode: MethodNode, unitMarks: Collection) { + internal fun cleanUpReturnsUnitMarkers(methodNode: MethodNode, unitMarks: Collection) { unitMarks.forEach { methodNode.instructions.removeAll(listOf(it.previous, it)) } } } diff --git a/compiler/testData/codegen/bytecodeText/coroutines/returnUnitInLambda.kt b/compiler/testData/codegen/bytecodeText/coroutines/returnUnitInLambda.kt new file mode 100644 index 00000000000..22deff56f86 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/coroutines/returnUnitInLambda.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME +// WITH_COROUTINES + +import helpers.* +import kotlin.coroutines.experimental.* +import kotlin.coroutines.experimental.intrinsics.* +// TREAT_AS_ONE_FILE + +var res = "FAIL" + +suspend fun suspendHere() = suspendCoroutineOrReturn { + res = "OK" + it.resume(Unit) + COROUTINE_SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box() : String { + builder { + suspendHere() + } + return res +} + +// 0 ICONST_2 +// 0 ICONST_3 \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 51cf3427e8c..2d3abe67339 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1137,6 +1137,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("returnUnitInLambda.kt") + public void testReturnUnitInLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/coroutines/returnUnitInLambda.kt"); + doTest(fileName); + } + @TestMetadata("varValueConflictsWithTable.kt") public void testVarValueConflictsWithTable() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTable.kt");