JVM IR: Avoid direct invokes in callable reference tests

Due to the direct invoke optimization, most callable reference tests
were not generating callable references/lambdas.
This commit is contained in:
Steven Schäfer
2022-06-13 14:49:49 +02:00
committed by Alexander Udalov
parent f0238766df
commit 7d59c7689c
123 changed files with 216 additions and 208 deletions
@@ -1,4 +1,4 @@
fun box(): String {
return if ((arrayOf(1, 2, 3)::get)(1) == 2) "OK" else "Fail"
return if ((arrayOf(1, 2, 3)::get).let { it(1) } == 2) "OK" else "Fail"
}
@@ -5,4 +5,4 @@ class A {
}
}
fun box() = (A.Companion::ok)()
fun box() = (A.Companion::ok).let { it() }
@@ -7,11 +7,11 @@ class A {
val aMemberProperty: Int get() = 42.also { result += "A.amp," }
fun test(): String {
(::memberFunction)()
(::aExtensionFunction)()
(::memberFunction).let { it() }
(::aExtensionFunction).let { it() }
(::memberProperty)()
(::aExtensionProperty)()
(::memberProperty).let { it() }
(::aExtensionProperty).let { it() }
return result
}
@@ -21,17 +21,17 @@ class A {
val memberProperty: Int get() = 42.also { result += "B.mp," }
fun test(): String {
(::aMemberFunction)()
(::aExtensionFunction)()
(::aMemberFunction).let { it() }
(::aExtensionFunction).let { it() }
(::aMemberProperty)()
(::aExtensionProperty)()
(::aMemberProperty).let { it() }
(::aExtensionProperty).let { it() }
(::memberFunction)()
(::memberProperty)()
(::memberFunction).let { it() }
(::memberProperty).let { it() }
(::bExtensionFunction)()
(::bExtensionProperty)()
(::bExtensionFunction).let { it() }
(::bExtensionProperty).let { it() }
return result
}
@@ -53,28 +53,28 @@ fun box(): String {
result = ""
with(A()) {
(::memberFunction)()
(::aExtensionFunction)()
(::memberFunction).let { it() }
(::aExtensionFunction).let { it() }
(::memberProperty)()
(::aExtensionProperty)()
(::memberProperty).let { it() }
(::aExtensionProperty).let { it() }
}
if (result != "A.mf,A.ef,A.mp,A.ep,") return "Fail $result"
result = ""
with(A()) {
with(B()) {
(::aMemberFunction)()
(::aExtensionFunction)()
(::aMemberFunction).let { it() }
(::aExtensionFunction).let { it() }
(::aMemberProperty)()
(::aExtensionProperty)()
(::aMemberProperty).let { it() }
(::aExtensionProperty).let { it() }
(::memberFunction)()
(::memberProperty)()
(::memberFunction).let { it() }
(::memberProperty).let { it() }
(::bExtensionFunction)()
(::bExtensionProperty)()
(::bExtensionFunction).let { it() }
(::bExtensionProperty).let { it() }
}
}
if (result != "A.amf,A.ef,A.amp,A.ep,B.mf,B.mp,B.ef,B.ep,") return "Fail $result"
@@ -7,6 +7,6 @@ class Host {
fun box(): String {
Generic(Host()).p::class
(Generic(Host()).p::t)()
return (Generic(Host()).p::v)()
(Generic(Host()).p::t).let { it() }
return (Generic(Host()).p::v).let { it() }
}
@@ -3,13 +3,13 @@
fun box(): String {
val a = intArrayOf(1, 2)
val b = arrayOf("OK")
if ((a::component2)() != 2) {
if ((a::component2).let { it() } != 2) {
return "fail"
}
if ((a::get)(1) != 2) {
if ((a::get).let { it(1) } != 2) {
return "fail"
}
return (b::get)(0)
return (b::get).let { it(0) }
}
@@ -3,4 +3,4 @@ object Singleton {
fun ok() = "OK"
}
fun box() = (Singleton::ok)()
fun box() = (Singleton::ok).let { it() }
@@ -10,6 +10,7 @@ class A {
// FILE: 1.kt
fun box(): String {
(::A)(0.0, 0)
val constructor = ::A
constructor(0.0, 0)
return "OK"
}
@@ -6,4 +6,4 @@ class B : A() {
override fun foo() = "OK"
}
fun box(): String = (A::foo)(B())
fun box(): String = (A::foo).let { it(B()) }
@@ -1,5 +1,5 @@
fun box(): String {
if ((Boolean::not)(true) != false) return "Fail 1"
if ((Boolean::not)(false) != true) return "Fail 2"
if ((Boolean::not).let { it(true) } != false) return "Fail 1"
if ((Boolean::not).let { it(false) } != true) return "Fail 2"
return "OK"
}
@@ -1,7 +1,7 @@
class A {
fun foo(k: Int) = k
fun result() = (A::foo)(this, 111)
fun result() = (A::foo).let { it(this, 111) }
}
fun box(): String {
@@ -3,7 +3,7 @@ class A {
fun k(k: Int) = k
}
fun A.foo() = (A::o)(this) + (A::k)(this, 222)
fun A.foo() = (A::o).let { it(this) } + (A::k).let { it(this, 222) }
fun box(): String {
val result = A().foo()
@@ -2,4 +2,4 @@ class A {
var result = "OK"
}
fun box() = (::A)().result
fun box() = (::A).let { it() }.result
@@ -1,3 +1,3 @@
class A(val result: String)
fun box() = (::A)("OK").result
fun box() = (::A).let { it("OK") }.result
@@ -1,3 +1,3 @@
class A
fun box() = if ((A::equals)(A(), A())) "Fail" else "OK"
fun box() = if ((A::equals).let { it(A(), A()) }) "Fail" else "OK"
@@ -1,5 +1,5 @@
class A {
fun result() = (A::foo)(this, "OK")
fun result() = (A::foo).let { it(this, "OK") }
}
fun A.foo(x: String) = x
@@ -1,6 +1,6 @@
class A
fun A.foo() = (A::bar)(this, "OK")
fun A.foo() = (A::bar).let { it(this, "OK") }
fun A.bar(x: String) = x
@@ -2,4 +2,4 @@ class A<T>(val t: T) {
fun foo(): T = t
}
fun box() = (A<String>::foo)(A("OK"))
fun box() = (A<String>::foo).let { it(A("OK")) }
@@ -4,7 +4,7 @@ class A {
val k = 222
}
fun result() = (A::Inner)(this).o + (A::Inner)(this).k
fun result() = (A::Inner).let { it(this) }.o + (A::Inner).let { it(this) }.k
}
fun box(): String {
@@ -5,7 +5,7 @@ class A {
}
}
fun A.foo() = (A::Inner)(this).o + (A::Inner)(this).k
fun A.foo() = (A::Inner).let { it(this) }.o + (A::Inner).let { it(this) }.k
fun box(): String {
val result = A().foo()
@@ -6,7 +6,7 @@ class A {
}
fun box(): String {
val result = (A::Inner)((::A)()).o + (A::Inner)(A()).k
val result = (A::Inner).let { c -> c((::A).let { it() }).o } + (A::Inner).let { it(A()) }.k
if (result != 333) return "Fail $result"
return "OK"
}
@@ -3,7 +3,10 @@ class A {
}
fun box(): String {
val result = (A::Inner)((::A)(), 111).result + (A::Inner)(A(), 222).result
val result = (A::Inner).let { c -> c((::A).let { it() }, 111) }.result + (A::Inner).let { it(A(), 222) }.result
if (result != 333) return "Fail $result"
return "OK"
}
// CHECK_BYTECODE_TEXT
// 3 Function[^.\n]*\.invoke
@@ -10,6 +10,6 @@ fun box(): String {
numbers.add(1)
numbers.add(2)
numbers.add(3)
(Collections::rotate)(numbers, 1)
(Collections::rotate).let { it(numbers, 1) }
return if ("$numbers" == "[3, 1, 2]") "OK" else "Fail $numbers"
}
@@ -3,5 +3,5 @@ fun box(): String {
val result = "OK"
}
return (::A)().result
return (::A).let { it() }.result
}
@@ -6,5 +6,5 @@ fun box(): String {
}
}
return (::A)().result
return (::A).let { it() }.result
}
@@ -2,5 +2,5 @@ class A
fun box(): String {
fun A.foo() = "OK"
return (A::foo)(A())
return (A::foo).let { it(A()) }
}
@@ -1,5 +1,5 @@
fun box(): String {
class A
fun A.foo() = "OK"
return (A::foo)((::A)())
return (A::foo).let { c -> c((::A).let { it() }) }
}
@@ -1,4 +1,4 @@
fun box(): String {
fun Int.is42With(that: Int) = this + 2 * that == 42
return if ((Int::is42With)(16, 13)) "OK" else "Fail"
return if ((Int::is42With).let { it(16, 13) }) "OK" else "Fail"
}
@@ -1,7 +1,7 @@
fun foo(until: Int): String {
fun bar(x: Int): String =
if (x == until) "OK" else bar(x + 1)
return (::bar)(0)
return (::bar).let { it(0) }
}
fun box() = foo(10)
@@ -1,4 +1,4 @@
fun box(): String {
fun foo() = "OK"
return (::foo)()
return (::foo).let { it() }
}
@@ -3,5 +3,5 @@ fun box(): String {
fun foo() = result
return (::foo)()
return (::foo).let { it() }
}
@@ -1,4 +1,4 @@
fun box(): String {
fun foo(s: String) = s
return (::foo)("OK")
return (::foo).let { it("OK") }
}
@@ -4,7 +4,7 @@ class A {
val k = 222
}
fun result() = (::Nested)().o + (A::Nested)().k
fun result() = (::Nested).let { it() }.o + (A::Nested).let { it() }.k
}
fun box(): String {
@@ -4,4 +4,4 @@ class A {
}
}
fun box() = (A::Nested)().result
fun box() = (A::Nested).let { it() }.result
@@ -2,4 +2,4 @@ class A {
class Nested(val result: String)
}
fun box() = (A::Nested)("OK").result
fun box() = (A::Nested).let { it("OK") }.result
@@ -1,7 +1,7 @@
class A {
private fun foo() = "OK"
fun bar() = (A::foo)(this)
fun bar() = (A::foo).let { it(this) }
}
fun box() = A().bar()
@@ -5,7 +5,7 @@ fun <T> run(arg1: T, arg2: T, funRef:(T,T) -> T): T {
fun foo(o: Int, k: Int) = o + k
class A {
fun bar() = (::foo)(111, 222)
fun bar() = (::foo).let { it(111, 222) }
}
fun box(): String {
@@ -6,7 +6,7 @@ fun foo(o: Int, k: Int) = o + k
class A
fun A.bar() = (::foo)(111, 222)
fun A.bar() = (::foo).let { it(111, 222) }
fun box(): String {
val result = A().bar()
@@ -4,7 +4,7 @@ interface T {
class B : T {
inner class C {
fun bar() = (T::foo)(this@B)
fun bar() = (T::foo).let { it(this@B) }
}
}
@@ -6,4 +6,4 @@ class B : A {
override fun foo() = "OK"
}
fun box() = (A::foo)(B())
fun box() = (A::foo).let { it(B()) }
@@ -13,6 +13,6 @@ class A {
fun box(): String {
val args = arrayOf("Fail")
(A::main)(args)
(A::main).let { it(args) }
return args[0]
}