You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importscala.annotation.tailrecsealedtraitFoo[+A]
caseclassBar[A](f: Foo[A]) extendsFoo[A]
caseclassDone[A](a: A) extendsFoo[A]
objectTest {
@tailrec
defrunT[A](c: Foo[A]):A= c match {
caseBar(f) => runT(f)
caseDone(a) => a
}
}
Output
--Error:try/tr.scala:10:23---------------------------------------------------10|caseBar(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
{
casevalx14:Bar=Bar.unapply(x9.asInstanceOf[Bar])
casevalx15:Foo= x14._1()
casevalf: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.
The text was updated successfully, but these errors were encountered:
It should prevent tailrec from working. An asInstanceOf is a real operation that requires something to happen.
However, in this case the asInstanceOf[Object] is completely useless. Obviously because everything is an Object, but in general expr.asInstanceOf[T] is useless if the type of expr is <: T according to the JVM type system.
Erasure is to blame here for inserting this useless cast. If it didn't insert that cast, tailrec would be able to do its job.
smarter
changed the title
Spurious tailrec error "Cannot rewrite recursive call: it is not in tail position" because of asInstanceOf cast inserted by erasure
Spurious tailrec error "Cannot rewrite recursive call: it is not in tail position" because of asInstanceOf cast inserted by typer
Apr 12, 2020
We can get rid of `asInstanceOf[T]` whenever the erased type of
expression is a subtype of T. This allows us to produce leaner bytecode
and also fixesscala#8712 since unnecessary asInstanceOf calls were
preventing tailrec from working.
Uh oh!
There was an error while loading. Please reload this page.
Minimized code
Output
The problem comes from the tree we get after erasure:
runT
is indeed not in tail position since it's followed by anasInstanceOf
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.The text was updated successfully, but these errors were encountered: