diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 56961c12c075..66954cc0120b 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -1,7 +1,7 @@ package dotty.tools.dotc.core.quoted import dotty.tools.dotc.ast.Trees._ -import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.ast.{TreeTypeMap, tpd} import dotty.tools.dotc.config.Printers._ import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts._ @@ -137,13 +137,12 @@ object PickledQuotes { def x1Ref() = ref(x1.symbol) def rec(f: Tree): Tree = f match { case closureDef(ddef) => - new TreeMap() { - private val paramSym = ddef.vparamss.head.head.symbol - override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = tree match { - case tree: Ident if tree.symbol == paramSym => x1Ref().withPos(tree.pos) - case _ => super.transform(tree) - } - }.transform(ddef.rhs) + val paramSym = ddef.vparamss.head.head.symbol + new TreeTypeMap( + oldOwners = ddef.symbol :: Nil, + newOwners = ctx.owner :: Nil, + treeMap = tree => if (tree.symbol == paramSym) x1Ref().withPos(tree.pos) else tree + ).transform(ddef.rhs) case Block(stats, expr) => val applied = rec(expr) if (stats.isEmpty) applied diff --git a/tests/run-with-compiler/quote-ackermann-1.check b/tests/run-with-compiler/quote-ackermann-1.check new file mode 100644 index 000000000000..c97bf28e0343 --- /dev/null +++ b/tests/run-with-compiler/quote-ackermann-1.check @@ -0,0 +1,4 @@ +13 +29 +61 +125 diff --git a/tests/run-with-compiler/quote-ackermann-1.scala b/tests/run-with-compiler/quote-ackermann-1.scala new file mode 100644 index 000000000000..9b4f06506236 --- /dev/null +++ b/tests/run-with-compiler/quote-ackermann-1.scala @@ -0,0 +1,25 @@ +import scala.quoted._ + +import dotty.tools.dotc.quoted.Toolbox._ + +object Test { + + def main(args: Array[String]): Unit = { + val ack3 = ackermann(3).run + println(ack3(1)) + println(ack3(2)) + println(ack3(3)) + println(ack3(4)) + } + + def ackermann(m: Int): Expr[Int => Int] = { + if (m == 0) '{ n => n + 1 } + else '{ n => + def `ackermann(m-1)`(n: Int): Int = ~ackermann(m - 1)('(n)) // Expr[Int => Int] applied to Expr[Int] + def `ackermann(m)`(n: Int): Int = + if (n == 0) `ackermann(m-1)`(1) else `ackermann(m-1)`(`ackermann(m)`(n - 1)) + `ackermann(m)`(n) + } + } + +}