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
@@ -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()) }