From 83cef51e1c7f65c2a57a6117964d06eaa314500a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 28 May 2018 14:41:45 +0200 Subject: [PATCH] Fix #4591: Unpickle type quotes with TreeReader.readTpt --- .../dotc/core/quoted/PickledQuotes.scala | 27 +++++++++++-------- .../dotc/core/tasty/DottyUnpickler.scala | 3 +++ .../tools/dotc/core/tasty/TreeUnpickler.scala | 7 +++++ tests/run-with-compiler/i4591.check | 1 + tests/run-with-compiler/i4591.scala | 15 +++++++++++ 5 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 tests/run-with-compiler/i4591.check create mode 100644 tests/run-with-compiler/i4591.scala diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index faf50b5848a6..007e47e30a5f 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -66,13 +66,13 @@ object PickledQuotes { /** Unpickle the tree contained in the TastyExpr */ private def unpickleExpr(expr: TastyExpr[_])(implicit ctx: Context): Tree = { val tastyBytes = TastyString.unpickle(expr.tasty) - unpickle(tastyBytes, expr.args) + unpickle(tastyBytes, expr.args, isType = false) } /** Unpickle the tree contained in the TastyType */ private def unpickleType(ttpe: TastyType[_])(implicit ctx: Context): Tree = { val tastyBytes = TastyString.unpickle(ttpe.tasty) - unpickle(tastyBytes, ttpe.args) + unpickle(tastyBytes, ttpe.args, isType = true) } // TASTY picklingtests/pos/quoteTest.scala @@ -85,28 +85,33 @@ object PickledQuotes { treePkl.compactify() pickler.addrOfTree = treePkl.buf.addrOfTree pickler.addrOfSym = treePkl.addrOfSym - // if (tree.pos.exists) - // new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) - // other pickle sections go here. + if (pickling ne noPrinter) + println(i"**** pickling quote of \n${tree.show}") + val pickled = pickler.assembleParts() - if (pickling ne noPrinter) { - println(i"**** pickled quote of \n${tree.show}") + if (pickling ne noPrinter) new TastyPrinter(pickled).printContents() - } pickled } /** Unpickle TASTY bytes into it's tree */ - private def unpickle(bytes: Array[Byte], splices: Seq[Any])(implicit ctx: Context): Tree = { + private def unpickle(bytes: Array[Byte], splices: Seq[Any], isType: Boolean)(implicit ctx: Context): Tree = { val unpickler = new TastyUnpickler(bytes, splices) - val tree = unpickler.unpickleExpr() if (pickling ne noPrinter) { - println(i"**** unpickled quote for \n${tree.show}") + println(i"**** unpickling quote from TASTY") new TastyPrinter(bytes).printContents() } + + val tree = + if (isType) unpickler.unpickleTypeTree() + else unpickler.unpickleExpr() + + if (pickling ne noPrinter) + println(i"**** unpickle quote ${tree.show}") + tree } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala index 5dc92ee916df..91832b997877 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala @@ -49,6 +49,9 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded with t def unpickleExpr()(implicit ctx: Context): Tree = treeUnpickler.unpickleExpr() + def unpickleTypeTree()(implicit ctx: Context): Tree = + treeUnpickler.unpickleTypeTree() + protected def treeSectionUnpickler(posUnpicklerOpt: Option[PositionUnpickler]): TreeSectionUnpickler = { new TreeSectionUnpickler(posUnpicklerOpt) } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 1a8fd49a5d99..5b35002530f7 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -85,6 +85,13 @@ class TreeUnpickler(reader: TastyReader, rdr.readTerm() } + def unpickleTypeTree()(implicit ctx: Context): Tree = { + this.roots = Set(ctx.owner) + val rdr = new TreeReader(reader).fork + ownerTree = new OwnerTree(NoAddr, 0, rdr.fork, reader.endAddr) + rdr.readTpt() + } + /** The unpickled trees */ def unpickle()(implicit ctx: Context): List[Tree] = { assert(roots != null, "unpickle without previous enterTopLevel") diff --git a/tests/run-with-compiler/i4591.check b/tests/run-with-compiler/i4591.check new file mode 100644 index 000000000000..ee1eff6a5131 --- /dev/null +++ b/tests/run-with-compiler/i4591.check @@ -0,0 +1 @@ +Some(9) diff --git a/tests/run-with-compiler/i4591.scala b/tests/run-with-compiler/i4591.scala new file mode 100644 index 000000000000..ad5119618c96 --- /dev/null +++ b/tests/run-with-compiler/i4591.scala @@ -0,0 +1,15 @@ +import dotty.tools.dotc.quoted.Toolbox._ +import scala.quoted._ + +object Test { + + def foo[T: Type](init: Expr[T]): Expr[Unit] = '{ + var x = ~init + println(x) + } + + def main(args: Array[String]): Unit = { + foo('(Option(9))).run + } + +}