Refine 'handleResult' calls generation within coroutines

Before this change everything works just fine for 'handleResult' methods
accepting non-Unit parameters

For other cases the same coercion-to-unit strategy is in plain lambdas:
- if last statement is not Unit type, execute it, pop from the stack, then put Unit instance
- for 'return@label' (no expression) just put Unit on the stack

 #KT-13531 Fixed
This commit is contained in:
Denis Zharkov
2016-08-31 15:42:32 +03:00
parent 12dad29336
commit 1226d8fc2c
3 changed files with 85 additions and 6 deletions
@@ -0,0 +1,46 @@
class Controller {
var result = "fail"
operator fun handleResult(u: Unit, c: Continuation<Nothing>) {
result = "OK"
}
suspend fun <T> await(t: T, c: Continuation<T>) {
c.resume(t)
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.result
}
var TRUE = true
var FALSE = false
fun box(): String {
val r1 = builder { await(Unit) }
if (r1 != "OK") return "fail 1"
val r2 = builder {
if (await(1) != 1) throw RuntimeException("fail1")
if (TRUE) return@builder
}
if (r2 != "OK") return "fail 2"
val r3 = builder {
if (await(1) != 1) throw RuntimeException("fail2")
if (FALSE) return@builder
}
if (r3 != "OK") return "fail 3"
val r4 = builder {
if (await(1) != 1) throw RuntimeException("fail3")
return@builder
}
if (r4 != "OK") return "fail 4"
return builder { await(1) }
}