When I present it with the following code (first line of function commented out because while it would be necessary for correctness, I want to make sure it's not what's causing the problem here), the Kotlin compiler tells me the recursive call is not a tail call.
class Env(val global: Map<Symbol, Term>, val outer: Env?, val local: Array<Term?>) {
tailrec operator fun get(i: Int): Term {
// if (i < local.size) return local[i]!!
val o = outer!!
return o[i - local.size]
}
}
If I change the syntax of the last line to explicitly say o.get(i - local.size) instead of using operator overloading, it makes no difference. Ditto if I uncomment the first line.
I cannot for the life of me see how it fails to be a tail call. Maybe I've just been staring at it so long I'm overlooking the obvious. Can anyone see what I'm doing wrong?
Update: If I rewrite it to take the object parameter explicitly instead of implicitly, the compiler is happy. Compiler bug?
tailrec fun get(env: Env, i: Int): Term {
if (i < env.local.size) return env.local[i]!!
val o = env.outer!!
return get(env, i - env.local.size)
}