diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-05-31 23:49:52 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-07-10 10:44:20 +1000 |
commit | a90d1f01d603d9f00445ead48a87a051cd0ede15 (patch) | |
tree | acd71415af0d2a487ad7fa7b31afaa2fafe4fddd /test | |
parent | 07fc7bb2f718f335058ea84700778827747a6314 (diff) | |
download | scala-a90d1f01d603d9f00445ead48a87a051cd0ede15.tar.gz scala-a90d1f01d603d9f00445ead48a87a051cd0ede15.tar.bz2 scala-a90d1f01d603d9f00445ead48a87a051cd0ede15.zip |
SI-6574 Support @tailrec for extension methods.
Currently, when the body of an extension method is transplanted
to the companion object, recursive calls point back to the original
instance method. That changes during erasure, but this is too late
for tail call analysis/elimination.
This commit eagerly updates the recursive calls to point to the
extension method in the companion. It also removes the @tailrec
annotation from the original method.
Diffstat (limited to 'test')
-rw-r--r-- | test/files/neg/t6574.check | 7 | ||||
-rw-r--r-- | test/files/neg/t6574.scala | 10 | ||||
-rw-r--r-- | test/files/pos/t6574.scala | 19 | ||||
-rw-r--r-- | test/files/run/t6574b.check | 1 | ||||
-rw-r--r-- | test/files/run/t6574b.scala | 7 |
5 files changed, 44 insertions, 0 deletions
diff --git a/test/files/neg/t6574.check b/test/files/neg/t6574.check new file mode 100644 index 0000000000..c67b4ed804 --- /dev/null +++ b/test/files/neg/t6574.check @@ -0,0 +1,7 @@ +t6574.scala:4: error: could not optimize @tailrec annotated method notTailPos$extension: it contains a recursive call not in tail position + println("tail") + ^ +t6574.scala:8: error: could not optimize @tailrec annotated method differentTypeArgs$extension: it is called recursively with different type arguments + {(); new Bad[String, Unit](0)}.differentTypeArgs + ^ +two errors found diff --git a/test/files/neg/t6574.scala b/test/files/neg/t6574.scala new file mode 100644 index 0000000000..bba97ad62e --- /dev/null +++ b/test/files/neg/t6574.scala @@ -0,0 +1,10 @@ +class Bad[X, Y](val v: Int) extends AnyVal { + @annotation.tailrec final def notTailPos[Z](a: Int)(b: String) { + this.notTailPos[Z](a)(b) + println("tail") + } + + @annotation.tailrec final def differentTypeArgs { + {(); new Bad[String, Unit](0)}.differentTypeArgs + } +} diff --git a/test/files/pos/t6574.scala b/test/files/pos/t6574.scala new file mode 100644 index 0000000000..59c1701eb4 --- /dev/null +++ b/test/files/pos/t6574.scala @@ -0,0 +1,19 @@ +class Bad[X, Y](val v: Int) extends AnyVal { + def vv = v + @annotation.tailrec final def foo[Z](a: Int)(b: String) { + this.foo[Z](a)(b) + } + + @annotation.tailrec final def differentReceiver { + {(); new Bad[X, Y](0)}.differentReceiver + } + + @annotation.tailrec final def dependent[Z](a: Int)(b: String): b.type = { + this.dependent[Z](a)(b) + } +} + +class HK[M[_]](val v: Int) extends AnyVal { + def hk[N[_]]: Unit = if (false) hk[M] else () +} + diff --git a/test/files/run/t6574b.check b/test/files/run/t6574b.check new file mode 100644 index 0000000000..e10fa4f810 --- /dev/null +++ b/test/files/run/t6574b.check @@ -0,0 +1 @@ +List(5, 4, 3, 2, 1) diff --git a/test/files/run/t6574b.scala b/test/files/run/t6574b.scala new file mode 100644 index 0000000000..df329a31ca --- /dev/null +++ b/test/files/run/t6574b.scala @@ -0,0 +1,7 @@ +object Test extends App { + implicit class AnyOps(val i: Int) extends AnyVal { + private def parentsOf(x: Int): List[Int] = if (x == 0) Nil else x :: parentsOf(x - 1) + def parents: List[Int] = parentsOf(i) + } + println((5).parents) +} |