Fix verify error with 'return when/if/try' in suspend function
The problem appears for tail-optimized suspend functions, we erroneously assumed that when/if/try expressions in tail-call position have simple types like `I` while actually, they can return SUSPENDED object, i.e. must have `java/lang/Object` as return type. But this only concerns branching operations in tail-call position, so we have to make an additional analysis for remembering whether a given expression is in a tail-call position. Also, it's important here that we now assume the return type of the current function as `java/lang/Object` that is necessary to avoid wrong checkcasts. #KT-15364 Fixed
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
suspend fun foo(x: Any): Int {
|
||||
return if (x == "56") suspendHere() else 13
|
||||
}
|
||||
|
||||
suspend fun suspendHere(): Int = suspendCoroutineOrReturn { x ->
|
||||
x.resume(56)
|
||||
SUSPENDED_MARKER
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = -1
|
||||
|
||||
builder {
|
||||
result = foo("56")
|
||||
}
|
||||
|
||||
if (result != 56) return "fail 1: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
suspend fun foo(x: Any): Int {
|
||||
return try {
|
||||
suspendHere()
|
||||
} catch (e: Throwable) {
|
||||
13
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun suspendHere(): Int = suspendCoroutineOrReturn { x ->
|
||||
x.resume(56)
|
||||
SUSPENDED_MARKER
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = -1
|
||||
|
||||
builder {
|
||||
result = foo("56")
|
||||
}
|
||||
|
||||
if (result != 56) return "fail 1: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
suspend fun foo(x: Any): Int {
|
||||
return when {
|
||||
x == "56" -> suspendHere()
|
||||
else -> 13
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun suspendHere(): Int = suspendCoroutineOrReturn { x ->
|
||||
x.resume(56)
|
||||
SUSPENDED_MARKER
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = -1
|
||||
|
||||
builder {
|
||||
result = foo("56")
|
||||
}
|
||||
|
||||
if (result != 56) return "fail 1: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user