Closed
Description
Minimized code
import scala.annotation.tailrec
sealed trait Foo[+A]
case class Bar[A](f: Foo[A]) extends Foo[A]
case class Done[A](a: A) extends Foo[A]
object Test {
@tailrec
def runT[A](c: Foo[A]): A = c match {
case Bar(f) => runT(f)
case Done(a) => a
}
}
Output
-- Error: try/tr.scala:10:23 ---------------------------------------------------
10 | case Bar(f) => runT(f)
| ^^^^^^^
| Cannot rewrite recursive call: it is not in tail position
The problem comes from the tree we get after erasure:
if x9.isInstanceOf[Bar] then
{
case val x14: Bar = Bar.unapply(x9.asInstanceOf[Bar])
case val x15: Foo = x14._1()
case val f: Foo = x15
return[matchResult7]
{
Test.runT(f.asInstanceOf[Foo]).asInstanceOf[Object]
}
}
else ()
runT
is indeed not in tail position since it's followed by an asInstanceOf
cast, but that shouldn't prevent tailrec from working. However, I don't know/remember enough about labelled blocks to be sure of the correct way to handle this.