diff --git a/library/src/scala/quoted/Liftable.scala b/library/src/scala/quoted/Liftable.scala index 4bb43917a166..871fde9ee6c0 100644 --- a/library/src/scala/quoted/Liftable.scala +++ b/library/src/scala/quoted/Liftable.scala @@ -15,16 +15,45 @@ abstract class Liftable[T] { * gives an alternative implementation using just the basic staging system. */ object Liftable { - implicit def BooleanIsLiftable: Liftable[Boolean] = (x: Boolean) => liftedExpr(x) - implicit def ByteIsLiftable: Liftable[Byte] = (x: Byte) => liftedExpr(x) - implicit def CharIsLiftable: Liftable[Char] = (x: Char) => liftedExpr(x) - implicit def ShortIsLiftable: Liftable[Short] = (x: Short) => liftedExpr(x) - implicit def IntIsLiftable: Liftable[Int] = (x: Int) => liftedExpr(x) - implicit def LongIsLiftable: Liftable[Long] = (x: Long) => liftedExpr(x) - implicit def FloatIsLiftable: Liftable[Float] = (x: Float) => liftedExpr(x) - implicit def DoubleIsLiftable: Liftable[Double] = (x: Double) => liftedExpr(x) - - implicit def StringIsLiftable: Liftable[String] = (x: String) => liftedExpr(x) - - implicit def ClassIsLiftable[T]: Liftable[Class[T]] = (x: Class[T]) => liftedExpr(x) + + implicit def BooleanIsLiftable: Liftable[Boolean] = new Liftable[Boolean] { + def toExpr(x: Boolean): Expr[Boolean] = liftedExpr(x) + } + + implicit def ByteIsLiftable: Liftable[Byte] = new Liftable[Byte] { + def toExpr(x: Byte): Expr[Byte] = liftedExpr(x) + } + + implicit def CharIsLiftable: Liftable[Char] = new Liftable[Char] { + def toExpr(x: Char): Expr[Char] = liftedExpr(x) + } + + implicit def ShortIsLiftable: Liftable[Short] = new Liftable[Short] { + def toExpr(x: Short): Expr[Short] = liftedExpr(x) + } + + implicit def IntIsLiftable: Liftable[Int] = new Liftable[Int] { + def toExpr(x: Int): Expr[Int] = liftedExpr(x) + } + + implicit def LongIsLiftable: Liftable[Long] = new Liftable[Long] { + def toExpr(x: Long): Expr[Long] = liftedExpr(x) + } + + implicit def FloatIsLiftable: Liftable[Float] = new Liftable[Float] { + def toExpr(x: Float): Expr[Float] = liftedExpr(x) + } + + implicit def DoubleIsLiftable: Liftable[Double] = new Liftable[Double] { + def toExpr(x: Double): Expr[Double] = liftedExpr(x) + } + + implicit def StringIsLiftable: Liftable[String] = new Liftable[String] { + def toExpr(x: String): Expr[String] = liftedExpr(x) + } + + implicit def ClassIsLiftable[T]: Liftable[Class[T]] = new Liftable[Class[T]] { + def toExpr(x: Class[T]): Expr[Class[T]] = liftedExpr(x) + } + } diff --git a/tests/run-with-compiler/i3847-b.scala b/tests/run-with-compiler/i3847-b.scala index 6e06d1c3da55..370322f5f071 100644 --- a/tests/run-with-compiler/i3847-b.scala +++ b/tests/run-with-compiler/i3847-b.scala @@ -3,9 +3,13 @@ import scala.quoted._ import scala.reflect.ClassTag object Arrays { - implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T]): Liftable[Array[List[T]]] = (arr: Array[List[T]]) => '{ - new Array[List[~t]](~arr.length.toExpr) - // TODO add elements + implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T]): Liftable[Array[List[T]]] = { + new Liftable[Array[List[T]]] { + def toExpr(arr: Array[List[T]]): Expr[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 1aef635e21e3..43a3efb5d573 100644 --- a/tests/run-with-compiler/i3847.scala +++ b/tests/run-with-compiler/i3847.scala @@ -3,9 +3,13 @@ import scala.quoted._ import scala.reflect.ClassTag object Arrays { - implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], ct: Expr[ClassTag[T]]): Liftable[Array[T]] = (arr: Array[T]) => '{ - new Array[~t](~arr.length.toExpr)(~ct) - // TODO add elements + 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]): Expr[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 2031c329f714..599504c2bb9a 100644 --- a/tests/run-with-compiler/quote-lib.scala +++ b/tests/run-with-compiler/quote-lib.scala @@ -53,7 +53,9 @@ package liftable { } object Units { - implicit def UnitIsLiftable: Liftable[Unit] = _=> '{ () } + implicit def UnitIsLiftable: Liftable[Unit] = new Liftable[Unit] { + def toExpr(x: Unit): Expr[Unit] = '() + } } object Lets { @@ -72,20 +74,26 @@ package liftable { object Tuples { - implicit def Tuple1IsLiftable[T1: Liftable](implicit t1: Type[T1]): Liftable[Tuple1[T1]] = { - case Tuple1(x1: T1) => '{ Tuple1[~t1](~x1.toExpr) } + implicit def Tuple1IsLiftable[T1: Liftable](implicit t1: Type[T1]): Liftable[Tuple1[T1]] = new Liftable[Tuple1[T1]] { + def toExpr(x: Tuple1[T1]): Expr[Tuple1[T1]] = + '{ Tuple1[~t1](~x._1.toExpr) } } - implicit def Tuple2IsLiftable[T1: Liftable, T2: Liftable](implicit t1: Type[T1], t2: Type[T2]): Liftable[(T1, T2)] = { - x => '{ Tuple2[~t1, ~t2](~x._1.toExpr, ~x._2.toExpr) } + 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)): Expr[(T1, T2)] = + '{ Tuple2[~t1, ~t2](~x._1.toExpr, ~x._2.toExpr) } + } - implicit def Tuple3IsLiftable[T1: Liftable, T2: Liftable, T3: Liftable](implicit t1: Type[T1], t2: Type[T2], t3: Type[T3]): Liftable[(T1, T2, T3)] = { - x => '{ Tuple3[~t1, ~t2, ~t3](~x._1.toExpr, ~x._2.toExpr, ~x._3.toExpr) } + 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)): Expr[(T1, T2, T3)] = + '{ Tuple3[~t1, ~t2, ~t3](~x._1.toExpr, ~x._2.toExpr, ~x._3.toExpr) } + } - 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)] = { - x => '{ Tuple4[~t1, ~t2, ~t3, ~t4](~x._1.toExpr, ~x._2.toExpr, ~x._3.toExpr, ~x._4.toExpr) } + 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)): Expr[(T1, T2, T3, T4)] = + '{ Tuple4[~t1, ~t2, ~t3, ~t4](~x._1.toExpr, ~x._2.toExpr, ~x._3.toExpr, ~x._4.toExpr) } } // TODO more tuples @@ -94,9 +102,11 @@ package liftable { object Lists { - implicit def ListIsLiftable[T: Liftable](implicit t: Type[T]): Liftable[List[T]] = { - case x :: xs => '{ (~xs.toExpr).::[~t](~x.toExpr) } - case Nil => '{ Nil: List[~t] } + implicit def ListIsLiftable[T: Liftable](implicit t: Type[T]): Liftable[List[T]] = new Liftable[List[T]] { + def toExpr(x: List[T]): Expr[List[T]] = x match { + case x :: xs => '{ (~xs.toExpr).::[~t](~x.toExpr) } + case Nil => '{ Nil: List[~t] } + } } implicit class LiftedOps[T: Liftable](list: Expr[List[T]])(implicit t: Type[T]) { @@ -118,8 +128,8 @@ package liftable { } object Arrays { - implicit def ArrayIsLiftable[T: Liftable](implicit t: Type[T], ct: Expr[ClassTag[T]]): Liftable[Array[T]] = (arr: Array[T]) => '{ - new Array[~t](~arr.length.toExpr)(~ct) + 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]): Expr[Array[T]] = '{ new Array[~t](~arr.length.toExpr)(~ct) } } }