IR: make calls with explicit singleton receiver tailrec [KT-48602]

This commit is contained in:
Tianyu Geng
2021-09-03 15:31:30 -07:00
committed by TeamCityServer
parent 8525b4932b
commit 3c84fbcab1
14 changed files with 143 additions and 28 deletions
@@ -0,0 +1,25 @@
// DONT_TARGET_EXACT_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// DONT_RUN_GENERATED_CODE: JS
// IGNORE_BACKEND: JS
// IGNORE_BACKEND: JVM
// IGNORE_FIR_DIAGNOSTICS_DIFF
// Light analysis thinks this test passes but it doesn't because JVM backend does not compile this into a tailrec function.
// IGNORE_LIGHT_ANALYSIS
class C {
companion object {
<!NO_TAIL_CALLS_FOUND!>tailrec fun rec(i: Int)<!> {
if (i <= 0) return
C.<!NON_TAIL_RECURSIVE_CALL!>rec<!>(i - 1)
}
}
}
fun box(): String {
C.rec(100000)
return "OK"
}
@@ -0,0 +1,16 @@
// DONT_TARGET_EXACT_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS
// IGNORE_BACKEND: JS_IR_ES6
// DONT_RUN_GENERATED_CODE: JS
object O {
tailrec fun rec(i: Int) {
if (i <= 0) return
O.rec(i - 1)
}
}
fun box(): String {
O.rec(100000)
return "OK"
}
@@ -7,8 +7,8 @@ object Foo {
this.foo2()
}
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo3()<!> {
Foo.<!NON_TAIL_RECURSIVE_CALL!>foo3<!>()
tailrec fun foo3() {
Foo.foo3()
}
}
@@ -22,12 +22,12 @@ class Bar {
this.bar2()
}
<!NO_TAIL_CALLS_FOUND!>tailrec fun bar3()<!> {
Bar.<!NON_TAIL_RECURSIVE_CALL!>bar3<!>()
tailrec fun bar3() {
Bar.bar3()
}
<!NO_TAIL_CALLS_FOUND!>tailrec fun bar4()<!> {
Bar.Companion.<!NON_TAIL_RECURSIVE_CALL!>bar4<!>()
tailrec fun bar4() {
Bar.Companion.bar4()
}
}
}
@@ -1,16 +0,0 @@
object O {
// foo is the same, but the compiler currently doesn't compile this as tail recursive. See KT-48602
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo(i: Int): Int<!> = if (i < 0) 0 else O.<!NON_TAIL_RECURSIVE_CALL!>foo<!>(i - 1)
}
class A {
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo(i: Int)<!> = if (i < 0) 0 else A.foo(i - 1)
companion object {
fun foo(i: Int) = 42 + i
}
}
class B {
<!NO_TAIL_CALLS_FOUND!>tailrec fun foo(i: Int)<!> = if (i < 0) 0 else O.foo(i - 1)
}
@@ -1,5 +1,6 @@
// FIR_IDENTICAL
object O {
// foo is the same, but the compiler currently doesn't compile this as tail recursive. See KT-48602
// tailrec since `O` is a singleton
tailrec fun foo(i: Int): Int = if (i < 0) 0 else O.foo(i - 1)
}