Fix codegen issue on suspend functions with receiver
When the extension receiver of a named suspend function was marked as used from the inner lambda, codegen used to throw a "Don't know how to generate outer expression for class" exception. It may seem quite tricky, but currently for suspend lambda body its extension receiver is treated as it's defined inside the relevant "doResume" (there is an actual bytecode part that fills the relevant local variable) The problem was that inside ExpressionCodegen for "doResume" of named suspend function we couldn't determine that original function has an extension receiver. #KT-15821 Fixed #KT-15820 Fixed
This commit is contained in:
+36
@@ -0,0 +1,36 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// TARGET_BACKEND: JVM
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.SUSPENDED_MARKER
|
||||
import kotlin.coroutines.intrinsics.suspendCoroutineOrReturn
|
||||
|
||||
class MyTest {
|
||||
suspend fun act(value: String): String = suspendCoroutineOrReturn {
|
||||
it.resume(value)
|
||||
SUSPENDED_MARKER
|
||||
}
|
||||
}
|
||||
|
||||
inline suspend fun <T> testAsync(routine: suspend MyTest.() -> T): T = routine(MyTest())
|
||||
|
||||
inline suspend fun Iterable<String>.test() = testAsync {
|
||||
var sum = ""
|
||||
for (v in this@test) {
|
||||
sum += act(v)
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
fun builder(x: suspend () -> Unit) {
|
||||
x.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var res = ""
|
||||
builder {
|
||||
res = listOf("O", "K").test()
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
Vendored
+35
@@ -0,0 +1,35 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.SUSPENDED_MARKER
|
||||
import kotlin.coroutines.intrinsics.suspendCoroutineOrReturn
|
||||
|
||||
class MyTest {
|
||||
suspend fun act(value: String): String = suspendCoroutineOrReturn {
|
||||
it.resume(value)
|
||||
SUSPENDED_MARKER
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun <T> testAsync(routine: suspend MyTest.() -> T): T = routine(MyTest())
|
||||
|
||||
suspend fun Iterable<String>.test() = testAsync {
|
||||
var sum = ""
|
||||
for (v in this@test) {
|
||||
sum += act(v)
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
fun builder(x: suspend () -> Unit) {
|
||||
x.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var res = ""
|
||||
builder {
|
||||
res = listOf("O", "K").test()
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
Reference in New Issue
Block a user