summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 8c582b1756..3c174d9b97 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -236,7 +236,7 @@ abstract class TailCalls extends Transform
case Return(expr) => super.transform(tree)
case Try(block, catches, finalizer) =>
- // no calls inside try are in tail position, but keep recursing for more nested functions
+ // no calls inside a try are in tail position, but keep recursing for nested functions
copy.Try(tree, transform(block, mkContext(ctx, false)),
transformTrees(catches, mkContext(ctx, false)).asInstanceOf[List[CaseDef]],
transform(finalizer, mkContext(ctx, false)))
@@ -252,7 +252,12 @@ abstract class TailCalls extends Transform
isSameTypes(ctx.tparams, targs map (_.tpe.typeSymbol)) &&
isRecursiveCall(fun)) {
fun match {
- case Select(receiver, _) => if (!forMSIL) rewriteTailCall(fun, receiver :: transformTrees(vargs, mkContext(ctx, false))) else defaultTree
+ case Select(receiver, _) =>
+ // make sure the type of 'this' doesn't change through this recursive call
+ if (!forMSIL && (receiver.tpe.widen == ctx.currentMethod.enclClass.typeOfThis))
+ rewriteTailCall(fun, receiver :: transformTrees(vargs, mkContext(ctx, false)))
+ else
+ defaultTree
case _ => rewriteTailCall(fun, This(currentClass) :: transformTrees(vargs, mkContext(ctx, false)))
}
} else
@@ -271,7 +276,11 @@ abstract class TailCalls extends Transform
ctx.tailPos &&
isRecursiveCall(fun)) {
fun match {
- case Select(receiver, _) => if (!forMSIL) rewriteTailCall(fun, receiver :: transformTrees(args, mkContext(ctx, false))) else defaultTree
+ case Select(receiver, _) =>
+ if (!forMSIL)
+ rewriteTailCall(fun, receiver :: transformTrees(args, mkContext(ctx, false)))
+ else
+ defaultTree
case _ => rewriteTailCall(fun, This(currentClass) :: transformTrees(args, mkContext(ctx, false)))
}
} else
@@ -303,8 +312,9 @@ abstract class TailCalls extends Transform
(fun.pos))
ctx.accessed = true
//println("fun: " + fun + " args: " + args)
- typed(atPos(fun.pos)(
- Apply(Ident(ctx.label), args)))
+ val t = atPos(fun.pos)(Apply(Ident(ctx.label), args))
+ //println(t)
+ typed(t)
}
private def isSameTypes(ts1: List[Symbol], ts2: List[Symbol]): Boolean = {