Here is a minimal code that raise the compilation error 'Recursive call not in tail position'. However, I'm using an @inline
and the recursive call is in tail position. The reason why I'm using this @inline
is that I have the code pf the original reccall
duplicated twice.
import scala.annotation._
object Test {
@tailrec private def test(i: Int): Int = {
@inline def reccall(i: Int): Int = test(i-1)
i match {
case 0 => 0
case i => reccall(i)
}
}
}
I've looked at the answers Recursive call not in tail position @tailrec why does this method not compile with 'contains a recursive call not in tail position'? but they do not apply to my case. Using Scala 2.12
It appears, the way @inline
is implemented is that it still passes the parameter via stack. The jump is eliminated, by inserting the code inline, but the stack is still used for the arguments. This makes it impossible to be in a tail position, because the stack needs to be cleaned up after the call is completed.
Besides, annotating a function with @inline
does not guarantee that the optimizer will inline it, just that it will "try especially hard".