From e05dfaeabf430dac8909ff9e5a5911b0c94101ae Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 10 Jan 2011 07:21:56 +0000 Subject: A pretty severe bug in the recognition of tail ... A pretty severe bug in the recognition of tail call elimination. It turns out that Tailcalls will perform "partial elimination" in situations such as: @annotation.tailrec final def f(x: Int): Int = f(f(x)) The outer call to f1 becomes a jump, but the inner call remains as it was. I implemented @tailrec under the impression that if the optimization had taken place, it had gone all the way. So this is now fixed with a direct examination of the rewritten tree. While I was in there I threw in some improved error reporting: the error positioning is now on the call which is not in tail position rather than the method declaration. Closes #4135, no review. --- test/files/neg/tailrec.check | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'test/files/neg/tailrec.check') diff --git a/test/files/neg/tailrec.check b/test/files/neg/tailrec.check index 27d99f632e..f6865b2f9d 100644 --- a/test/files/neg/tailrec.check +++ b/test/files/neg/tailrec.check @@ -1,16 +1,16 @@ -tailrec.scala:43: error: could not optimize @tailrec annotated method: it contains a recursive call not in tail position - def facfail(n: Int): Int = - ^ -tailrec.scala:50: error: could not optimize @tailrec annotated method: it is neither private nor final so can be overridden +tailrec.scala:45: error: could not optimize @tailrec annotated method facfail: it contains a recursive call not in tail position + else n * facfail(n - 1) + ^ +tailrec.scala:50: error: could not optimize @tailrec annotated method fail1: it is neither private nor final so can be overridden @tailrec def fail1(x: Int): Int = fail1(x) - ^ -tailrec.scala:53: error: could not optimize @tailrec annotated method: it contains a recursive call not in tail position - @tailrec final def fail2[T](xs: List[T]): List[T] = xs match { - ^ -tailrec.scala:59: error: could not optimize @tailrec annotated method: it is called recursively with different type arguments + ^ +tailrec.scala:55: error: could not optimize @tailrec annotated method fail2: it contains a recursive call not in tail position + case x :: xs => x :: fail2[T](xs) + ^ +tailrec.scala:59: error: could not optimize @tailrec annotated method fail3: it is called recursively with different type arguments @tailrec final def fail3[T](x: Int): Int = fail3(x - 1) - ^ -tailrec.scala:63: error: could not optimize @tailrec annotated method: it changes type of 'this' on a polymorphic recursive call + ^ +tailrec.scala:63: error: could not optimize @tailrec annotated method fail4: it changes type of 'this' on a polymorphic recursive call @tailrec final def fail4[U](other: Tom[U], x: Int): Int = other.fail4[U](other, x - 1) - ^ + ^ 5 errors found -- cgit v1.2.3