From fec41ea3d4bdaf1971422bb3e38cc18b0f1e7982 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Sun, 21 Jan 2018 20:45:49 +0100 Subject: [PATCH 1/8] Move library implemtations of Quoted to one place --- .../dotc/core/quoted/PickledQuotes.scala | 12 +++--- .../src/dotty/tools/dotc/quoted/Runners.scala | 2 +- library/src/scala/quoted/Expr.scala | 2 +- library/src/scala/quoted/Liftable.scala | 6 +-- library/src/scala/quoted/Quoted.scala | 42 +++++++++++++++++++ library/src/scala/quoted/TastyExpr.scala | 8 ---- library/src/scala/quoted/TastyQuoted.scala | 9 ---- library/src/scala/quoted/TastyType.scala | 8 ---- library/src/scala/quoted/Type.scala | 25 +++++------ .../src/scala/runtime/quoted/Unpickler.scala | 3 +- 10 files changed, 65 insertions(+), 52 deletions(-) delete mode 100644 library/src/scala/quoted/TastyExpr.scala delete mode 100644 library/src/scala/quoted/TastyQuoted.scala delete mode 100644 library/src/scala/quoted/TastyType.scala diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 2e0aa50e6c2a..cb60fa48c14f 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -13,6 +13,8 @@ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.tasty.{TastyPickler, TastyPrinter, TastyString} import dotty.tools.dotc.interpreter.RawQuoted +import scala.quoted.Quoted._ + import scala.reflect.ClassTag object PickledQuotes { @@ -30,20 +32,20 @@ object PickledQuotes { /** Transform the expression into its fully spliced Tree */ def quotedToTree(expr: quoted.Quoted)(implicit ctx: Context): Tree = expr match { - case expr: quoted.TastyQuoted => + case expr: TastyQuoted => unpickleQuote(expr) - case expr: quoted.Liftable.ConstantExpr[_] => + case expr: ConstantExpr[_] => Literal(Constant(expr.value)) - case expr: quoted.Expr.FunctionAppliedTo[_, _] => + case expr: FunctionAppliedTo[_, _] => functionAppliedTo(quotedToTree(expr.f), quotedToTree(expr.x)) - case expr: quoted.Type.TaggedPrimitive[_] => + case expr: TaggedType[_] => classTagToTypeTree(expr.ct) case expr: RawQuoted => expr.tree } /** Unpickle the tree contained in the TastyQuoted */ - private def unpickleQuote(expr: quoted.TastyQuoted)(implicit ctx: Context): Tree = { + private def unpickleQuote(expr: TastyQuoted)(implicit ctx: Context): Tree = { val tastyBytes = TastyString.unpickle(expr.tasty) val unpickled = unpickle(tastyBytes, expr.args) unpickled match { diff --git a/compiler/src/dotty/tools/dotc/quoted/Runners.scala b/compiler/src/dotty/tools/dotc/quoted/Runners.scala index 1bd66050f515..265e49fe1f7f 100644 --- a/compiler/src/dotty/tools/dotc/quoted/Runners.scala +++ b/compiler/src/dotty/tools/dotc/quoted/Runners.scala @@ -6,8 +6,8 @@ import dotty.tools.dotc.core.Constants._ import dotty.tools.dotc.printing.RefinedPrinter import scala.quoted.Expr -import scala.quoted.Liftable.ConstantExpr import scala.runtime.BoxedUnit +import scala.quoted.Quoted.ConstantExpr import scala.runtime.quoted._ /** Default runners for quoted expressions */ diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index c8cc488e0f29..6cd536e9ad71 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -1,5 +1,6 @@ package scala.quoted +import scala.quoted.Quoted.FunctionAppliedTo import scala.runtime.quoted.Runner abstract class Expr[T] extends Quoted { @@ -16,5 +17,4 @@ object Expr { def apply(x: Expr[T]): Expr[U] = new FunctionAppliedTo[T, U](f, x) } - final class FunctionAppliedTo[T, U] private[Expr](val f: Expr[T => U], val x: Expr[T]) extends Expr[U] } diff --git a/library/src/scala/quoted/Liftable.scala b/library/src/scala/quoted/Liftable.scala index a802dda0bd22..2249912c80ba 100644 --- a/library/src/scala/quoted/Liftable.scala +++ b/library/src/scala/quoted/Liftable.scala @@ -1,5 +1,7 @@ package scala.quoted +import scala.quoted.Quoted.ConstantExpr + /** A typeclass for types that can be turned to `quoted.Expr[T]` * without going through an explicit `'(...)` operation. */ @@ -18,10 +20,6 @@ object Liftable { def toExpr(implicit liftable: Liftable[T]): Expr[T] = liftable.toExpr(x) } - final class ConstantExpr[T] private[Liftable](val value: T) extends Expr[T] { - override def toString: String = s"Expr($value)" - } - implicit def UnitIsLiftable: Liftable[Unit] = (x: Unit) => new ConstantExpr(x) implicit def BooleanIsLiftable: Liftable[Boolean] = (x: Boolean) => new ConstantExpr(x) implicit def ByteLiftable: Liftable[Byte] = (x: Byte) => new ConstantExpr(x) diff --git a/library/src/scala/quoted/Quoted.scala b/library/src/scala/quoted/Quoted.scala index 537dd6221d51..d02c34116e07 100644 --- a/library/src/scala/quoted/Quoted.scala +++ b/library/src/scala/quoted/Quoted.scala @@ -1,4 +1,46 @@ package scala.quoted +import scala.reflect.ClassTag +import scala.runtime.quoted.Unpickler.Pickled + /** Common superclass of Expr and Type */ abstract class Quoted + +object Quoted { + + /** A quote backed by a pickled TASTY tree */ + trait TastyQuoted extends Quoted { + def tasty: Pickled + def args: Seq[Any] + } + + // Implementations of Expr[T] + + /** An Expr backed by a pickled TASTY tree */ + final class TastyExpr[T](val tasty: Pickled, val args: Seq[Any]) extends Expr[T] with TastyQuoted { + override def toString(): String = s"Expr()" + } + + /** An Expr backed by a value */ + final class ConstantExpr[T](val value: T) extends Expr[T] { + override def toString: String = s"Expr($value)" + } + + /** An Expr representing `'{(~f).apply(~x)}` but it is beta-reduced when the closure is known */ + final class FunctionAppliedTo[T, U](val f: Expr[T => U], val x: Expr[T]) extends Expr[U] { + override def toString: String = s"Expr($f $x)" + } + + // Implementations of Type[T] + + /** A Type backed by a pickled TASTY tree */ + final class TastyType[T](val tasty: Pickled, val args: Seq[Any]) extends Type[T] with TastyQuoted { + override def toString(): String = s"Type()" + } + + /** An Type backed by a value */ + final class TaggedType[T](implicit val ct: ClassTag[T]) extends Type[T] { + override def toString: String = s"Type($ct)" + } + +} diff --git a/library/src/scala/quoted/TastyExpr.scala b/library/src/scala/quoted/TastyExpr.scala deleted file mode 100644 index 219ea5d924d7..000000000000 --- a/library/src/scala/quoted/TastyExpr.scala +++ /dev/null @@ -1,8 +0,0 @@ -package scala.quoted - -import scala.runtime.quoted.Unpickler.Pickled - -/** An Expr backed by a pickled TASTY tree */ -final class TastyExpr[T](val tasty: Pickled, val args: Seq[Any]) extends Expr[T] with TastyQuoted { - override def toString(): String = s"Expr()" -} diff --git a/library/src/scala/quoted/TastyQuoted.scala b/library/src/scala/quoted/TastyQuoted.scala deleted file mode 100644 index 729fedd9a998..000000000000 --- a/library/src/scala/quoted/TastyQuoted.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.quoted - -import scala.runtime.quoted.Unpickler.Pickled - -/** A quote backed by a pickled TASTY tree */ -trait TastyQuoted extends Quoted { - def tasty: Pickled - def args: Seq[Any] -} diff --git a/library/src/scala/quoted/TastyType.scala b/library/src/scala/quoted/TastyType.scala deleted file mode 100644 index 2301466e9a9d..000000000000 --- a/library/src/scala/quoted/TastyType.scala +++ /dev/null @@ -1,8 +0,0 @@ -package scala.quoted - -import scala.runtime.quoted.Unpickler.Pickled - -/** A Type backed by a pickled TASTY tree */ -final class TastyType[T](val tasty: Pickled, val args: Seq[Any]) extends Type[T] with TastyQuoted { - override def toString(): String = s"Type()" -} diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index 068df6478d96..4e33eaedf417 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -1,6 +1,6 @@ package scala.quoted -import scala.reflect.ClassTag +import scala.quoted.Quoted.TaggedType abstract class Type[T] extends Quoted { type unary_~ = T @@ -8,18 +8,13 @@ abstract class Type[T] extends Quoted { /** Some basic type tags, currently incomplete */ object Type { - - final class TaggedPrimitive[T] private[Type] (implicit val ct: ClassTag[T]) extends Type[T] { - override def toString: String = s"Type($ct)" - } - - implicit def UnitTag: Type[Unit] = new TaggedPrimitive[Unit] - implicit def BooleanTag: Type[Boolean] = new TaggedPrimitive[Boolean] - implicit def ByteTag: Type[Byte] = new TaggedPrimitive[Byte] - implicit def CharTag: Type[Char] = new TaggedPrimitive[Char] - implicit def ShortTag: Type[Short] = new TaggedPrimitive[Short] - implicit def IntTag: Type[Int] = new TaggedPrimitive[Int] - implicit def LongTag: Type[Long] = new TaggedPrimitive[Long] - implicit def FloatTag: Type[Float] = new TaggedPrimitive[Float] - implicit def DoubleTag: Type[Double] = new TaggedPrimitive[Double] + implicit def UnitTag: Type[Unit] = new TaggedType[Unit] + implicit def BooleanTag: Type[Boolean] = new TaggedType[Boolean] + implicit def ByteTag: Type[Byte] = new TaggedType[Byte] + implicit def CharTag: Type[Char] = new TaggedType[Char] + implicit def ShortTag: Type[Short] = new TaggedType[Short] + implicit def IntTag: Type[Int] = new TaggedType[Int] + implicit def LongTag: Type[Long] = new TaggedType[Long] + implicit def FloatTag: Type[Float] = new TaggedType[Float] + implicit def DoubleTag: Type[Double] = new TaggedType[Double] } diff --git a/library/src/scala/runtime/quoted/Unpickler.scala b/library/src/scala/runtime/quoted/Unpickler.scala index 5bd07b140cd2..08b70936fb68 100644 --- a/library/src/scala/runtime/quoted/Unpickler.scala +++ b/library/src/scala/runtime/quoted/Unpickler.scala @@ -1,6 +1,7 @@ package scala.runtime.quoted -import scala.quoted._ +import scala.quoted.Quoted.{TastyExpr, TastyType} +import scala.quoted.{Expr, Type} /** Provides methods to unpickle `Expr` and `Type` trees. */ object Unpickler { From f129f7efaa47839edd999f7588af264536a7dec2 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 22 Jan 2018 08:17:40 +0100 Subject: [PATCH 2/8] Move RawQuoted to library --- .../dotc/core/quoted/PickledQuotes.scala | 25 ++++++++++--------- .../tools/dotc/core/tasty/TreeUnpickler.scala | 25 +++++++++++++------ .../tools/dotc/interpreter/Interpreter.scala | 4 ++- .../tools/dotc/interpreter/RawQuoted.scala | 22 ---------------- .../tools/dotc/quoted/ExprCompiler.scala | 4 +-- .../dotty/tools/dotc/transform/Splicer.scala | 2 +- library/src/scala/quoted/Quoted.scala | 14 +++++++++++ 7 files changed, 50 insertions(+), 46 deletions(-) delete mode 100644 compiler/src/dotty/tools/dotc/interpreter/RawQuoted.scala diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index cb60fa48c14f..b6a37fc70d50 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -7,11 +7,10 @@ import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts._ import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags._ -import dotty.tools.dotc.core.NameKinds import dotty.tools.dotc.core.StdNames._ +import dotty.tools.dotc.core.NameKinds import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.tasty.{TastyPickler, TastyPrinter, TastyString} -import dotty.tools.dotc.interpreter.RawQuoted import scala.quoted.Quoted._ @@ -31,17 +30,19 @@ object PickledQuotes { } /** Transform the expression into its fully spliced Tree */ - def quotedToTree(expr: quoted.Quoted)(implicit ctx: Context): Tree = expr match { - case expr: TastyQuoted => - unpickleQuote(expr) - case expr: ConstantExpr[_] => - Literal(Constant(expr.value)) + def quotedExprToTree(expr: quoted.Expr[_])(implicit ctx: Context): Tree = expr match { + case expr: TastyExpr[_] => unpickleQuote(expr) + case expr: ConstantExpr[_] => Literal(Constant(expr.value)) + case expr: RawExpr[Tree] @unchecked => expr.tree case expr: FunctionAppliedTo[_, _] => - functionAppliedTo(quotedToTree(expr.f), quotedToTree(expr.x)) - case expr: TaggedType[_] => - classTagToTypeTree(expr.ct) - case expr: RawQuoted => - expr.tree + functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x)) + } + + /** Transform the expression into its fully spliced TypeTree */ + def quotedTypeToTree(expr: quoted.Type[_])(implicit ctx: Context): Tree = expr match { + case expr: TastyType[_] => unpickleQuote(expr) + case expr: TaggedType[_] => classTagToTypeTree(expr.ct) + case expr: RawType[Tree] @unchecked => expr.tree } /** Unpickle the tree contained in the TastyQuoted */ diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 7debff863d65..d49f9e08d2ee 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -20,8 +20,8 @@ import config.Printers.pickling import typer.Checking import config.Config import dotty.tools.dotc.core.quoted.PickledQuotes -import dotty.tools.dotc.interpreter.RawQuoted import scala.quoted +import scala.quoted.Quoted.{RawExpr, RawType} /** Unpickler for typed trees * @param reader the reader from which to unpickle @@ -296,7 +296,7 @@ class TreeUnpickler(reader: TastyReader, case ENUMconst => ConstantType(Constant(readTermRef().termSymbol)) case HOLE => - readHole(end).tpe + readHole(end, isType = true).tpe } assert(currentAddr == end, s"$start $currentAddr $end ${astTagToString(tag)}") result @@ -1076,7 +1076,7 @@ class TreeUnpickler(reader: TastyReader, val hi = if (currentAddr == end) lo else readTpt() TypeBoundsTree(lo, hi) case HOLE => - readHole(end) + readHole(end, isType = false) case _ => readPathTerm() } @@ -1127,14 +1127,23 @@ class TreeUnpickler(reader: TastyReader, new LazyReader(localReader, op) } - def readHole(end: Addr)(implicit ctx: Context): Tree = { + def readHole(end: Addr, isType: Boolean)(implicit ctx: Context): Tree = { val idx = readNat() val args = until(end)(readTerm()) val splice = splices(idx) - val quotedType = - if (args.isEmpty) splice.asInstanceOf[quoted.Quoted] - else splice.asInstanceOf[Seq[Any] => quoted.Quoted](args.map(RawQuoted.apply)) - PickledQuotes.quotedToTree(quotedType) + + if (isType) { + val quotedType = + if (args.isEmpty) splice.asInstanceOf[quoted.Type[_]] + else splice.asInstanceOf[Seq[Any] => quoted.Type[_]](args.map(tree => new RawType(tree))) + PickledQuotes.quotedTypeToTree(quotedType) + } else { + val quotedExpr = + if (args.isEmpty) splice.asInstanceOf[quoted.Expr[_]] + else splice.asInstanceOf[Seq[Any] => quoted.Expr[_]](args.map(tree => new RawExpr(tree))) + PickledQuotes.quotedExprToTree(quotedExpr) + } + } // ------ Setting positions ------------------------------------------------ diff --git a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala index 5fa447af602d..8150bd50e762 100644 --- a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala +++ b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala @@ -72,7 +72,9 @@ class Interpreter(implicit ctx: Context) { implicit val pos: Position = tree.pos tree match { - case Quoted(quotedTree) => RawQuoted(quotedTree) + case Quoted(quotedTree) => + if (tree.isTerm) new scala.quoted.Quoted.RawExpr(quotedTree) + else new scala.quoted.Quoted.RawType(quotedTree) case Literal(Constant(c)) => c.asInstanceOf[Object] diff --git a/compiler/src/dotty/tools/dotc/interpreter/RawQuoted.scala b/compiler/src/dotty/tools/dotc/interpreter/RawQuoted.scala deleted file mode 100644 index db669d0c5f5e..000000000000 --- a/compiler/src/dotty/tools/dotc/interpreter/RawQuoted.scala +++ /dev/null @@ -1,22 +0,0 @@ -package dotty.tools.dotc.interpreter - -import dotty.tools.dotc.ast.tpd - -/** Quoted `quoted.Quoted` for which its internal representation is its tree. - * - Used for trees that cannot be serialized, such as references to local symbols that will be spliced in. - * - Used for trees that do not need to be serialized to avoid the overhead of serialization/deserialization. - */ -trait RawQuoted extends quoted.Quoted { - def tree: tpd.Tree - override def toString: String = s"${this.getClass.getName}(${tree.toString})" -} - -object RawQuoted { - - def apply(tree: tpd.Tree): RawQuoted = - if (tree.isTerm) new RawExpr(tree) - else new RawType(tree) - - private final class RawExpr(val tree: tpd.Tree) extends quoted.Expr[Any] with RawQuoted - private final class RawType(val tree: tpd.Tree) extends quoted.Type[Any] with RawQuoted -} diff --git a/compiler/src/dotty/tools/dotc/quoted/ExprCompiler.scala b/compiler/src/dotty/tools/dotc/quoted/ExprCompiler.scala index 5bbc9bfd157d..fb782c031543 100644 --- a/compiler/src/dotty/tools/dotc/quoted/ExprCompiler.scala +++ b/compiler/src/dotty/tools/dotc/quoted/ExprCompiler.scala @@ -61,7 +61,7 @@ class ExprCompiler(directory: AbstractFile) extends Compiler { case exprUnit: ExprCompilationUnit => val tree = if (putInClass) inClass(exprUnit.expr) - else PickledQuotes.quotedToTree(exprUnit.expr) + else PickledQuotes.quotedExprToTree(exprUnit.expr) val source = new SourceFile("", Seq()) CompilationUnit.mkCompilationUnit(source, tree, forceTrees = true) } @@ -80,7 +80,7 @@ class ExprCompiler(directory: AbstractFile) extends Compiler { cls.enter(ctx.newDefaultConstructor(cls), EmptyScope) val meth = ctx.newSymbol(cls, nme.apply, Method, ExprType(defn.AnyType), coord = pos).entered - val quoted = PickledQuotes.quotedToTree(expr)(ctx.withOwner(meth)) + val quoted = PickledQuotes.quotedExprToTree(expr)(ctx.withOwner(meth)) val run = DefDef(meth, quoted) val classTree = ClassDef(cls, DefDef(cls.primaryConstructor.asTerm), run :: Nil) diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index 6e05b9d85873..b24357a934bd 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -24,7 +24,7 @@ object Splicer { /** Splice the Tree for a Quoted expression which is constructed via a reflective call to the given method */ private def reflectiveSplice(tree: Tree)(implicit ctx: Context): Tree = { val interpreter = new Interpreter - interpreter.interpretTree[scala.quoted.Expr[_]](tree).map(PickledQuotes.quotedToTree(_)).getOrElse(tree) + interpreter.interpretTree[scala.quoted.Expr[_]](tree).map(PickledQuotes.quotedExprToTree).getOrElse(tree) } } diff --git a/library/src/scala/quoted/Quoted.scala b/library/src/scala/quoted/Quoted.scala index d02c34116e07..40bad1373f21 100644 --- a/library/src/scala/quoted/Quoted.scala +++ b/library/src/scala/quoted/Quoted.scala @@ -14,6 +14,14 @@ object Quoted { def args: Seq[Any] } + /** Quoted for which its internal representation is its tree. + * - Used for trees that cannot be serialized, such as references to local symbols that will be spliced in. + * - Used for trees that do not need to be serialized to avoid the overhead of serialization/deserialization. + */ + trait RawQuoted[Tree] extends quoted.Quoted { + def tree: Tree + } + // Implementations of Expr[T] /** An Expr backed by a pickled TASTY tree */ @@ -26,6 +34,9 @@ object Quoted { override def toString: String = s"Expr($value)" } + /** An Expr backed by a tree */ + final class RawExpr[Tree](val tree: Tree) extends quoted.Expr[Any] with RawQuoted[Tree] + /** An Expr representing `'{(~f).apply(~x)}` but it is beta-reduced when the closure is known */ final class FunctionAppliedTo[T, U](val f: Expr[T => U], val x: Expr[T]) extends Expr[U] { override def toString: String = s"Expr($f $x)" @@ -43,4 +54,7 @@ object Quoted { override def toString: String = s"Type($ct)" } + /** An Type backed by a tree */ + final class RawType[Tree](val tree: Tree) extends quoted.Type[Any] with RawQuoted[Tree] + } From 4c628cc9458daaa99518006d64003b564ae5e596 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 22 Jan 2018 08:27:03 +0100 Subject: [PATCH 3/8] Remove TastyQuoted and RawQuoted abstractions --- .../dotc/core/quoted/PickledQuotes.scala | 20 +++++++++----- library/src/scala/quoted/Quoted.scala | 26 ++++++------------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index b6a37fc70d50..3e69923fb620 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -31,7 +31,7 @@ object PickledQuotes { /** Transform the expression into its fully spliced Tree */ def quotedExprToTree(expr: quoted.Expr[_])(implicit ctx: Context): Tree = expr match { - case expr: TastyExpr[_] => unpickleQuote(expr) + case expr: TastyExpr[_] => unpickleExpr(expr) case expr: ConstantExpr[_] => Literal(Constant(expr.value)) case expr: RawExpr[Tree] @unchecked => expr.tree case expr: FunctionAppliedTo[_, _] => @@ -40,19 +40,27 @@ object PickledQuotes { /** Transform the expression into its fully spliced TypeTree */ def quotedTypeToTree(expr: quoted.Type[_])(implicit ctx: Context): Tree = expr match { - case expr: TastyType[_] => unpickleQuote(expr) + case expr: TastyType[_] => unpickleType(expr) case expr: TaggedType[_] => classTagToTypeTree(expr.ct) case expr: RawType[Tree] @unchecked => expr.tree } - /** Unpickle the tree contained in the TastyQuoted */ - private def unpickleQuote(expr: TastyQuoted)(implicit ctx: Context): Tree = { + /** Unpickle the tree contained in the TastyExpr */ + private def unpickleExpr(expr: TastyExpr[_])(implicit ctx: Context): Tree = { val tastyBytes = TastyString.unpickle(expr.tasty) val unpickled = unpickle(tastyBytes, expr.args) + unpickled match { + case PackageDef(_, (vdef: ValDef) :: Nil) => vdef.rhs + } + } + + /** Unpickle the tree contained in the TastyType */ + private def unpickleType(ttpe: TastyType[_])(implicit ctx: Context): Tree = { + val tastyBytes = TastyString.unpickle(ttpe.tasty) + val unpickled = unpickle(tastyBytes, ttpe.args) unpickled match { case PackageDef(_, (vdef: ValDef) :: Nil) => - if (vdef.name == "$quote".toTermName) vdef.rhs - else vdef.rhs.asInstanceOf[TypeApply].args.head + vdef.rhs.asInstanceOf[TypeApply].args.head } } diff --git a/library/src/scala/quoted/Quoted.scala b/library/src/scala/quoted/Quoted.scala index 40bad1373f21..49f58de2f4c5 100644 --- a/library/src/scala/quoted/Quoted.scala +++ b/library/src/scala/quoted/Quoted.scala @@ -8,24 +8,10 @@ abstract class Quoted object Quoted { - /** A quote backed by a pickled TASTY tree */ - trait TastyQuoted extends Quoted { - def tasty: Pickled - def args: Seq[Any] - } - - /** Quoted for which its internal representation is its tree. - * - Used for trees that cannot be serialized, such as references to local symbols that will be spliced in. - * - Used for trees that do not need to be serialized to avoid the overhead of serialization/deserialization. - */ - trait RawQuoted[Tree] extends quoted.Quoted { - def tree: Tree - } - // Implementations of Expr[T] /** An Expr backed by a pickled TASTY tree */ - final class TastyExpr[T](val tasty: Pickled, val args: Seq[Any]) extends Expr[T] with TastyQuoted { + final class TastyExpr[T](val tasty: Pickled, val args: Seq[Any]) extends Expr[T] { override def toString(): String = s"Expr()" } @@ -35,7 +21,9 @@ object Quoted { } /** An Expr backed by a tree */ - final class RawExpr[Tree](val tree: Tree) extends quoted.Expr[Any] with RawQuoted[Tree] + final class RawExpr[Tree](val tree: Tree) extends quoted.Expr[Any] { + override def toString: String = s"Expr()" + } /** An Expr representing `'{(~f).apply(~x)}` but it is beta-reduced when the closure is known */ final class FunctionAppliedTo[T, U](val f: Expr[T => U], val x: Expr[T]) extends Expr[U] { @@ -45,7 +33,7 @@ object Quoted { // Implementations of Type[T] /** A Type backed by a pickled TASTY tree */ - final class TastyType[T](val tasty: Pickled, val args: Seq[Any]) extends Type[T] with TastyQuoted { + final class TastyType[T](val tasty: Pickled, val args: Seq[Any]) extends Type[T] { override def toString(): String = s"Type()" } @@ -55,6 +43,8 @@ object Quoted { } /** An Type backed by a tree */ - final class RawType[Tree](val tree: Tree) extends quoted.Type[Any] with RawQuoted[Tree] + final class RawType[Tree](val tree: Tree) extends quoted.Type[Any] { + override def toString: String = s"Type()" + } } From 41630f905729c05b1419bea2e32a519d5829dbad Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 22 Jan 2018 08:44:45 +0100 Subject: [PATCH 4/8] Seal quoted.Expr and quoted.Type --- .../dotc/core/quoted/PickledQuotes.scala | 3 +- .../tools/dotc/core/tasty/TreeUnpickler.scala | 3 +- .../tools/dotc/interpreter/Interpreter.scala | 4 +- .../src/dotty/tools/dotc/quoted/Runners.scala | 2 +- .../reference/principled-meta-programming.md | 2 +- library/src/scala/quoted/Expr.scala | 29 ++++++++++-- library/src/scala/quoted/Liftable.scala | 2 +- library/src/scala/quoted/Quoted.scala | 46 ------------------- library/src/scala/quoted/Type.scala | 24 +++++++++- .../src/scala/runtime/quoted/Unpickler.scala | 3 +- 10 files changed, 59 insertions(+), 59 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 3e69923fb620..5a4c7b8bb8f6 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -12,7 +12,8 @@ import dotty.tools.dotc.core.NameKinds import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.tasty.{TastyPickler, TastyPrinter, TastyString} -import scala.quoted.Quoted._ +import scala.quoted.Types._ +import scala.quoted.Exprs._ import scala.reflect.ClassTag diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index d49f9e08d2ee..d0cd35665eb5 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -21,7 +21,8 @@ import typer.Checking import config.Config import dotty.tools.dotc.core.quoted.PickledQuotes import scala.quoted -import scala.quoted.Quoted.{RawExpr, RawType} +import scala.quoted.Types.RawType +import scala.quoted.Exprs.RawExpr /** Unpickler for typed trees * @param reader the reader from which to unpickle diff --git a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala index 8150bd50e762..0d1fa6360af5 100644 --- a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala +++ b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala @@ -73,8 +73,8 @@ class Interpreter(implicit ctx: Context) { tree match { case Quoted(quotedTree) => - if (tree.isTerm) new scala.quoted.Quoted.RawExpr(quotedTree) - else new scala.quoted.Quoted.RawType(quotedTree) + if (tree.isTerm) new scala.quoted.Exprs.RawExpr(quotedTree) + else new scala.quoted.Types.RawType(quotedTree) case Literal(Constant(c)) => c.asInstanceOf[Object] diff --git a/compiler/src/dotty/tools/dotc/quoted/Runners.scala b/compiler/src/dotty/tools/dotc/quoted/Runners.scala index 265e49fe1f7f..4d0f487da703 100644 --- a/compiler/src/dotty/tools/dotc/quoted/Runners.scala +++ b/compiler/src/dotty/tools/dotc/quoted/Runners.scala @@ -7,7 +7,7 @@ import dotty.tools.dotc.printing.RefinedPrinter import scala.quoted.Expr import scala.runtime.BoxedUnit -import scala.quoted.Quoted.ConstantExpr +import scala.quoted.Exprs.ConstantExpr import scala.runtime.quoted._ /** Default runners for quoted expressions */ diff --git a/docs/docs/reference/principled-meta-programming.md b/docs/docs/reference/principled-meta-programming.md index 1adc3f8ce89d..ea11ac33c3fc 100644 --- a/docs/docs/reference/principled-meta-programming.md +++ b/docs/docs/reference/principled-meta-programming.md @@ -445,7 +445,7 @@ to be executed at a later stage. To run that code, there is another method in class `Expr` called `run`. Note that `~` and `run` both map from `Expr[T]` to `T` but only `~` is subject to the PCP, whereas `run` is just a normal method. - abstract class Expr[T] { + sealed abstract class Expr[T] { def unary_~: T def run(implicit runner: Runner[T]): T // run staged code def show(implicit runner: Runner[T]): String // show staged code diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index 6cd536e9ad71..83ec2b3bb96e 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -1,9 +1,9 @@ package scala.quoted -import scala.quoted.Quoted.FunctionAppliedTo import scala.runtime.quoted.Runner +import scala.runtime.quoted.Unpickler.Pickled -abstract class Expr[T] extends Quoted { +sealed abstract class Expr[T] extends Quoted { final def unary_~ : T = throw new Error("~ should have been compiled away") final def run(implicit runner: Runner[T]): T = runner.run(this) final def show(implicit runner: Runner[T]): String = runner.show(this) @@ -14,7 +14,30 @@ object Expr { ev.toExpr(x) implicit class AsFunction[T, U](private val f: Expr[T => U]) extends AnyVal { - def apply(x: Expr[T]): Expr[U] = new FunctionAppliedTo[T, U](f, x) + def apply(x: Expr[T]): Expr[U] = new Exprs.FunctionAppliedTo[T, U](f, x) } } + +/** All implementations of Expr[T] */ +object Exprs { + /** An Expr backed by a pickled TASTY tree */ + final class TastyExpr[T](val tasty: Pickled, val args: Seq[Any]) extends Expr[T] { + override def toString(): String = s"Expr()" + } + + /** An Expr backed by a value */ + final class ConstantExpr[T](val value: T) extends Expr[T] { + override def toString: String = s"Expr($value)" + } + + /** An Expr backed by a tree */ + final class RawExpr[Tree](val tree: Tree) extends quoted.Expr[Any] { + override def toString: String = s"Expr()" + } + + /** An Expr representing `'{(~f).apply(~x)}` but it is beta-reduced when the closure is known */ + final class FunctionAppliedTo[T, U](val f: Expr[T => U], val x: Expr[T]) extends Expr[U] { + override def toString: String = s"Expr($f $x)" + } +} diff --git a/library/src/scala/quoted/Liftable.scala b/library/src/scala/quoted/Liftable.scala index 2249912c80ba..486c5f3c8331 100644 --- a/library/src/scala/quoted/Liftable.scala +++ b/library/src/scala/quoted/Liftable.scala @@ -1,6 +1,6 @@ package scala.quoted -import scala.quoted.Quoted.ConstantExpr +import scala.quoted.Exprs.ConstantExpr /** A typeclass for types that can be turned to `quoted.Expr[T]` * without going through an explicit `'(...)` operation. diff --git a/library/src/scala/quoted/Quoted.scala b/library/src/scala/quoted/Quoted.scala index 49f58de2f4c5..537dd6221d51 100644 --- a/library/src/scala/quoted/Quoted.scala +++ b/library/src/scala/quoted/Quoted.scala @@ -1,50 +1,4 @@ package scala.quoted -import scala.reflect.ClassTag -import scala.runtime.quoted.Unpickler.Pickled - /** Common superclass of Expr and Type */ abstract class Quoted - -object Quoted { - - // Implementations of Expr[T] - - /** An Expr backed by a pickled TASTY tree */ - final class TastyExpr[T](val tasty: Pickled, val args: Seq[Any]) extends Expr[T] { - override def toString(): String = s"Expr()" - } - - /** An Expr backed by a value */ - final class ConstantExpr[T](val value: T) extends Expr[T] { - override def toString: String = s"Expr($value)" - } - - /** An Expr backed by a tree */ - final class RawExpr[Tree](val tree: Tree) extends quoted.Expr[Any] { - override def toString: String = s"Expr()" - } - - /** An Expr representing `'{(~f).apply(~x)}` but it is beta-reduced when the closure is known */ - final class FunctionAppliedTo[T, U](val f: Expr[T => U], val x: Expr[T]) extends Expr[U] { - override def toString: String = s"Expr($f $x)" - } - - // Implementations of Type[T] - - /** A Type backed by a pickled TASTY tree */ - final class TastyType[T](val tasty: Pickled, val args: Seq[Any]) extends Type[T] { - override def toString(): String = s"Type()" - } - - /** An Type backed by a value */ - final class TaggedType[T](implicit val ct: ClassTag[T]) extends Type[T] { - override def toString: String = s"Type($ct)" - } - - /** An Type backed by a tree */ - final class RawType[Tree](val tree: Tree) extends quoted.Type[Any] { - override def toString: String = s"Type()" - } - -} diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index 4e33eaedf417..34b45a4a159a 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -1,8 +1,10 @@ package scala.quoted -import scala.quoted.Quoted.TaggedType +import scala.quoted.Types.TaggedType +import scala.reflect.ClassTag +import scala.runtime.quoted.Unpickler.Pickled -abstract class Type[T] extends Quoted { +sealed abstract class Type[T] extends Quoted { type unary_~ = T } @@ -18,3 +20,21 @@ object Type { implicit def FloatTag: Type[Float] = new TaggedType[Float] implicit def DoubleTag: Type[Double] = new TaggedType[Double] } + +/** Implementations of Type[T] */ +object Types { + /** A Type backed by a pickled TASTY tree */ + final class TastyType[T](val tasty: Pickled, val args: Seq[Any]) extends Type[T] { + override def toString(): String = s"Type()" + } + + /** An Type backed by a value */ + final class TaggedType[T](implicit val ct: ClassTag[T]) extends Type[T] { + override def toString: String = s"Type($ct)" + } + + /** An Type backed by a tree */ + final class RawType[Tree](val tree: Tree) extends quoted.Type[Any] { + override def toString: String = s"Type()" + } +} \ No newline at end of file diff --git a/library/src/scala/runtime/quoted/Unpickler.scala b/library/src/scala/runtime/quoted/Unpickler.scala index 08b70936fb68..4cf1e854f8f0 100644 --- a/library/src/scala/runtime/quoted/Unpickler.scala +++ b/library/src/scala/runtime/quoted/Unpickler.scala @@ -1,6 +1,7 @@ package scala.runtime.quoted -import scala.quoted.Quoted.{TastyExpr, TastyType} +import scala.quoted.Types.TastyType +import scala.quoted.Exprs.TastyExpr import scala.quoted.{Expr, Type} /** Provides methods to unpickle `Expr` and `Type` trees. */ From 8aae9c19be72cd906f092c2a430708b5471877f7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 15 Feb 2018 18:05:18 +0100 Subject: [PATCH 5/8] Make test for i3187 more stable Number of errors depend on classes present in the std libs --- .../dotc/reporting/ErrorMessagesTests.scala | 12 ++++++++++ tests/neg/i3187.scala | 23 ------------------- 2 files changed, 12 insertions(+), 23 deletions(-) delete mode 100644 tests/neg/i3187.scala diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index 9d950953f550..de80777ea241 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1294,4 +1294,16 @@ class ErrorMessagesTests extends ErrorMessagesTest { val JavaSymbolIsNotAValue(symbol) = messages.head assertEquals(symbol.show, "package p") } + + @Test def i3187 = + checkMessagesAfter("genBCode") { + """ + |package scala + |object collection + """.stripMargin + }.expect { (itcx, messages) => + implicit val ctx: Context = itcx + + assert(ctx.reporter.hasErrors) + } } diff --git a/tests/neg/i3187.scala b/tests/neg/i3187.scala deleted file mode 100644 index 25e098326bd1..000000000000 --- a/tests/neg/i3187.scala +++ /dev/null @@ -1,23 +0,0 @@ -package scala - -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error - -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error -// nopos-error - -object collection From 3e9330fb9e0325c03394accb8b58a42c4d404eeb Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 22 Jan 2018 08:53:26 +0100 Subject: [PATCH 6/8] Remove quoted.Quoted --- library/src/scala/quoted/Expr.scala | 2 +- library/src/scala/quoted/Quoted.scala | 4 ---- library/src/scala/quoted/Type.scala | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 library/src/scala/quoted/Quoted.scala diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index 83ec2b3bb96e..e9b8318da42b 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -3,7 +3,7 @@ package scala.quoted import scala.runtime.quoted.Runner import scala.runtime.quoted.Unpickler.Pickled -sealed abstract class Expr[T] extends Quoted { +sealed abstract class Expr[T] { final def unary_~ : T = throw new Error("~ should have been compiled away") final def run(implicit runner: Runner[T]): T = runner.run(this) final def show(implicit runner: Runner[T]): String = runner.show(this) diff --git a/library/src/scala/quoted/Quoted.scala b/library/src/scala/quoted/Quoted.scala deleted file mode 100644 index 537dd6221d51..000000000000 --- a/library/src/scala/quoted/Quoted.scala +++ /dev/null @@ -1,4 +0,0 @@ -package scala.quoted - -/** Common superclass of Expr and Type */ -abstract class Quoted diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index 34b45a4a159a..4b9c49b96f86 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -4,7 +4,7 @@ import scala.quoted.Types.TaggedType import scala.reflect.ClassTag import scala.runtime.quoted.Unpickler.Pickled -sealed abstract class Type[T] extends Quoted { +sealed abstract class Type[T] { type unary_~ = T } From 09bb61f5fb0e8dd9dbc61b8928313fd96a0c3a11 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 22 Jan 2018 11:28:19 +0100 Subject: [PATCH 7/8] Change ConstantExpr to ValueExpr and add documentation --- .../dotc/core/quoted/PickledQuotes.scala | 2 +- .../src/dotty/tools/dotc/quoted/Runners.scala | 8 +++---- library/src/scala/quoted/Expr.scala | 6 +++-- library/src/scala/quoted/Liftable.scala | 22 +++++++++---------- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 5a4c7b8bb8f6..8e1e4858491c 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -33,7 +33,7 @@ object PickledQuotes { /** Transform the expression into its fully spliced Tree */ def quotedExprToTree(expr: quoted.Expr[_])(implicit ctx: Context): Tree = expr match { case expr: TastyExpr[_] => unpickleExpr(expr) - case expr: ConstantExpr[_] => Literal(Constant(expr.value)) + case expr: ValueExpr[_] => Literal(Constant(expr.value)) case expr: RawExpr[Tree] @unchecked => expr.tree case expr: FunctionAppliedTo[_, _] => functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x)) diff --git a/compiler/src/dotty/tools/dotc/quoted/Runners.scala b/compiler/src/dotty/tools/dotc/quoted/Runners.scala index 4d0f487da703..661d636e68e8 100644 --- a/compiler/src/dotty/tools/dotc/quoted/Runners.scala +++ b/compiler/src/dotty/tools/dotc/quoted/Runners.scala @@ -7,7 +7,7 @@ import dotty.tools.dotc.printing.RefinedPrinter import scala.quoted.Expr import scala.runtime.BoxedUnit -import scala.quoted.Exprs.ConstantExpr +import scala.quoted.Exprs.ValueExpr import scala.runtime.quoted._ /** Default runners for quoted expressions */ @@ -31,7 +31,7 @@ object Runners { case _ => None } expr match { - case expr: ConstantExpr[T] => Some(expr.value) + case expr: ValueExpr[T] => Some(expr.value) case _ => new QuoteDriver().withTree(expr, (tree, _) => toConstantOpt(tree), Settings.run()) } } @@ -39,12 +39,12 @@ object Runners { } def run[T](expr: Expr[T], settings: Settings[Run]): T = expr match { - case expr: ConstantExpr[T] => expr.value + case expr: ValueExpr[T] => expr.value case _ => new QuoteDriver().run(expr, settings) } def show[T](expr: Expr[T], settings: Settings[Show]): String = expr match { - case expr: ConstantExpr[T] => + case expr: ValueExpr[T] => implicit val ctx = new QuoteDriver().initCtx if (settings.compilerArgs.contains("-color:never")) ctx.settings.color.update("never") diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index e9b8318da42b..e0d83624fbdc 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -26,8 +26,10 @@ object Exprs { override def toString(): String = s"Expr()" } - /** An Expr backed by a value */ - final class ConstantExpr[T](val value: T) extends Expr[T] { + /** An Expr backed by a value. + * Values can only be of type Boolean, Byte, Short, Char, Int, Long, Float, Double, Unit, String or Null. + */ + final class ValueExpr[T](val value: T) extends Expr[T] { override def toString: String = s"Expr($value)" } diff --git a/library/src/scala/quoted/Liftable.scala b/library/src/scala/quoted/Liftable.scala index 486c5f3c8331..f1f01a60bd93 100644 --- a/library/src/scala/quoted/Liftable.scala +++ b/library/src/scala/quoted/Liftable.scala @@ -1,6 +1,6 @@ package scala.quoted -import scala.quoted.Exprs.ConstantExpr +import scala.quoted.Exprs.ValueExpr /** A typeclass for types that can be turned to `quoted.Expr[T]` * without going through an explicit `'(...)` operation. @@ -20,15 +20,15 @@ object Liftable { def toExpr(implicit liftable: Liftable[T]): Expr[T] = liftable.toExpr(x) } - implicit def UnitIsLiftable: Liftable[Unit] = (x: Unit) => new ConstantExpr(x) - implicit def BooleanIsLiftable: Liftable[Boolean] = (x: Boolean) => new ConstantExpr(x) - implicit def ByteLiftable: Liftable[Byte] = (x: Byte) => new ConstantExpr(x) - implicit def CharIsLiftable: Liftable[Char] = (x: Char) => new ConstantExpr(x) - implicit def ShortIsLiftable: Liftable[Short] = (x: Short) => new ConstantExpr(x) - implicit def IntIsLiftable: Liftable[Int] = (x: Int) => new ConstantExpr(x) - implicit def LongIsLiftable: Liftable[Long] = (x: Long) => new ConstantExpr(x) - implicit def FloatIsLiftable: Liftable[Float] = (x: Float) => new ConstantExpr(x) - implicit def DoubleIsLiftable: Liftable[Double] = (x: Double) => new ConstantExpr(x) + implicit def UnitIsLiftable: Liftable[Unit] = (x: Unit) => new ValueExpr(x) + implicit def BooleanIsLiftable: Liftable[Boolean] = (x: Boolean) => new ValueExpr(x) + implicit def ByteLiftable: Liftable[Byte] = (x: Byte) => new ValueExpr(x) + implicit def CharIsLiftable: Liftable[Char] = (x: Char) => new ValueExpr(x) + implicit def ShortIsLiftable: Liftable[Short] = (x: Short) => new ValueExpr(x) + implicit def IntIsLiftable: Liftable[Int] = (x: Int) => new ValueExpr(x) + implicit def LongIsLiftable: Liftable[Long] = (x: Long) => new ValueExpr(x) + implicit def FloatIsLiftable: Liftable[Float] = (x: Float) => new ValueExpr(x) + implicit def DoubleIsLiftable: Liftable[Double] = (x: Double) => new ValueExpr(x) - implicit def StringIsLiftable: Liftable[String] = (x: String) => new ConstantExpr(x) + implicit def StringIsLiftable: Liftable[String] = (x: String) => new ValueExpr(x) } From 4f769ea8605a5c979d2a26cdfb9dc78b7695daab Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 22 Jan 2018 11:34:28 +0100 Subject: [PATCH 8/8] Rename Raw{Expr|Type} to Tree{Expr|Type} --- .../src/dotty/tools/dotc/core/quoted/PickledQuotes.scala | 4 ++-- .../src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 8 ++++---- .../src/dotty/tools/dotc/interpreter/Interpreter.scala | 4 ++-- library/src/scala/quoted/Expr.scala | 8 +++++--- library/src/scala/quoted/Type.scala | 6 ++++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 8e1e4858491c..b4a065a473fd 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -34,7 +34,7 @@ object PickledQuotes { def quotedExprToTree(expr: quoted.Expr[_])(implicit ctx: Context): Tree = expr match { case expr: TastyExpr[_] => unpickleExpr(expr) case expr: ValueExpr[_] => Literal(Constant(expr.value)) - case expr: RawExpr[Tree] @unchecked => expr.tree + case expr: TreeExpr[Tree] @unchecked => expr.tree case expr: FunctionAppliedTo[_, _] => functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x)) } @@ -43,7 +43,7 @@ object PickledQuotes { def quotedTypeToTree(expr: quoted.Type[_])(implicit ctx: Context): Tree = expr match { case expr: TastyType[_] => unpickleType(expr) case expr: TaggedType[_] => classTagToTypeTree(expr.ct) - case expr: RawType[Tree] @unchecked => expr.tree + case expr: TreeType[Tree] @unchecked => expr.tree } /** Unpickle the tree contained in the TastyExpr */ diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index d0cd35665eb5..3e38a9119fbe 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -21,8 +21,8 @@ import typer.Checking import config.Config import dotty.tools.dotc.core.quoted.PickledQuotes import scala.quoted -import scala.quoted.Types.RawType -import scala.quoted.Exprs.RawExpr +import scala.quoted.Types.TreeType +import scala.quoted.Exprs.TreeExpr /** Unpickler for typed trees * @param reader the reader from which to unpickle @@ -1136,12 +1136,12 @@ class TreeUnpickler(reader: TastyReader, if (isType) { val quotedType = if (args.isEmpty) splice.asInstanceOf[quoted.Type[_]] - else splice.asInstanceOf[Seq[Any] => quoted.Type[_]](args.map(tree => new RawType(tree))) + else splice.asInstanceOf[Seq[Any] => quoted.Type[_]](args.map(tree => new TreeType(tree))) PickledQuotes.quotedTypeToTree(quotedType) } else { val quotedExpr = if (args.isEmpty) splice.asInstanceOf[quoted.Expr[_]] - else splice.asInstanceOf[Seq[Any] => quoted.Expr[_]](args.map(tree => new RawExpr(tree))) + else splice.asInstanceOf[Seq[Any] => quoted.Expr[_]](args.map(tree => new TreeExpr(tree))) PickledQuotes.quotedExprToTree(quotedExpr) } diff --git a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala index 0d1fa6360af5..5be936d71ee1 100644 --- a/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala +++ b/compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala @@ -73,8 +73,8 @@ class Interpreter(implicit ctx: Context) { tree match { case Quoted(quotedTree) => - if (tree.isTerm) new scala.quoted.Exprs.RawExpr(quotedTree) - else new scala.quoted.Types.RawType(quotedTree) + if (tree.isTerm) new scala.quoted.Exprs.TreeExpr(quotedTree) + else new scala.quoted.Types.TreeType(quotedTree) case Literal(Constant(c)) => c.asInstanceOf[Object] diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index e0d83624fbdc..0f724c9257ca 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -19,7 +19,9 @@ object Expr { } -/** All implementations of Expr[T] */ +/** All implementations of Expr[T]. + * These should never be used directly. + */ object Exprs { /** An Expr backed by a pickled TASTY tree */ final class TastyExpr[T](val tasty: Pickled, val args: Seq[Any]) extends Expr[T] { @@ -33,8 +35,8 @@ object Exprs { override def toString: String = s"Expr($value)" } - /** An Expr backed by a tree */ - final class RawExpr[Tree](val tree: Tree) extends quoted.Expr[Any] { + /** An Expr backed by a tree. Only the current compiler trees are allowed. */ + final class TreeExpr[Tree](val tree: Tree) extends quoted.Expr[Any] { override def toString: String = s"Expr()" } diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index 4b9c49b96f86..66ace17f1bee 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -21,7 +21,9 @@ object Type { implicit def DoubleTag: Type[Double] = new TaggedType[Double] } -/** Implementations of Type[T] */ +/** All implementations of Type[T]. + * These should never be used directly. + */ object Types { /** A Type backed by a pickled TASTY tree */ final class TastyType[T](val tasty: Pickled, val args: Seq[Any]) extends Type[T] { @@ -34,7 +36,7 @@ object Types { } /** An Type backed by a tree */ - final class RawType[Tree](val tree: Tree) extends quoted.Type[Any] { + final class TreeType[Tree](val tree: Tree) extends quoted.Type[Any] { override def toString: String = s"Type()" } } \ No newline at end of file