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:
@@ -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 = ""
|
||||||
+6
@@ -5362,6 +5362,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("returnFromFinally.kt")
|
||||||
public void testReturnFromFinally() throws Exception {
|
public void testReturnFromFinally() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
|
||||||
|
|||||||
@@ -5362,6 +5362,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("returnFromFinally.kt")
|
||||||
public void testReturnFromFinally() throws Exception {
|
public void testReturnFromFinally() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
|
||||||
|
|||||||
@@ -5362,6 +5362,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("returnFromFinally.kt")
|
||||||
public void testReturnFromFinally() throws Exception {
|
public void testReturnFromFinally() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
|
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) {
|
when (inner) {
|
||||||
is JsWhile,
|
is JsWhile,
|
||||||
is JsDoWhile,
|
is JsDoWhile,
|
||||||
is JsFor -> inner.accept(this)
|
is JsFor -> {
|
||||||
|
if (x in nodesToSplit) {
|
||||||
|
inner.accept(this)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
currentStatements += x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else -> splitIfNecessary(x) {
|
else -> splitIfNecessary(x) {
|
||||||
val successor = CoroutineBlock()
|
val successor = CoroutineBlock()
|
||||||
|
|||||||
@@ -6077,6 +6077,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("returnFromFinally.kt")
|
||||||
public void testReturnFromFinally() throws Exception {
|
public void testReturnFromFinally() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user