diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index 91d03ddf64c5..d279bea1f0ed 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -204,7 +204,7 @@ class ReifyQuotes extends MacroTransform { private def pickledQuote(body: Tree, splices: List[Tree], originalTp: Type, isType: Boolean)(implicit ctx: Context) = { def liftedValue[T](value: T, name: TermName, qctx: Tree) = - ref(defn.LiftableModule).select(name).select("toExpr".toTermName).appliedTo(Literal(Constant(value))).appliedTo(qctx) + 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) diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 199b48db7526..b3d7c575e32f 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -270,7 +270,7 @@ knowing anything about the representation of `Expr` trees. For instance, here is a possible instance of `Liftable[Boolean]`: ```scala delegate for Liftable[Boolean] { - def toExpr(b: Boolean) given QuoteContext: Expr[Boolean] = + def toExpr(b: Boolean) = if (b) '{ true } else '{ false } } ``` @@ -279,7 +279,7 @@ possible implementation of `Liftable[Int]` that does not use the underlying tree machinery: ```scala delegate for Liftable[Int] { - def toExpr(n: Int) given QuoteContext: Expr[Int] = n match { + def toExpr(n: Int) = n match { case Int.MinValue => '{ Int.MinValue } case _ if n < 0 => '{ - ${ toExpr(-n) } } case 0 => '{ 0 } @@ -292,7 +292,7 @@ Since `Liftable` is a type class, its instances can be conditional. For example, a `List` is liftable if its element type is: ```scala delegate [T: Liftable] for Liftable[List[T]] { - def toExpr(xs: List[T]) given QuoteContext: Expr[List[T]] = xs match { + def toExpr(xs: List[T]) = xs match { case head :: tail => '{ ${ toExpr(head) } :: ${ toExpr(tail) } } case Nil => '{ Nil: List[T] } } diff --git a/library/src/scala/quoted/Liftable.scala b/library/src/scala/quoted/Liftable.scala index 40903fc20526..d26988d55008 100644 --- a/library/src/scala/quoted/Liftable.scala +++ b/library/src/scala/quoted/Liftable.scala @@ -6,7 +6,7 @@ package scala.quoted trait Liftable[T] { /** Lift a value into an expression containing the construction of that value */ - def toExpr(x: T) given QuoteContext: Expr[T] + def toExpr(x: T): given QuoteContext => Expr[T] } @@ -29,7 +29,7 @@ object Liftable { private class PrimitiveLiftable[T <: Unit | Null | Int | Boolean | Byte | Short | Int | Long | Float | Double | Char | String] extends Liftable[T] { /** Lift a primitive value `n` into `'{ n }` */ - def toExpr(x: T) given (qctx: QuoteContext): Expr[T] = { + def toExpr(x: T) = given qctx => { import qctx.tasty._ Literal(Constant(x)).seal.asInstanceOf[Expr[T]] } @@ -37,7 +37,7 @@ object Liftable { implicit def ClassIsLiftable[T]: Liftable[Class[T]] = new Liftable[Class[T]] { /** Lift a `Class[T]` into `'{ classOf[T] }` */ - def toExpr(x: Class[T]) given (qctx: QuoteContext): Expr[Class[T]] = { + def toExpr(x: Class[T]) = given qctx => { import qctx.tasty._ Ref(definitions.Predef_classOf).appliedToType(Type(x)).seal.asInstanceOf[Expr[Class[T]]] } diff --git a/tests/pos/quote-liftable-list-2.scala b/tests/pos/quote-liftable-list-2.scala index b64e6ab43ddb..8071e5771fee 100644 --- a/tests/pos/quote-liftable-list-2.scala +++ b/tests/pos/quote-liftable-list-2.scala @@ -3,11 +3,7 @@ import scala.quoted._ object Test { implicit def ListIsLiftableOr[T: Type, U: Type]: Liftable[List[T | U]] = new { - def toExpr(xs: List[T | U]) given QuoteContext: Expr[List[T | U]] = '{ Nil: List[T | U] } - } - - implicit def ListIsLiftableAnd[T: Type, U: Type]: Liftable[List[T & U]] = new { - def toExpr(xs: List[T & U]) given QuoteContext: Expr[List[T & U]] = '{ Nil: List[T & U] } + def toExpr(xs: List[T | U]) = '{ Nil: List[T | U] } } } diff --git a/tests/pos/quote-liftable-list-3.scala b/tests/pos/quote-liftable-list-3.scala new file mode 100644 index 000000000000..4118df7d92a7 --- /dev/null +++ b/tests/pos/quote-liftable-list-3.scala @@ -0,0 +1,9 @@ +import scala.quoted._ + +object Test { + + implicit def ListIsLiftableAnd[T: Type, U: Type]: Liftable[List[T & U]] = new { + def toExpr(xs: List[T & U]) = '{ Nil: List[T & U] } + } + +} diff --git a/tests/pos/quote-liftable-list.scala b/tests/pos/quote-liftable-list.scala index 205315261fbd..c2c4af24341b 100644 --- a/tests/pos/quote-liftable-list.scala +++ b/tests/pos/quote-liftable-list.scala @@ -3,7 +3,7 @@ import scala.quoted._ object Test { implicit def ListIsLiftable[T: Liftable: Type]: Liftable[List[T]] = new { - def toExpr(xs: List[T]) given QuoteContext: Expr[List[T]] = '{ Nil: List[T] } + def toExpr(xs: List[T]) = '{ Nil: List[T] } } } diff --git a/tests/pos/quote-liftable.scala b/tests/pos/quote-liftable.scala index 08c9bbc5eea3..3467a983c326 100644 --- a/tests/pos/quote-liftable.scala +++ b/tests/pos/quote-liftable.scala @@ -5,7 +5,7 @@ def test given QuoteContext = { delegate for QuoteContext = ??? implicit def IntIsLiftable: Liftable[Int] = new { - def toExpr(n: Int) given QuoteContext: Expr[Int] = n match { + def toExpr(n: Int) = n match { case Int.MinValue => '{Int.MinValue} case _ if n < 0 => '{- ${toExpr(n)}} case 0 => '{0} @@ -15,12 +15,12 @@ def test given QuoteContext = { } implicit def BooleanIsLiftable: Liftable[Boolean] = new { - implicit def toExpr(b: Boolean) given QuoteContext: Expr[Boolean] = + implicit def toExpr(b: Boolean) = if (b) '{true} else '{false} } implicit def ListIsLiftable[T: Liftable: Type]: Liftable[List[T]] = new { - def toExpr(xs: List[T]) given QuoteContext: Expr[List[T]] = xs match { + def toExpr(xs: List[T]) = xs match { case x :: xs1 => '{ ${ implicitly[Liftable[T]].toExpr(x) } :: ${ toExpr(xs1) } } case Nil => '{Nil: List[T]} } diff --git a/tests/run-macros/gestalt-type-toolbox-reflect/Macro_1.scala b/tests/run-macros/gestalt-type-toolbox-reflect/Macro_1.scala index 76523b4f5f90..9e3718a26938 100644 --- a/tests/run-macros/gestalt-type-toolbox-reflect/Macro_1.scala +++ b/tests/run-macros/gestalt-type-toolbox-reflect/Macro_1.scala @@ -112,7 +112,7 @@ object TypeToolbox { // TODO add to the std lib private implicit def listIsLiftable[T: Type: Liftable]: Liftable[List[T]] = new Liftable { - def toExpr(list: List[T]) given QuoteContext: Expr[List[T]] = list match { + def toExpr(list: List[T]) = list match { case x :: xs => '{${x.toExpr} :: ${toExpr(xs)}} case Nil => '{Nil} } diff --git a/tests/run-macros/quote-force/quoted_1.scala b/tests/run-macros/quote-force/quoted_1.scala index 86f3fdbe7e7b..b537f3f847ca 100644 --- a/tests/run-macros/quote-force/quoted_1.scala +++ b/tests/run-macros/quote-force/quoted_1.scala @@ -13,7 +13,7 @@ object Location { } private implicit def ListIsLiftable[T : Liftable : Type]: Liftable[List[T]] = new Liftable[List[T]] { - def toExpr(x: List[T]) given QuoteContext: Expr[List[T]] = x match { + def toExpr(x: List[T]) = x match { case x :: xs => '{ ${x} :: ${xs} } case Nil => '{ List.empty[T] } } diff --git a/tests/run-macros/tasty-interpolation-1/Macro.scala b/tests/run-macros/tasty-interpolation-1/Macro.scala index 884c63754a3e..3f64a3e8a7e4 100644 --- a/tests/run-macros/tasty-interpolation-1/Macro.scala +++ b/tests/run-macros/tasty-interpolation-1/Macro.scala @@ -77,10 +77,10 @@ abstract class MacroStringInterpolator[T] { } protected implicit def StringContextIsLiftable: Liftable[StringContext] = new Liftable[StringContext] { - def toExpr(strCtx: StringContext) given QuoteContext: Expr[StringContext] = { + def toExpr(strCtx: StringContext) = { // TODO define in stdlib? implicit def ListIsLiftable: Liftable[List[String]] = new Liftable[List[String]] { - override def toExpr(list: List[String]) given QuoteContext: Expr[List[String]] = list match { + override def toExpr(list: List[String]) = list match { case x :: xs => '{${x.toExpr} :: ${toExpr(xs)}} case Nil => '{Nil} } diff --git a/tests/run-macros/tasty-location/quoted_1.scala b/tests/run-macros/tasty-location/quoted_1.scala index 850de61bf4ec..b350cf9c6fa4 100644 --- a/tests/run-macros/tasty-location/quoted_1.scala +++ b/tests/run-macros/tasty-location/quoted_1.scala @@ -19,7 +19,7 @@ object Location { } private implicit def ListIsLiftable[T : Liftable : Type]: Liftable[List[T]] = new Liftable[List[T]] { - def toExpr(x: List[T]) given QuoteContext: Expr[List[T]] = x match { + def toExpr(x: List[T]) = x match { case x :: xs => '{ $x :: $xs } case Nil => '{ List.empty[T] } } diff --git a/tests/run-with-compiler/i3847-b.scala b/tests/run-with-compiler/i3847-b.scala index b75729d59998..d51e9815d49f 100644 --- a/tests/run-with-compiler/i3847-b.scala +++ b/tests/run-with-compiler/i3847-b.scala @@ -4,7 +4,7 @@ import scala.reflect.ClassTag object Arrays { implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], qctx: QuoteContext): Liftable[Array[List[T]]] = { new Liftable[Array[List[T]]] { - def toExpr(arr: Array[List[T]]) given QuoteContext: Expr[Array[List[T]]] = '{ + def toExpr(arr: Array[List[T]]) = '{ new Array[List[$t]](${arr.length.toExpr}) // TODO add elements } diff --git a/tests/run-with-compiler/i3847.scala b/tests/run-with-compiler/i3847.scala index c59ea5abfb58..cce0dfd919c3 100644 --- a/tests/run-with-compiler/i3847.scala +++ b/tests/run-with-compiler/i3847.scala @@ -4,7 +4,7 @@ import scala.reflect.ClassTag object Arrays { implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], ct: Expr[ClassTag[T]]): Liftable[Array[T]] = { new Liftable[Array[T]] { - def toExpr(arr: Array[T]) given QuoteContext: Expr[Array[T]] = '{ + def toExpr(arr: Array[T]) = '{ new Array[$t](${arr.length.toExpr})($ct) // TODO add elements } diff --git a/tests/run-with-compiler/quote-lib.scala b/tests/run-with-compiler/quote-lib.scala index f0a3ea6b2c80..04726cd8de57 100644 --- a/tests/run-with-compiler/quote-lib.scala +++ b/tests/run-with-compiler/quote-lib.scala @@ -53,7 +53,7 @@ package liftable { object Units { implicit def UnitIsLiftable: Liftable[Unit] = new Liftable[Unit] { - def toExpr(x: Unit) given QuoteContext: Expr[Unit] = '{} + def toExpr(x: Unit) = '{} } } @@ -74,24 +74,24 @@ package liftable { object Tuples { implicit def Tuple1IsLiftable[T1: Liftable](implicit t1: Type[T1]): Liftable[Tuple1[T1]] = new Liftable[Tuple1[T1]] { - def toExpr(x: Tuple1[T1]) given QuoteContext: Expr[Tuple1[T1]] = + def toExpr(x: Tuple1[T1]) = '{ Tuple1[$t1](${ x._1}) } } implicit def Tuple2IsLiftable[T1: Liftable, T2: Liftable](implicit t1: Type[T1], t2: Type[T2]): Liftable[(T1, T2)] = new Liftable[(T1, T2)] { - def toExpr(x: (T1, T2)) given QuoteContext: Expr[(T1, T2)] = + def toExpr(x: (T1, T2)) = '{ Tuple2[$t1, $t2](${x._1}, ${x._2}) } } implicit def Tuple3IsLiftable[T1: Liftable, T2: Liftable, T3: Liftable](implicit t1: Type[T1], t2: Type[T2], t3: Type[T3]): Liftable[(T1, T2, T3)] = new Liftable[(T1, T2, T3)] { - def toExpr(x: (T1, T2, T3)) given QuoteContext: Expr[(T1, T2, T3)] = + def toExpr(x: (T1, T2, T3)) = '{ Tuple3[$t1, $t2, $t3](${x._1}, ${x._2}, ${x._3}) } } implicit def Tuple4IsLiftable[T1: Liftable, T2: Liftable, T3: Liftable, T4: Liftable](implicit t1: Type[T1], t2: Type[T2], t3: Type[T3], t4: Type[T4]): Liftable[(T1, T2, T3, T4)] = new Liftable[(T1, T2, T3, T4)] { - def toExpr(x: (T1, T2, T3, T4)) given QuoteContext: Expr[(T1, T2, T3, T4)] = + def toExpr(x: (T1, T2, T3, T4)) = '{ Tuple4[$t1, $t2, $t3, $t4](${x._1}, ${x._2}, ${x._3}, ${x._4}) } } @@ -102,7 +102,7 @@ package liftable { object Lists { implicit def ListIsLiftable[T: Liftable](implicit t: Type[T]): Liftable[List[T]] = new Liftable[List[T]] { - def toExpr(x: List[T]) given QuoteContext: Expr[List[T]] = x match { + def toExpr(x: List[T]): given QuoteContext => Expr[List[T]] = x match { case x :: xs => '{ (${xs}).::[$t](${x}) } case Nil => '{ Nil: List[$t] } } @@ -128,7 +128,7 @@ package liftable { object Arrays { implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], ct: Expr[ClassTag[T]]): Liftable[Array[T]] = new Liftable[Array[T]] { - def toExpr(arr: Array[T]) given QuoteContext: Expr[Array[T]] = '{ new Array[$t](${arr.length})($ct) } + def toExpr(arr: Array[T]) = '{ new Array[$t](${arr.length})($ct) } } } diff --git a/tests/run-with-compiler/quote-unrolled-foreach.scala b/tests/run-with-compiler/quote-unrolled-foreach.scala index 117807b0963d..86b5c56184df 100644 --- a/tests/run-with-compiler/quote-unrolled-foreach.scala +++ b/tests/run-with-compiler/quote-unrolled-foreach.scala @@ -118,7 +118,7 @@ object Test { } implicit object ArrayIntIsLiftable extends Liftable[Array[Int]] { - override def toExpr(x: Array[Int]) given QuoteContext: Expr[Array[Int]] = '{ + override def toExpr(x: Array[Int]) = '{ val array = new Array[Int](${x.length}) ${ foreachInRange(0, x.length)(i => '{ array(${i}) = ${x(i)}}) } array diff --git a/tests/run-with-compiler/shonan-hmm-simple.scala b/tests/run-with-compiler/shonan-hmm-simple.scala index 8c139e46d112..56ffad70fe21 100644 --- a/tests/run-with-compiler/shonan-hmm-simple.scala +++ b/tests/run-with-compiler/shonan-hmm-simple.scala @@ -72,7 +72,7 @@ case class Complex[T](re: T, im: T) object Complex { implicit def isLiftable[T: Type: Liftable]: Liftable[Complex[T]] = new Liftable[Complex[T]] { - def toExpr(comp: Complex[T]) given QuoteContext: Expr[Complex[T]] = '{Complex(${comp.re}, ${comp.im})} + def toExpr(comp: Complex[T]) = '{Complex(${comp.re}, ${comp.im})} } } diff --git a/tests/run-with-compiler/shonan-hmm/Complex.scala b/tests/run-with-compiler/shonan-hmm/Complex.scala index 43d7776f3e83..8fe5ac91a4ea 100644 --- a/tests/run-with-compiler/shonan-hmm/Complex.scala +++ b/tests/run-with-compiler/shonan-hmm/Complex.scala @@ -5,7 +5,7 @@ case class Complex[T](re: T, im: T) object Complex { implicit def complexIsLiftable[T: Type: Liftable]: Liftable[Complex[T]] = new Liftable { - def toExpr(c: Complex[T]) given QuoteContext: Expr[Complex[T]] = '{ Complex(${c.re.toExpr}, ${c.im.toExpr}) } + def toExpr(c: Complex[T]) = '{ Complex(${c.re.toExpr}, ${c.im.toExpr}) } } def of_complex_expr(x: Expr[Complex[Int]]) given QuoteContext: Complex[Expr[Int]] = Complex('{$x.re}, '{$x.im}) diff --git a/tests/run-with-compiler/shonan-hmm/Lifters.scala b/tests/run-with-compiler/shonan-hmm/Lifters.scala index 199da46f1a96..3be354ec0fda 100644 --- a/tests/run-with-compiler/shonan-hmm/Lifters.scala +++ b/tests/run-with-compiler/shonan-hmm/Lifters.scala @@ -11,14 +11,14 @@ object Lifters { } implicit def ArrayIsLiftable[T : Type: ClassTag](implicit l: Liftable[T]): Liftable[Array[T]] = new Liftable[Array[T]] { - def toExpr(x: Array[T]) given QuoteContext: Expr[Array[T]] = '{ + def toExpr(x: Array[T]) = '{ val array = new Array[T](${x.length})(${implicitly[Expr[ClassTag[T]]]}) ${initArray(x, 'array)} } } implicit def IntArrayIsLiftable: Liftable[Array[Int]] = new Liftable[Array[Int]] { - def toExpr(x: Array[Int]) given QuoteContext: Expr[Array[Int]] = '{ + def toExpr(x: Array[Int]) = '{ val array = new Array[Int](${x.length}) ${initArray(x, 'array)} }