diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 2078184b5571..65d71b62e4e3 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -59,7 +59,6 @@ object PickledQuotes { tpt case tpt => tpt } - case expr: TaggedType[_] => classTagToTypeTree(expr.ct) case expr: TreeType[Tree] @unchecked => healOwner(expr.typeTree) } @@ -127,21 +126,6 @@ object PickledQuotes { tree } - private def classTagToTypeTree(ct: ClassTag[_])(implicit ctx: Context): TypeTree = { - val tpe = ct match { - case ClassTag.Unit => defn.UnitType - case ClassTag.Boolean => defn.BooleanType - case ClassTag.Byte => defn.ByteType - case ClassTag.Char => defn.CharType - case ClassTag.Short => defn.ShortType - case ClassTag.Int => defn.IntType - case ClassTag.Long => defn.LongType - case ClassTag.Float => defn.FloatType - case ClassTag.Double => defn.DoubleType - } - TypeTree(tpe) - } - private def functionAppliedTo(fn: Tree, args: List[Tree])(implicit ctx: Context): Tree = { val (argVals, argRefs) = args.map(arg => arg.tpe match { case tpe: SingletonType if isIdempotentExpr(arg) => (Nil, arg) diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index d279bea1f0ed..7ab344a263e2 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -202,27 +202,28 @@ class ReifyQuotes extends MacroTransform { } private def pickledQuote(body: Tree, splices: List[Tree], originalTp: Type, isType: Boolean)(implicit ctx: Context) = { + def qctx: Tree = { + val qctx = ctx.typer.inferImplicitArg(defn.QuoteContextClass.typeRef, body.span) + if (qctx.tpe.isInstanceOf[SearchFailureType]) + ctx.error(ctx.typer.missingArgMsg(qctx, defn.QuoteContextClass.typeRef, ""), ctx.source.atSpan(body.span)) + qctx + } def liftedValue[T](value: T, name: TermName, qctx: Tree) = ref(defn.LiftableModule).select(name).select("toExpr".toTermName).appliedTo(Literal(Constant(value))).select(nme.apply).appliedTo(qctx) - def pickleAsValue[T](value: T) = { - val qctx = ctx.typer.inferImplicitArg(defn.QuoteContextClass.typeRef, body.span) - if (qctx.tpe.isInstanceOf[SearchFailureType]) - ctx.error(ctx.typer.missingArgMsg(qctx, defn.QuoteContextClass.typeRef, ""), ctx.source.atSpan(body.span)) - value match { - case null => ref(defn.QuotedExprModule).select("nullExpr".toTermName).appliedTo(qctx) - case _: Unit => ref(defn.QuotedExprModule).select("unitExpr".toTermName).appliedTo(qctx) - case _: Boolean => liftedValue(value, "Liftable_Boolean_delegate".toTermName, qctx) - case _: Byte => liftedValue(value, "Liftable_Byte_delegate".toTermName, qctx) - case _: Short => liftedValue(value, "Liftable_Short_delegate".toTermName, qctx) - case _: Int => liftedValue(value, "Liftable_Int_delegate".toTermName, qctx) - case _: Long => liftedValue(value, "Liftable_Long_delegate".toTermName, qctx) - case _: Float => liftedValue(value, "Liftable_Float_delegate".toTermName, qctx) - case _: Double => liftedValue(value, "Liftable_Double_delegate".toTermName, qctx) - case _: Char => liftedValue(value, "Liftable_Char_delegate".toTermName, qctx) - case _: String => liftedValue(value, "Liftable_String_delegate".toTermName, qctx) - } + def pickleAsValue[T](value: T) = value match { + case null => ref(defn.QuotedExprModule).select("nullExpr".toTermName).appliedTo(qctx) + case _: Unit => ref(defn.QuotedExprModule).select("unitExpr".toTermName).appliedTo(qctx) + case _: Boolean => liftedValue(value, "Liftable_Boolean_delegate".toTermName, qctx) + case _: Byte => liftedValue(value, "Liftable_Byte_delegate".toTermName, qctx) + case _: Short => liftedValue(value, "Liftable_Short_delegate".toTermName, qctx) + case _: Int => liftedValue(value, "Liftable_Int_delegate".toTermName, qctx) + case _: Long => liftedValue(value, "Liftable_Long_delegate".toTermName, qctx) + case _: Float => liftedValue(value, "Liftable_Float_delegate".toTermName, qctx) + case _: Double => liftedValue(value, "Liftable_Double_delegate".toTermName, qctx) + case _: Char => liftedValue(value, "Liftable_Char_delegate".toTermName, qctx) + case _: String => liftedValue(value, "Liftable_String_delegate".toTermName, qctx) } def pickleAsTasty() = { @@ -239,7 +240,7 @@ class ReifyQuotes extends MacroTransform { } if (splices.nonEmpty) pickleAsTasty() else if (isType) { - def tag(tagName: String) = ref(defn.QuotedTypeModule).select(tagName.toTermName) + def tag(tagName: String) = ref(defn.QuotedTypeModule).select(tagName.toTermName).appliedTo(qctx) if (body.symbol.isPrimitiveValueClass) tag(s"${body.symbol.name}Tag") else pickleAsTasty() } diff --git a/compiler/test-resources/repl-macros/i6263 b/compiler/test-resources/repl-macros/i6263 new file mode 100644 index 000000000000..4b3df71a76b0 --- /dev/null +++ b/compiler/test-resources/repl-macros/i6263 @@ -0,0 +1,15 @@ +scala> import quoted._ +scala> implicit def toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) +def toolbox: quoted.Toolbox +scala> def fn[T : Type](v : T) = println("ok") +def fn[T](v: T)(implicit evidence$1: quoted.Type[T]): Unit +scala> withQuoteContext { fn("foo") } +ok +scala> withQuoteContext { fn((1,2)) } +ok +scala> object O +// defined object O +scala> withQuoteContext { fn(O) } +ok +scala> withQuoteContext { fn(1) } +ok diff --git a/compiler/test-resources/repl/i6263 b/compiler/test-resources/repl/i6263 deleted file mode 100644 index 8a9047cc2b85..000000000000 --- a/compiler/test-resources/repl/i6263 +++ /dev/null @@ -1,13 +0,0 @@ -scala> import quoted._ -scala> def fn[T : Type](v : T) = println("ok") -def fn[T](v: T)(implicit evidence$1: quoted.Type[T]): Unit -scala> fn("foo") -ok -scala> fn((1,2)) -ok -scala> object O -// defined object O -scala> fn(O) -ok -scala> fn(1) -ok diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index 12dcbb0706e0..3aaf8b5eb3d8 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -1,7 +1,6 @@ package scala package quoted { - import scala.internal.quoted.TaggedType import scala.quoted.show.SyntaxHighlight sealed trait Type[T <: AnyKind] { @@ -17,15 +16,52 @@ package quoted { /** Some basic type tags, currently incomplete */ object Type { - given UnitTag as Type[Unit] = new TaggedType[Unit] - given BooleanTag as Type[Boolean] = new TaggedType[Boolean] - given ByteTag as Type[Byte] = new TaggedType[Byte] - given CharTag as Type[Char] = new TaggedType[Char] - given ShortTag as Type[Short] = new TaggedType[Short] - given IntTag as Type[Int] = new TaggedType[Int] - given LongTag as Type[Long] = new TaggedType[Long] - given FloatTag as Type[Float] = new TaggedType[Float] - given DoubleTag as Type[Double] = new TaggedType[Double] + + given UnitTag as Type[Unit] given (qctx: QuoteContext) = { + import qctx.tasty._ + definitions.UnitType.seal.asInstanceOf[quoted.Type[Unit]] + } + + given BooleanTag as Type[Boolean] given (qctx: QuoteContext) = { + import qctx.tasty._ + definitions.BooleanType.seal.asInstanceOf[quoted.Type[Boolean]] + } + + given ByteTag as Type[Byte] given (qctx: QuoteContext) = { + import qctx.tasty._ + definitions.ByteType.seal.asInstanceOf[quoted.Type[Byte]] + } + + given CharTag as Type[Char] given (qctx: QuoteContext) = { + import qctx.tasty._ + definitions.CharType.seal.asInstanceOf[quoted.Type[Char]] + } + + given ShortTag as Type[Short] given (qctx: QuoteContext) = { + import qctx.tasty._ + definitions.ShortType.seal.asInstanceOf[quoted.Type[Short]] + } + + given IntTag as Type[Int] given (qctx: QuoteContext) = { + import qctx.tasty._ + definitions.IntType.seal.asInstanceOf[quoted.Type[Int]] + } + + given LongTag as Type[Long] given (qctx: QuoteContext) = { + import qctx.tasty._ + definitions.LongType.seal.asInstanceOf[quoted.Type[Long]] + } + + given FloatTag as Type[Float] given (qctx: QuoteContext) = { + import qctx.tasty._ + definitions.FloatType.seal.asInstanceOf[quoted.Type[Float]] + } + + given DoubleTag as Type[Double] given (qctx: QuoteContext) = { + import qctx.tasty._ + definitions.DoubleType.seal.asInstanceOf[quoted.Type[Double]] + } + } } @@ -33,7 +69,6 @@ package quoted { package internal { package quoted { import scala.quoted.Type - import scala.reflect.ClassTag import scala.runtime.quoted.Unpickler.Pickled /** A Type backed by a pickled TASTY tree */ @@ -41,11 +76,6 @@ package internal { 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 TreeType[Tree](val typeTree: Tree) extends Type[Any] { override def toString: String = s"Type()" diff --git a/tests/pos/typetags.scala b/tests/pos/typetags.scala index 509ccb6087d0..ae1a5222b22a 100644 --- a/tests/pos/typetags.scala +++ b/tests/pos/typetags.scala @@ -2,7 +2,7 @@ import scala.quoted._ object Test { - def f[T: Type] = { + def f[T: Type] given QuoteContext = { implicitly[Type[Int]] implicitly[Type[List[Int]]] implicitly[Type[T]] diff --git a/tests/run-with-compiler/i3947b.check b/tests/run-with-compiler/i3947b.check index ecebc25acde9..dcdad6244a7b 100644 --- a/tests/run-with-compiler/i3947b.check +++ b/tests/run-with-compiler/i3947b.check @@ -1,9 +1,9 @@ scala.Predef.classOf[scala.Boolean].getCanonicalName() -boolean scala.Predef.classOf[scala.Byte].getCanonicalName() -byte scala.Predef.classOf[scala.Char].getCanonicalName() +boolean +byte char diff --git a/tests/run-with-compiler/i3947b.scala b/tests/run-with-compiler/i3947b.scala index 93ea766e2f07..c3ae8163019b 100644 --- a/tests/run-with-compiler/i3947b.scala +++ b/tests/run-with-compiler/i3947b.scala @@ -3,9 +3,10 @@ import scala.quoted._ object Test { - def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def test[T: Type](clazz: java.lang.Class[T]): Unit = run { + implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + + def main(args: Array[String]): Unit = run { + def test[T: Type](clazz: java.lang.Class[T]) = { val lclazz = clazz.toExpr val name = '{ ($lclazz).getCanonicalName } println() @@ -14,9 +15,11 @@ object Test { } // primitives - test(classOf[Boolean]) - test(classOf[Byte]) - test(classOf[Char]) + '{ + ${test(classOf[Boolean])} + ${test(classOf[Byte])} + ${test(classOf[Char])} + } } } diff --git a/tests/run-with-compiler/i3947b2.check b/tests/run-with-compiler/i3947b2.check index 7c5e630bb5a2..d699b2b8e433 100644 --- a/tests/run-with-compiler/i3947b2.check +++ b/tests/run-with-compiler/i3947b2.check @@ -1,9 +1,9 @@ scala.Predef.classOf[scala.Short].getCanonicalName() -short scala.Predef.classOf[scala.Int].getCanonicalName() -int scala.Predef.classOf[scala.Long].getCanonicalName() +short +int long diff --git a/tests/run-with-compiler/i3947b2.scala b/tests/run-with-compiler/i3947b2.scala index ecd892c81d58..50616f22f987 100644 --- a/tests/run-with-compiler/i3947b2.scala +++ b/tests/run-with-compiler/i3947b2.scala @@ -3,9 +3,10 @@ import scala.quoted._ object Test { - def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def test[T: Type](clazz: java.lang.Class[T]): Unit = run { + implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + + def main(args: Array[String]): Unit = run { + def test[T: Type](clazz: given QuoteContext => java.lang.Class[T]) = { val lclazz = clazz.toExpr val name = '{ ($lclazz).getCanonicalName } println() @@ -14,9 +15,11 @@ object Test { } // primitives - test(classOf[Short]) - test(classOf[Int]) - test(classOf[Long]) + '{ + ${test(classOf[Short])} + ${test(classOf[Int])} + ${test(classOf[Long])} + } } } diff --git a/tests/run-with-compiler/i3947b3.check b/tests/run-with-compiler/i3947b3.check index d2d1b24c0edf..f48976b954a9 100644 --- a/tests/run-with-compiler/i3947b3.check +++ b/tests/run-with-compiler/i3947b3.check @@ -1,9 +1,6 @@ - scala.Predef.classOf[scala.Float].getCanonicalName() -float - scala.Predef.classOf[scala.Double].getCanonicalName() -double - scala.Predef.classOf[scala.Unit].getCanonicalName() +float +double void diff --git a/tests/run-with-compiler/i3947b3.scala b/tests/run-with-compiler/i3947b3.scala index 5eccdc6334ce..9219b4465138 100644 --- a/tests/run-with-compiler/i3947b3.scala +++ b/tests/run-with-compiler/i3947b3.scala @@ -3,20 +3,21 @@ import scala.quoted._ object Test { - def main(args: Array[String]): Unit = { - implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) - def test[T: Type](clazz: java.lang.Class[T]): Unit = run { + implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + + def main(args: Array[String]): Unit = run { + def test[T: Type](clazz: java.lang.Class[T]) = { val lclazz = clazz.toExpr val name = '{ ($lclazz).getCanonicalName } - println() println(name.show) '{ println($name) } } - // primitives - test(classOf[Float]) - test(classOf[Double]) - test(classOf[Unit]) + '{ + ${test(classOf[Float])} + ${test(classOf[Double])} + ${test(classOf[Unit])} + } } } diff --git a/tests/run-with-compiler/i6263.scala b/tests/run-with-compiler/i6263.scala index b940c1c61d37..4c2d67d7abb7 100644 --- a/tests/run-with-compiler/i6263.scala +++ b/tests/run-with-compiler/i6263.scala @@ -1,7 +1,9 @@ import quoted._ object Test { - def main(args: Array[String]): Unit = { + implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + + def main(args: Array[String]): Unit = withQuoteContext { fn("foo") fn((1,2)) fn(O)