Skip to content

Spurious tailrec error "Cannot rewrite recursive call: it is not in tail position" because of asInstanceOf cast inserted by typer #8712

Closed
@smarter

Description

@smarter

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions