Do not transform state-machine when inlining
Sometimes, state-machine, generated in inline functions with crossinline parameter, is transformed, since all usages should be renamed. However, this is wrong: in this case, we will have state-machine inside state-machine. This fix addresses the issue. #KT-25893 Fixed
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
||||
// WITH_RUNTIME
|
||||
// LANGUAGE_VERSION: 1.2
|
||||
// IGNORE_BACKEND: JVM
|
||||
// WITH_COROUTINES
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
interface SuspendRunnable {
|
||||
suspend fun run(): String
|
||||
}
|
||||
|
||||
inline fun inlineMe(crossinline c: suspend () -> String) = object : SuspendRunnable {
|
||||
override suspend fun run() = c()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var res = "FAIL"
|
||||
builder {
|
||||
res = inlineMe { "OK" }.run()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Test for continuation of 'run' transformation.
|
||||
// Since continuation is not suspend lambda, it should not have state-machine.
|
||||
// @CrossinlineSuspendContinuation_1_2Kt$box$1$doResume$$inlined$inlineMe$1$1.class:
|
||||
// 0 TABLESWITCH
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// WITH_RUNTIME
|
||||
// LANGUAGE_VERSION: 1.3
|
||||
// WITH_COROUTINES
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
interface SuspendRunnable {
|
||||
suspend fun run(): String
|
||||
}
|
||||
|
||||
inline fun inlineMe(crossinline c: suspend () -> String) = object : SuspendRunnable {
|
||||
override suspend fun run() = c()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var res = "FAIL"
|
||||
builder {
|
||||
res = inlineMe { "OK" }.run()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Test for continuation of 'run' transformation.
|
||||
// Since continuation is not suspend lambda, it should not have state-machine
|
||||
// @CrossinlineSuspendContinuation_1_3Kt$box$1$invokeSuspend$$inlined$inlineMe$1$1.class:
|
||||
// 0 TABLESWITCH
|
||||
@@ -0,0 +1,13 @@
|
||||
class Handler(val func: suspend (Any) -> Unit)
|
||||
|
||||
inline fun createHandler(crossinline handler: suspend (Any) -> Unit): Handler {
|
||||
return Handler({ handler.invoke(it) })
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
createHandler({
|
||||
if (it !is String) {}
|
||||
})
|
||||
}
|
||||
|
||||
// 2 TABLESWITCH
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
fun <T> builder(c: suspend () -> T): T = TODO()
|
||||
|
||||
class Test {
|
||||
fun doWork() {
|
||||
builder {
|
||||
execute {
|
||||
getData { getSomeString() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun execute(crossinline action: suspend () -> Unit) {
|
||||
builder { action() }
|
||||
}
|
||||
|
||||
private suspend fun <T> getData(dataProvider: suspend () -> T): T = builder { dataProvider() }
|
||||
|
||||
private suspend fun getSomeString(): String {
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
// 4 TABLESWITCH
|
||||
Reference in New Issue
Block a user