From 9cfa54713d3ce307fb54674794c0c11e16545c22 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 19 Mar 2018 14:35:12 +0100 Subject: [PATCH 1/3] Fix owners of AsFunction applied expressions --- .../dotc/core/quoted/PickledQuotes.scala | 2 +- .../run-with-compiler/quote-ackermann-1.check | 1 + .../run-with-compiler/quote-ackermann-1.scala | 21 +++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/run-with-compiler/quote-ackermann-1.check create mode 100644 tests/run-with-compiler/quote-ackermann-1.scala diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 56961c12c075..451deac4351b 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -143,7 +143,7 @@ object PickledQuotes { case tree: Ident if tree.symbol == paramSym => x1Ref().withPos(tree.pos) case _ => super.transform(tree) } - }.transform(ddef.rhs) + }.transform(ddef.rhs).changeOwner(ddef.symbol, ctx.owner) 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..d136d6a71426 --- /dev/null +++ b/tests/run-with-compiler/quote-ackermann-1.check @@ -0,0 +1 @@ +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..279f2860b827 --- /dev/null +++ b/tests/run-with-compiler/quote-ackermann-1.scala @@ -0,0 +1,21 @@ +import scala.quoted._ + +import dotty.tools.dotc.quoted.Toolbox._ + +object Test { + + def main(args: Array[String]): Unit = { + println(ackermann(3)(4).run) + } + + 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) + } + } + +} From acc662e3b8431b38645c87a93fbfce6cd1f9957b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 19 Mar 2018 14:52:34 +0100 Subject: [PATCH 2/3] Use TreeTypeMap to change owners at tree transformation time --- .../tools/dotc/core/quoted/PickledQuotes.scala | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 451deac4351b..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).changeOwner(ddef.symbol, ctx.owner) + 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 From 6b1432c6c8e08df13fba6307ad20be9f15d2584f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 20 Mar 2018 10:16:08 +0100 Subject: [PATCH 3/3] Fix code that bug due to silent implicit conversion --- tests/run-with-compiler/quote-ackermann-1.check | 3 +++ tests/run-with-compiler/quote-ackermann-1.scala | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/run-with-compiler/quote-ackermann-1.check b/tests/run-with-compiler/quote-ackermann-1.check index d136d6a71426..c97bf28e0343 100644 --- a/tests/run-with-compiler/quote-ackermann-1.check +++ b/tests/run-with-compiler/quote-ackermann-1.check @@ -1 +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 index 279f2860b827..9b4f06506236 100644 --- a/tests/run-with-compiler/quote-ackermann-1.scala +++ b/tests/run-with-compiler/quote-ackermann-1.scala @@ -5,7 +5,11 @@ import dotty.tools.dotc.quoted.Toolbox._ object Test { def main(args: Array[String]): Unit = { - println(ackermann(3)(4).run) + val ack3 = ackermann(3).run + println(ack3(1)) + println(ack3(2)) + println(ack3(3)) + println(ack3(4)) } def ackermann(m: Int): Expr[Int => Int] = {