JS IR: fix type checks for suspend function descendants (^KT-54382 fixed)
Consider `class A : suspend () -> Unit {}`. Type checks such as `is A`
are now performed via a regular `instanceof` check instead of the special
checks for suspend lambdas.
This commit is contained in:
committed by
Space Team
parent
bc13173ea9
commit
9342356c38
@@ -0,0 +1,29 @@
|
||||
// WITH_STDLIB
|
||||
// WITH_COROUTINES
|
||||
|
||||
typealias AsyncFun = suspend () -> Unit
|
||||
val actions = arrayListOf<AsyncFun>()
|
||||
|
||||
private class SyncFunAdapter(private val target: () -> Unit) : AsyncFun {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return if (other is SyncFunAdapter) {
|
||||
target == other.target
|
||||
} else {
|
||||
target == other
|
||||
}
|
||||
}
|
||||
|
||||
override fun hashCode() = target.hashCode()
|
||||
|
||||
override suspend fun invoke() {
|
||||
target()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val x = SyncFunAdapter { }
|
||||
actions.add(x)
|
||||
if (!actions.remove(x)) return "FAIL 1"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// WITH_STDLIB
|
||||
// !LANGUAGE: +SuspendFunctionAsSupertype
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
import kotlin.coroutines.*
|
||||
|
||||
class C: suspend () -> Unit {
|
||||
override suspend fun invoke() {
|
||||
}
|
||||
}
|
||||
|
||||
interface I: suspend () -> Unit {}
|
||||
|
||||
fun interface FI: suspend () -> Unit {}
|
||||
|
||||
@Suppress("INCOMPATIBLE_TYPES")
|
||||
fun box(): String {
|
||||
val c = C()
|
||||
if (c !is SuspendFunction0<*>) return "FAIL 1"
|
||||
if (c is SuspendFunction1<*, *>) return "FAIL 3"
|
||||
|
||||
val i = object : I {
|
||||
override suspend fun invoke() {
|
||||
}
|
||||
}
|
||||
if (i !is SuspendFunction0<Unit>) return "FAIL 4"
|
||||
if (i is SuspendFunction1<*, *>) return "FAIL 6"
|
||||
|
||||
val fi = object : FI {
|
||||
override suspend fun invoke() {
|
||||
}
|
||||
}
|
||||
if (fi !is SuspendFunction0<Unit>) return "FAIL 7"
|
||||
if (fi is SuspendFunction1<*, *>) return "FAIL 9"
|
||||
|
||||
val o = object : suspend () -> Unit {
|
||||
override suspend fun invoke() {
|
||||
}
|
||||
}
|
||||
if (o !is SuspendFunction0<Unit>) return "FAIL 10"
|
||||
if (o is SuspendFunction1<*, *>) return "FAIL 12"
|
||||
|
||||
if (c !is C) return "FAIL 13"
|
||||
if (i !is I) return "FAIL 14"
|
||||
if (fi !is FI) return "FAIL 15"
|
||||
|
||||
if (c !is C) return "FAIL 16"
|
||||
val a: Any = c
|
||||
if (a !is C) return "FAIL 17"
|
||||
if (i !is I) return "FAIL 18"
|
||||
if (fi !is FI) return "FAIL 19"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// WITH_STDLIB
|
||||
// WITH_COROUTINES
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
fun check(condition: Boolean, msg: () -> Unit) {
|
||||
if (!condition) {
|
||||
throw AssertionError(msg())
|
||||
}
|
||||
}
|
||||
|
||||
fun fn1(x: Any) {}
|
||||
suspend fun suspendFn0() {}
|
||||
|
||||
val lambda1 = { x: Any -> } as (Any) -> Unit
|
||||
val suspendLambda0: suspend () -> Unit = {}
|
||||
|
||||
fun Any.extFun(a: Any) {}
|
||||
suspend fun Any.suspendExtFun() {}
|
||||
|
||||
class A {
|
||||
fun foo(a: Any) {}
|
||||
suspend fun suspendFoo() {}
|
||||
}
|
||||
|
||||
inline fun <reified T : suspend () -> Unit> checkReified(noinline x: (Any?) -> Unit) {
|
||||
if(x is T) throw IllegalStateException("x is T")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val f1 = ::fn1 as Any
|
||||
val sf0 = ::suspendFn0 as Any
|
||||
|
||||
val ef = Any::extFun as Any
|
||||
val sef = Any::suspendExtFun as Any
|
||||
|
||||
val afoo = A::foo
|
||||
val safoo = A::suspendFoo
|
||||
|
||||
fun local1(x: Any) {}
|
||||
suspend fun suspendLocal0() {}
|
||||
|
||||
val localFun1 = ::local1 as Any
|
||||
val suspendLocalFun0 = ::suspendLocal0 as Any
|
||||
|
||||
check(f1 !is SuspendFunction0<*>) { "Failed: f1 !is SuspendFunction0<*>" }
|
||||
check(sf0 is SuspendFunction0<*>) { "Failed: f1 is SuspendFunction0<*>" }
|
||||
|
||||
check(lambda1 !is SuspendFunction0<*>) { "Failed: lambda1 !is SuspendFunction0<*>" }
|
||||
check(suspendLambda0 is SuspendFunction0<*>) { "Failed: suspendLambda0 is SuspendFunction0<*>" }
|
||||
|
||||
check(localFun1 !is SuspendFunction0<*>) { "Failed: localFun1 !is SuspendFunction0<*, *>" }
|
||||
check(suspendLocalFun0 is SuspendFunction0<*>) { "Failed: suspendLocalFun0 is SuspendFunction0<*>" }
|
||||
|
||||
check(ef !is SuspendFunction1<*, *>) { "Failed: ef !is SuspendFunction1<*, *>" }
|
||||
check(sef is SuspendFunction1<*, *>) { "Failed: sef is SuspendFunction1<*, *>" }
|
||||
|
||||
check(afoo !is SuspendFunction1<*, *>) { "afoo !is SuspendFunction1<*, *>" }
|
||||
check(safoo is SuspendFunction1<*, *>) { "asfoo is SuspendFunction1<*, *>" }
|
||||
|
||||
checkReified<suspend () -> Unit> {}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user