summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2007-03-19 17:46:30 +0000
committerIulian Dragos <jaguarul@gmail.com>2007-03-19 17:46:30 +0000
commita694dd57cc8e0dadd3a1b7ec30a18dc4739c16f0 (patch)
treed150c43d9b6be5c85f71f2969a3c2dcb15d7c4e9
parenta600ff64fbb6a5397859496779177d6afdcc6e8b (diff)
downloadscala-a694dd57cc8e0dadd3a1b7ec30a18dc4739c16f0.tar.gz
scala-a694dd57cc8e0dadd3a1b7ec30a18dc4739c16f0.tar.bz2
scala-a694dd57cc8e0dadd3a1b7ec30a18dc4739c16f0.zip
Catch tail calls made from tail boolean or.
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala4
-rw-r--r--test/files/run/tailcalls.check1
-rw-r--r--test/files/run/tailcalls.scala22
3 files changed, 26 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 1fc2f43e3e..02735d0609 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -236,7 +236,9 @@ abstract class TailCalls extends Transform
case TypeApply(fun, args) =>
super.transform(tree)
-// throw new RuntimeException("Lonely TypeApply found -- we can only handle them inside Apply(TypeApply()): " + tree + " at: " + unit);
+
+ case Apply(fun, args) if fun.symbol == definitions.Boolean_or =>
+ copy.Apply(tree, fun, transformTrees(args));
case Apply(fun, args) =>
if (ctx.currentMethod.isFinal &&
diff --git a/test/files/run/tailcalls.check b/test/files/run/tailcalls.check
index 83ea0b3760..49af1207a0 100644
--- a/test/files/run/tailcalls.check
+++ b/test/files/run/tailcalls.check
@@ -48,3 +48,4 @@ test TailCall.h1 was successful
test NonTailCall.f1 0 1 2 was successful
test NonTailCall.f2 was successful
+test TailCall.b1 was successful
diff --git a/test/files/run/tailcalls.scala b/test/files/run/tailcalls.scala
index b20fbb20f4..87a14b3f53 100644
--- a/test/files/run/tailcalls.scala
+++ b/test/files/run/tailcalls.scala
@@ -180,6 +180,9 @@ class TailCall[S](s: S) {
aux(x, y, Nil);
}
+ final def b1(x: Int): Boolean =
+ (x == 1) || b1(x - 1)
+
def h1(n: Int, v: Int): Int = hP(n, v);
private def hP(n: Int, v: Int): Int = if (n == 0) v else hP(n - 1, v - 1);
@@ -226,6 +229,23 @@ object Test {
Console.println;
}
+ def check_success_b(name: String, closure: => Boolean, expected: Boolean): Unit = {
+ Console.print("test " + name);
+ try {
+ val actual: Boolean = closure;
+ if (actual == expected) {
+ Console.print(" was successful");
+ } else {
+ Console.print(" failed: expected "+ expected +", found "+ actual);
+ }
+ } catch {
+ case exception: Throwable => {
+ Console.print(" raised exception " + exception);
+ }
+ }
+ Console.println;
+ }
+
def check_overflow(name: String, closure: => Int): Unit = {
Console.print("test " + name);
try {
@@ -323,6 +343,8 @@ object Test {
val NonTailCall = new NonTailCall;
check_success("NonTailCall.f1", NonTailCall.f1(2), 0)
check_overflow("NonTailCall.f2", NonTailCall.f2(max))
+
+ check_success_b("TailCall.b1", TailCall.b1(max), true);
}
}