Add tests for converting expressions of function types to suspending functional types

This commit is contained in:
Victor Petukhov
2021-07-13 15:34:37 +03:00
committed by teamcityserver
parent 780b9a032b
commit 0cc6fbbc6e
30 changed files with 1065 additions and 0 deletions
@@ -0,0 +1,25 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun foo1(f: suspend () -> String) {}
fun foo2(f: suspend (Int) -> String) {}
fun foo3(f: suspend () -> Unit) {}
fun test(
f0: suspend () -> String,
f1: () -> String,
f2: (Int) -> String,
f3: () -> Unit,
) {
foo1 { "str" }
foo1(f0)
foo1(f1)
foo2(f2)
foo3(f3)
}
fun box(): String {
test({ "" }, { "" }, { it.toString() }, {})
return "OK"
}
@@ -0,0 +1,6 @@
package
public fun foo1(/*0*/ f: suspend () -> kotlin.String): kotlin.Unit
public fun foo2(/*0*/ f: suspend (kotlin.Int) -> kotlin.String): kotlin.Unit
public fun foo3(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
public fun test(/*0*/ f0: suspend () -> kotlin.String, /*1*/ f1: () -> kotlin.String, /*2*/ f2: (kotlin.Int) -> kotlin.String, /*3*/ f3: () -> kotlin.Unit): kotlin.Unit
@@ -0,0 +1,18 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun foo1(f: suspend () -> Unit) {}
fun bar1() {}
fun <T> foo2(e: T, f: suspend (T) -> Unit) {}
fun bar2(x: Int) {}
fun bar2(s: String) {}
fun box(): String {
foo1(::bar1)
foo2(42, ::bar2)
foo2("str", ::bar2)
return "OK"
}
@@ -0,0 +1,8 @@
package
public fun bar1(): kotlin.Unit
public fun bar2(/*0*/ x: kotlin.Int): kotlin.Unit
public fun bar2(/*0*/ s: kotlin.String): kotlin.Unit
public fun foo1(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
public fun </*0*/ T> foo2(/*0*/ e: T, /*1*/ f: suspend (T) -> kotlin.Unit): kotlin.Unit
public fun test(): kotlin.Unit
@@ -0,0 +1,54 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
// WITH_RUNTIME
class Inv2<T, K>
inline fun <reified T> materialize(): T = T::class.java.newInstance()
inline fun <reified T> foo1(crossinline f: suspend (T) -> String): T = materialize()
inline fun <reified T> foo2(crossinline f: suspend () -> T): T = materialize()
inline fun <reified T, K> foo3(crossinline f: suspend (T) -> K): Inv2<T, K> = Inv2()
fun <T> foo11(f: suspend (T) -> String): T = 1 as T
fun <T> foo21(f: suspend () -> T): T = "" as T
fun <T, K> foo31(f: suspend (T) -> K): Inv2<T, K> = Inv2()
fun <I> id(e: I): I = e
fun test(f: (Int) -> String, g: () -> String) {
val a0 = foo1(f)
val a01 = foo11(f)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>a0<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>a01<!>
val a1 = foo2(g)
val a11 = foo21(g)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>a1<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>a11<!>
val a2 = foo3(f)
val a21 = foo31(f)
<!DEBUG_INFO_EXPRESSION_TYPE("Inv2<kotlin.Int, kotlin.String>")!>a2<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Inv2<kotlin.Int, kotlin.String>")!>a21<!>
val a3 = foo1(id(f))
val a31 = foo11(id(f))
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>a3<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>a31<!>
val a4 = foo2(id(g))
val a41 = foo21(id(g))
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>a4<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>a41<!>
val a5 = foo3(id(f))
val a51 = foo31(id(f))
<!DEBUG_INFO_EXPRESSION_TYPE("Inv2<kotlin.Int, kotlin.String>")!>a5<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Inv2<kotlin.Int, kotlin.String>")!>a51<!>
}
fun box(): String {
test({ it.toString() }, { "" })
return "OK"
}
@@ -0,0 +1,14 @@
package
public fun </*0*/ T> foo1(/*0*/ f: suspend (T) -> kotlin.String): T
public fun </*0*/ T> foo2(/*0*/ f: suspend () -> T): T
public fun </*0*/ T, /*1*/ K> foo3(/*0*/ f: suspend (T) -> K): Inv2<T, K>
public fun </*0*/ I> id(/*0*/ e: I): I
public fun test(/*0*/ f: (kotlin.Int) -> kotlin.String, /*1*/ g: () -> kotlin.String): kotlin.Unit
public final class Inv2</*0*/ T, /*1*/ K> {
public constructor Inv2</*0*/ T, /*1*/ K>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,19 @@
// FIR_IDENTICAL
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun interface SuspendRunnable {
suspend fun invoke()
}
fun foo(s: SuspendRunnable) {}
fun test(f: () -> Unit) {
foo { }
foo(f)
}
fun box(): String {
test({ "" })
return "OK"
}
@@ -0,0 +1,11 @@
package
public fun foo(/*0*/ s: SuspendRunnable): kotlin.Unit
public fun test(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public fun interface SuspendRunnable {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract suspend fun invoke(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,19 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun foo(x: () -> Int) {}
fun foo(x: suspend () -> Int) {}
fun usualCall(): Int = 42
suspend fun suspendCall(): Int = 42
// candidate without suspend conversions is more specific
fun test2(f: () -> Int, g: suspend () -> Int) {
foo(f)
foo(g)
}
fun box(): String {
test2({ 1 }, { 2 })
return "OK"
}
@@ -0,0 +1,8 @@
package
public fun foo(/*0*/ x: () -> kotlin.Int): kotlin.Unit
public fun foo(/*0*/ x: suspend () -> kotlin.Int): kotlin.Unit
public suspend fun suspendCall(): kotlin.Int
public fun test1(): kotlin.Unit
public fun test2(/*0*/ f: () -> kotlin.Int, /*1*/ g: suspend () -> kotlin.Int): kotlin.Unit
public fun usualCall(): kotlin.Int
@@ -0,0 +1,17 @@
// FIR_IDENTICAL
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun foo(f: () -> String, g: suspend () -> String, h: suspend () -> String) {}
fun test(f: () -> String, g: suspend () -> String) {
foo(f, f, f)
foo(f, { "str" }, f)
foo(f, f, g)
foo(f, g, g)
}
fun box(): String {
test({ "1" }, { "2" })
return "OK"
}
@@ -0,0 +1,4 @@
package
public fun foo(/*0*/ f: () -> kotlin.String, /*1*/ g: suspend () -> kotlin.String, /*2*/ h: suspend () -> kotlin.String): kotlin.Unit
public fun test(/*0*/ f: () -> kotlin.String, /*1*/ g: suspend () -> kotlin.String): kotlin.Unit
@@ -0,0 +1,36 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun interface SuspendRunnable {
suspend fun run()
}
object Test1 {
fun call(r: () -> Unit) {}
object Scope {
fun call(r: SuspendRunnable) {}
fun bar(f: () -> Unit) {
<!DEBUG_INFO_CALL("fqName: Test1.call; typeCall: function")!>call(f)<!>
}
}
}
object Test2 {
fun call(r: Runnable) {}
object Scope {
fun call(r: SuspendRunnable) {}
fun bar(f: () -> Unit) {
<!DEBUG_INFO_CALL("fqName: Test2.Scope.call; typeCall: function")!>call(f)<!>
}
}
}
fun box(): String {
Test2.Scope.bar { }
Test1.Scope.bar { }
return "OK"
}
@@ -0,0 +1,42 @@
package
public fun interface SuspendRunnable {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract suspend fun run(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object Test1 {
private constructor Test1()
public final fun call(/*0*/ r: () -> kotlin.Unit): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public object Scope {
private constructor Scope()
public final fun bar(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public final fun call(/*0*/ r: SuspendRunnable): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public object Test2 {
private constructor Test2()
public final fun call(/*0*/ r: java.lang.Runnable): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public object Scope {
private constructor Scope()
public final fun bar(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public final fun call(/*0*/ r: SuspendRunnable): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,57 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
// WITH_RUNTIME
object Test1 {
fun foo(f: () -> Unit) {}
object Scope {
fun foo(f: suspend () -> Unit) {}
fun test(g: () -> Unit) {
<!DEBUG_INFO_CALL("fqName: Test1.foo; typeCall: function")!>foo(g)<!>
}
}
}
object Test2 {
inline fun <reified T> foo(crossinline f: suspend () -> T): T = 1 as T
fun <T> foo2(f: suspend () -> T): T = 1 as T
suspend fun bar(): Int = 0
object Scope {
fun bar(): String = ""
fun test() {
val result = foo(::bar)
val result2 = foo2(::bar)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>result<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>result2<!>
}
}
}
object Test3 {
inline fun <reified T> foo(crossinline f: suspend () -> T): T = "" as T
fun <T> foo2(f: suspend () -> T): T = "" as T
suspend fun bar(x: Int = 42): Int = 0
object Scope {
fun bar(x: Int = 42): String = ""
fun test() {
val result = foo(::bar)
val result2 = foo2(::bar)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>result<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>result2<!>
}
}
}
fun box(): String {
Test1.Scope.test {}
Test2.Scope.test()
Test3.Scope.test()
return "OK"
}
@@ -0,0 +1,54 @@
package
public object Test1 {
private constructor Test1()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public object Scope {
private constructor Scope()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun test(/*0*/ g: () -> kotlin.Unit): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public object Test2 {
private constructor Test2()
public final suspend fun bar(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun </*0*/ T> foo(/*0*/ f: suspend () -> T): T
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public object Scope {
private constructor Scope()
public final fun bar(): kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun test(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public object Test3 {
private constructor Test3()
public final suspend fun bar(/*0*/ x: kotlin.Int = ...): kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun </*0*/ T> foo(/*0*/ f: suspend () -> T): T
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public object Scope {
private constructor Scope()
public final fun bar(/*0*/ x: kotlin.Int = ...): kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun test(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,27 @@
// FIR_IDENTICAL
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun useSuspendVararg(vararg sfn: suspend () -> Unit) {}
fun testSuspendConversionInVarargElementsSome(
sf1: suspend () -> Unit,
f2: () -> Unit,
sf3: suspend () -> Unit
) {
useSuspendVararg(sf1, f2, sf3)
}
fun testSuspendConversionInVarargElementsAll(
f1: () -> Unit,
f2: () -> Unit,
f3: () -> Unit
) {
useSuspendVararg(f1, f2, f3)
}
fun box(): String {
testSuspendConversionInVarargElementsSome({}, {}, {})
testSuspendConversionInVarargElementsAll({}, {}, {})
return "OK"
}
@@ -0,0 +1,5 @@
package
public fun testSuspendConversionInVarargElementsAll(/*0*/ f1: () -> kotlin.Unit, /*1*/ f2: () -> kotlin.Unit, /*2*/ f3: () -> kotlin.Unit): kotlin.Unit
public fun testSuspendConversionInVarargElementsSome(/*0*/ sf1: suspend () -> kotlin.Unit, /*1*/ f2: () -> kotlin.Unit, /*2*/ sf3: suspend () -> kotlin.Unit): kotlin.Unit
public fun useSuspendVararg(/*0*/ vararg sfn: suspend () -> kotlin.Unit /*kotlin.Array<out suspend () -> kotlin.Unit>*/): kotlin.Unit
@@ -0,0 +1,24 @@
// FIR_IDENTICAL
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun interface SuspendRunnable {
suspend fun invoke()
}
fun foo1(s: SuspendRunnable) {}
fun bar1() {}
fun bar2(s: String = ""): Int = 0
fun bar3() {}
suspend fun bar3(s: String = ""): Int = 0
fun box(): String {
foo1(::bar1)
foo1(::bar2)
foo1(::bar3) // Should be ambiguity
return "OK"
}
@@ -0,0 +1,15 @@
package
public fun bar1(): kotlin.Unit
public fun bar2(/*0*/ s: kotlin.String = ...): kotlin.Int
public fun bar3(): kotlin.Unit
public suspend fun bar3(/*0*/ s: kotlin.String = ...): kotlin.Int
public fun foo1(/*0*/ s: SuspendRunnable): kotlin.Unit
public fun test(): kotlin.Unit
public fun interface SuspendRunnable {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract suspend fun invoke(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,23 @@
// FIR_IDENTICAL
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun unitCoercion(f: suspend () -> Unit) {}
fun foo(): Int = 0
fun defaults(f: suspend (Int) -> String) {}
fun bar(i: Int, l: Long = 42L): String = ""
fun varargs(f: suspend (Int, Int, Int) -> String) {}
fun baz(vararg ints: Int): String = ""
fun unitCoercionAndDefaults(f: suspend () -> Unit) {}
fun all(s: String = ""): Int = 0
fun box(): String {
unitCoercion(::foo)
defaults(::bar)
varargs(::baz)
unitCoercionAndDefaults(::all)
return "OK"
}
@@ -0,0 +1,11 @@
package
public fun all(/*0*/ s: kotlin.String = ...): kotlin.Int
public fun bar(/*0*/ i: kotlin.Int, /*1*/ l: kotlin.Long = ...): kotlin.String
public fun baz(/*0*/ vararg ints: kotlin.Int /*kotlin.IntArray*/): kotlin.String
public fun defaults(/*0*/ f: suspend (kotlin.Int) -> kotlin.String): kotlin.Unit
public fun foo(): kotlin.Int
public fun test(): kotlin.Unit
public fun unitCoercion(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
public fun unitCoercionAndDefaults(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
public fun varargs(/*0*/ f: suspend (kotlin.Int, kotlin.Int, kotlin.Int) -> kotlin.String): kotlin.Unit