JVM: Suspend conversion for function references

This commit is contained in:
Dmitry Petrov
2020-04-23 15:20:44 +03:00
parent 6b9a7464f5
commit c7a96810bf
23 changed files with 886 additions and 25 deletions
@@ -0,0 +1,28 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
var test = "failed"
fun foo(s: String): String {
test = s + "K"
return test
}
suspend fun invokeSuspend(fn: suspend (String) -> Unit, arg: String) = fn.invoke(arg)
fun box(): String {
runSuspend {
invokeSuspend(::foo, "O")
}
return test
}
@@ -0,0 +1,24 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun foo(s1: String, s2: String = "K"): String = s1 + s2
suspend fun invokeSuspend(fn: suspend (String) -> String, arg: String) = fn.invoke(arg)
fun box(): String {
var test = "failed"
runSuspend {
test = invokeSuspend(::foo, "O")
}
return test
}
@@ -0,0 +1,24 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun foo(vararg ss: String): String = ss[0] + "K"
suspend fun invokeSuspend(fn: suspend (String) -> String, arg: String) = fn.invoke(arg)
fun box(): String {
var test = "failed"
runSuspend {
test = invokeSuspend(::foo, "O")
}
return test
}
@@ -0,0 +1,30 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// ^ this test hangs on JS_IR (even if it's IGNOREd)
// IGNORE_BACKEND: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
class C {
var test = "failed"
fun foo() {
test = "OK"
}
}
fun box(): String {
val c = C()
runSuspend(c::foo)
return c.test
}
@@ -0,0 +1,25 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
var test = "failed"
fun foo() { test = "OK" }
inline suspend fun invokeSuspend(crossinline fn: suspend () -> Unit) = suspend { fn() }
fun box(): String {
runSuspend {
invokeSuspend(::foo)()
}
return test
}
@@ -0,0 +1,28 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
var test = "failed"
fun foo(s: String): String {
test = s + "K"
return test
}
inline suspend fun invokeSuspend(fn: suspend (String) -> Unit, arg: String) = fn.invoke(arg)
fun box(): String {
runSuspend {
invokeSuspend(::foo, "O")
}
return test
}
@@ -0,0 +1,24 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun foo(s1: String, s2: String = "K"): String = s1 + s2
inline suspend fun invokeSuspend(fn: suspend (String) -> String, arg: String) = fn.invoke(arg)
fun box(): String {
var test = "failed"
runSuspend {
test = invokeSuspend(::foo, "O")
}
return test
}
@@ -0,0 +1,24 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun foo(vararg ss: String): String = ss[0] + "K"
inline suspend fun invokeSuspend(fn: suspend (String) -> String, arg: String) = fn.invoke(arg)
fun box(): String {
var test = "failed"
runSuspend {
test = invokeSuspend(::foo, "O")
}
return test
}
@@ -0,0 +1,34 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// ^ this test hangs on JS_IR (even if it's IGNOREd)
// IGNORE_BACKEND: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
inline suspend fun invokeSuspend(fn: suspend () -> Unit) = fn()
class C {
var test = "failed"
fun foo() {
test = "OK"
}
}
fun box(): String {
val c = C()
runSuspend {
invokeSuspend(c::foo)
}
return c.test
}
@@ -0,0 +1,27 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
var test = "failed"
fun foo() { test = "OK" }
inline suspend fun invokeSuspend(fn: suspend () -> Unit) { fn() }
fun box(): String {
runSuspend {
invokeSuspend(::foo)
}
return test
}
@@ -0,0 +1,24 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun foo(s: String): String = s + "K"
inline suspend fun invokeSuspend(fn: suspend (String) -> String, arg: String) = fn.invoke(arg)
fun box(): String {
var test = "failed"
runSuspend {
test = invokeSuspend(::foo, "O")
}
return test
}
@@ -0,0 +1,22 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
var test = "failed"
fun foo() { test = "OK" }
fun box(): String {
runSuspend(::foo)
return test
}
@@ -0,0 +1,24 @@
// !LANGUAGE: +SuspendConversion
// WITH_RUNTIME
// WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
fun runSuspend(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun foo(s: String): String = s + "K"
suspend fun invokeSuspend(fn: suspend (String) -> String, arg: String) = fn.invoke(arg)
fun box(): String {
var test = "failed"
runSuspend {
test = invokeSuspend(::foo, "O")
}
return test
}
@@ -0,0 +1,53 @@
// !LANGUAGE: +SuspendConversion
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR, JS_IR
// FILE: suspendCovnersion.kt
fun checkNotEqual(x: Any, y: Any) {
if (x == y || y == x) throw AssertionError("$x and $y should NOT be equal")
}
fun capturePlain(fn: () -> Unit): Any = fn
fun captureSuspend(fn: suspend () -> Unit): Any = fn
fun capturePlainInt(fn: (Int) -> Unit): Any = fn
fun captureSuspendInt(fn: suspend (Int) -> Unit): Any = fn
fun foo() {}
class C {
fun memberFun() {}
}
fun fnWithVararg(vararg xs: Int) {}
fun fnWithDefault(x1: Int = 1, x2: Int = 2) {}
fun fnReturnsInt() = 1
fun box(): String {
val c = C()
checkNotEqual(capturePlain(::foo), captureSuspend(::foo))
checkNotEqual(capturePlain(c::memberFun), captureSuspend(c::memberFun))
checkNotEqual(captureOther1(), captureOther2())
checkNotEqual(captureBoundOther1(c), captureBoundOther2(c))
checkNotEqual(capturePlainInt(::fnWithVararg), captureSuspendInt(::fnWithVararg))
checkNotEqual(captureSuspend(::fnWithVararg), captureSuspendInt(::fnWithVararg))
checkNotEqual(capturePlainInt(::fnWithDefault), captureSuspendInt(::fnWithDefault))
checkNotEqual(captureSuspend(::fnWithDefault), captureSuspendInt(::fnWithDefault))
checkNotEqual(capturePlain(::fnReturnsInt), captureSuspend(::fnReturnsInt))
return "OK"
}
// FILE: fromOtherFile.kt
fun captureOther1() = capturePlain(::foo)
fun captureOther2() = captureSuspend(::foo)
fun captureBoundOther1(c: C) = capturePlain(c::memberFun)
fun captureBoundOther2(c: C) = captureSuspend(c::memberFun)