From f96f42ca223826b9807bdf5ff4235a2144d13ede Mon Sep 17 00:00:00 2001 From: Allan Renucci Date: Mon, 1 Oct 2018 14:44:43 +0200 Subject: [PATCH] Fix handling of && and || in TailRec `Apply::fun` should not be transformed in tail position --- .../dotty/tools/dotc/transform/TailRec.scala | 2 +- tests/neg-tailcall/tailrec-and-or.scala | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/neg-tailcall/tailrec-and-or.scala diff --git a/compiler/src/dotty/tools/dotc/transform/TailRec.scala b/compiler/src/dotty/tools/dotc/transform/TailRec.scala index d91bf1d13dfd..405e3dd25cb7 100644 --- a/compiler/src/dotty/tools/dotc/transform/TailRec.scala +++ b/compiler/src/dotty/tools/dotc/transform/TailRec.scala @@ -276,7 +276,7 @@ class TailRec extends MiniPhase { case tree@Apply(fun, args) => val meth = fun.symbol if (meth == defn.Boolean_|| || meth == defn.Boolean_&&) - tpd.cpy.Apply(tree)(fun, transform(args)) + tpd.cpy.Apply(tree)(noTailTransform(fun), transform(args)) else rewriteApply(tree) diff --git a/tests/neg-tailcall/tailrec-and-or.scala b/tests/neg-tailcall/tailrec-and-or.scala new file mode 100644 index 000000000000..0a76c0f42524 --- /dev/null +++ b/tests/neg-tailcall/tailrec-and-or.scala @@ -0,0 +1,21 @@ +import annotation.tailrec + +class Test { + def cond: Boolean = ??? + + @tailrec final def tailCall1(x: Int): Boolean = + if (x < 0) tailCall1(0) + else tailCall1(x - 1) || cond // error + + @tailrec final def tailCall2(x: Int): Boolean = + if (x < 0) tailCall2(0) + else tailCall2(x - 1) && cond // error + + @tailrec final def tailCall3(x: Int): Boolean = + if (x < 0) tailCall3(0) + else cond || tailCall3(x - 1) + + @tailrec final def tailCall4(x: Int): Boolean = + if (x < 0) tailCall4(0) + else cond && tailCall4(x - 1) +}