Fix non-suspending labeled loop in suspend function

Fix bug when labeled loop, which does not contain suspend calls
in its body, was losing its label
This commit is contained in:
Alexey Andreev
2017-04-27 17:37:17 +03:00
parent 6047746c90
commit c8c3d24b45
6 changed files with 82 additions and 1 deletions
@@ -0,0 +1,50 @@
// IGNORE_BACKEND: NATIVE
// WITH_RUNTIME
// WITH_COROUTINES
import kotlin.coroutines.experimental.*
import kotlin.coroutines.experimental.intrinsics.*
fun builder(c: suspend () -> Unit): Unit {
c.startCoroutine(handleResultContinuation {
finished = true
})
}
fun box(): String {
builder {
var i = 0
var j = 0
outer@while (i < 10) {
while (j < 10) {
if (i + j > 3) break@outer
log += "$i,$j;"
suspendAndContinue()
j++
}
log += "i++;"
i++
}
log += "done;"
suspendAndContinue()
}
while (!finished) {
log += "@;"
postponed()
}
if (log != "0,0;@;0,1;@;0,2;@;0,3;@;done;@;") return "fail: $log"
return "OK"
}
suspend fun suspendAndContinue(): Unit = suspendCoroutineOrReturn { c ->
postponed = {
c.resume(Unit)
}
COROUTINE_SUSPENDED
}
var postponed: () -> Unit = {}
var finished = false
var log = ""
@@ -5362,6 +5362,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("labeledWhile.kt")
public void testLabeledWhile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/labeledWhile.kt");
doTest(fileName);
}
@TestMetadata("returnFromFinally.kt")
public void testReturnFromFinally() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
@@ -5362,6 +5362,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("labeledWhile.kt")
public void testLabeledWhile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/labeledWhile.kt");
doTest(fileName);
}
@TestMetadata("returnFromFinally.kt")
public void testReturnFromFinally() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
@@ -5362,6 +5362,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
doTest(fileName);
}
@TestMetadata("labeledWhile.kt")
public void testLabeledWhile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/labeledWhile.kt");
doTest(fileName);
}
@TestMetadata("returnFromFinally.kt")
public void testReturnFromFinally() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
@@ -93,7 +93,14 @@ class CoroutineBodyTransformer(private val program: JsProgram, private val conte
when (inner) {
is JsWhile,
is JsDoWhile,
is JsFor -> inner.accept(this)
is JsFor -> {
if (x in nodesToSplit) {
inner.accept(this)
}
else {
currentStatements += x
}
}
else -> splitIfNecessary(x) {
val successor = CoroutineBlock()
@@ -6077,6 +6077,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("labeledWhile.kt")
public void testLabeledWhile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/labeledWhile.kt");
doTest(fileName);
}
@TestMetadata("returnFromFinally.kt")
public void testReturnFromFinally() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");