diff --git a/library/src-bootstrapped/scala/quoted/Liftable.scala b/library/src-bootstrapped/scala/quoted/Liftable.scala index c555ddaf8613..d12651540de4 100644 --- a/library/src-bootstrapped/scala/quoted/Liftable.scala +++ b/library/src-bootstrapped/scala/quoted/Liftable.scala @@ -37,7 +37,7 @@ object Liftable { } } - implicit def ClassIsLiftable[T]: Liftable[Class[T]] = new Liftable[Class[T]] { + given ClassIsLiftable[T] as Liftable[Class[T]] = new Liftable[Class[T]] { /** Lift a `Class[T]` into `'{ classOf[T] }` */ def toExpr(x: Class[T]) = given qctx => { import qctx.tasty._ @@ -45,18 +45,67 @@ object Liftable { } } + given ClassTagIsLiftable[T: Type] as Liftable[ClassTag[T]] = new Liftable[ClassTag[T]] { + def toExpr(ct: ClassTag[T]): given QuoteContext => Expr[ClassTag[T]] = + '{ ClassTag[T](${ct.runtimeClass.toExpr}) } + } + given ArrayIsLiftable[T: Type: Liftable: ClassTag] as Liftable[Array[T]] = new Liftable[Array[T]] { - def toExpr(arr: Array[T]): given QuoteContext => Expr[Array[T]] = '{ - val array = new Array[T](${arr.length.toExpr})(ClassTag(${the[ClassTag[T]].runtimeClass.toExpr})) - ${ Expr.block(List.tabulate(arr.length)(i => '{ array(${i.toExpr}) = ${arr(i).toExpr} }), '{ array }) } - } + def toExpr(arr: Array[T]): given QuoteContext => Expr[Array[T]] = + '{ Array[T](${arr.toSeq.toExpr}: _*)(${the[ClassTag[T]].toExpr}) } } - given IArrayIsLiftable[T: Type: Liftable: ClassTag] as Liftable[IArray[T]] = new Liftable[IArray[T]] { - def toExpr(iarray: IArray[T]): given QuoteContext => Expr[IArray[T]] = '{ - val array = new Array[T](${iarray.length.toExpr})(ClassTag(${the[ClassTag[T]].runtimeClass.toExpr})) - ${ Expr.block(List.tabulate(iarray.length)(i => '{ array(${i.toExpr}) = ${iarray(i).toExpr} }), '{ array.asInstanceOf[IArray[T]] }) } - } + given ArrayOfBooleanIsLiftable as Liftable[Array[Boolean]] = new Liftable[Array[Boolean]] { + def toExpr(array: Array[Boolean]): given QuoteContext => Expr[Array[Boolean]] = + if (array.length == 0) '{ Array.emptyBooleanArray } + else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) } + } + + given ArrayOfByteIsLiftable as Liftable[Array[Byte]] = new Liftable[Array[Byte]] { + def toExpr(array: Array[Byte]): given QuoteContext => Expr[Array[Byte]] = + if (array.length == 0) '{ Array.emptyByteArray } + else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) } + } + + given ArrayOfShortIsLiftable as Liftable[Array[Short]] = new Liftable[Array[Short]] { + def toExpr(array: Array[Short]): given QuoteContext => Expr[Array[Short]] = + if (array.length == 0) '{ Array.emptyShortArray } + else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) } + } + + given ArrayOfCharIsLiftable as Liftable[Array[Char]] = new Liftable[Array[Char]] { + def toExpr(array: Array[Char]): given QuoteContext => Expr[Array[Char]] = + if (array.length == 0) '{ Array.emptyCharArray } + else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) } + } + + given ArrayOfIntIsLiftable as Liftable[Array[Int]] = new Liftable[Array[Int]] { + def toExpr(array: Array[Int]): given QuoteContext => Expr[Array[Int]] = + if (array.length == 0) '{ Array.emptyIntArray } + else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) } + } + + given ArrayOfLongIsLiftable as Liftable[Array[Long]] = new Liftable[Array[Long]] { + def toExpr(array: Array[Long]): given QuoteContext => Expr[Array[Long]] = + if (array.length == 0) '{ Array.emptyLongArray } + else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) } + } + + given ArrayOfFloatIsLiftable as Liftable[Array[Float]] = new Liftable[Array[Float]] { + def toExpr(array: Array[Float]): given QuoteContext => Expr[Array[Float]] = + if (array.length == 0) '{ Array.emptyFloatArray } + else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) } + } + + given ArrayOfDoubleIsLiftable as Liftable[Array[Double]] = new Liftable[Array[Double]] { + def toExpr(array: Array[Double]): given QuoteContext => Expr[Array[Double]] = + if (array.length == 0) '{ Array.emptyDoubleArray } + else '{ Array(${array(0).toExpr}, ${array.toSeq.tail.toExpr}: _*) } + } + + given IArrayIsLiftable[T: Type] as Liftable[IArray[T]] given (ltArray: Liftable[Array[T]]) = new Liftable[IArray[T]] { + def toExpr(iarray: IArray[T]): given QuoteContext => Expr[IArray[T]] = + '{ ${ltArray.toExpr(iarray.asInstanceOf[Array[T]])}.asInstanceOf[IArray[T]] } } given [T: Type: Liftable] as Liftable[Seq[T]] = new Liftable[Seq[T]] { diff --git a/tests/run-with-compiler/quote-lib.scala b/tests/run-with-compiler/quote-lib.scala index 4e036949d001..915f8fe28736 100644 --- a/tests/run-with-compiler/quote-lib.scala +++ b/tests/run-with-compiler/quote-lib.scala @@ -68,9 +68,32 @@ object Test { val iarray: IArray[Int] = IArray(1, 2, 3) val liftedIArray: Expr[IArray[Int]] = iarray + val iarray2: IArray[String] = IArray("a", "b", "c") + iarray2.toExpr + + IArray(false).toExpr + IArray(1: Byte).toExpr + IArray(1: Short).toExpr + IArray(1).toExpr + IArray(1L).toExpr + IArray(1.1f).toExpr + IArray(1.1d).toExpr + IArray('a').toExpr + IArray((1, 3)).toExpr + val array: Array[Int] = Array(1, 2, 3) val liftedArray: Expr[Array[Int]] = array + Array(false).toExpr + Array(1: Byte).toExpr + Array(1: Short).toExpr + Array(1).toExpr + Array(1L).toExpr + Array(1.1f).toExpr + Array(1.1d).toExpr + Array('a').toExpr + Array((1, 3)).toExpr + val some: Option[Int] = Some(2) val none: Option[Int] = Some(2) val liftedSome: Expr[Option[Int]] = some diff --git a/tests/run-with-compiler/quote-lift-Array.check b/tests/run-with-compiler/quote-lift-Array.check new file mode 100644 index 000000000000..8520859a40fd --- /dev/null +++ b/tests/run-with-compiler/quote-lift-Array.check @@ -0,0 +1,19 @@ +[] +[] +[] +[] +[] +[] +[] +[] +[] + +[true] +[1, 2] +[2, 3] +[a, b] +[4, 5] +[6, 7] +[2.1, 3.2] +[2.2, 3.3] +[abc, xyz] diff --git a/tests/run-with-compiler/quote-lift-Array.scala b/tests/run-with-compiler/quote-lift-Array.scala new file mode 100644 index 000000000000..45db0fb959bf --- /dev/null +++ b/tests/run-with-compiler/quote-lift-Array.scala @@ -0,0 +1,32 @@ +import scala.quoted._ +import scala.quoted.autolift._ + +object Test { + implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + def main(args: Array[String]): Unit = run { + '{ + def p[T](arr: Array[T]): Unit = { + println(arr.asInstanceOf[Array[_]].mkString("[", ", ", "]")) + } + p(${Array.empty[Boolean]}) + p(${Array.empty[Byte]}) + p(${Array.empty[Short]}) + p(${Array.empty[Char]}) + p(${Array.empty[Int]}) + p(${Array.empty[Long]}) + p(${Array.empty[Float]}) + p(${Array.empty[Double]}) + p(${Array.empty[String]}) + println() + p(${Array(true)}) + p(${Array[Byte](1, 2)}) + p(${Array[Short](2, 3)}) + p(${Array[Char]('a', 'b')}) + p(${Array[Int](4, 5)}) + p(${Array[Long](6L, 7L)}) + p(${Array[Float](2.1f, 3.2f)}) + p(${Array[Double](2.2, 3.3)}) + p(${Array("abc", "xyz")}) + } + } +} \ No newline at end of file diff --git a/tests/run-with-compiler/quote-lift-IArray.check b/tests/run-with-compiler/quote-lift-IArray.check new file mode 100644 index 000000000000..8520859a40fd --- /dev/null +++ b/tests/run-with-compiler/quote-lift-IArray.check @@ -0,0 +1,19 @@ +[] +[] +[] +[] +[] +[] +[] +[] +[] + +[true] +[1, 2] +[2, 3] +[a, b] +[4, 5] +[6, 7] +[2.1, 3.2] +[2.2, 3.3] +[abc, xyz] diff --git a/tests/run-with-compiler/quote-lift-IArray.scala b/tests/run-with-compiler/quote-lift-IArray.scala new file mode 100644 index 000000000000..c90144e4db52 --- /dev/null +++ b/tests/run-with-compiler/quote-lift-IArray.scala @@ -0,0 +1,32 @@ +import scala.quoted._ +import scala.quoted.autolift._ + +object Test { + implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + def main(args: Array[String]): Unit = run { + '{ + def p[T](arr: IArray[T]): Unit = { + println(arr.asInstanceOf[Array[_]].mkString("[", ", ", "]")) + } + p(${IArray.empty[Boolean]}) + p(${IArray.empty[Byte]}) + p(${IArray.empty[Short]}) + p(${IArray.empty[Char]}) + p(${IArray.empty[Int]}) + p(${IArray.empty[Long]}) + p(${IArray.empty[Float]}) + p(${IArray.empty[Double]}) + p(${IArray.empty[String]}) + println() + p(${IArray(true)}) + p(${IArray[Byte](1, 2)}) + p(${IArray[Short](2, 3)}) + p(${IArray[Char]('a', 'b')}) + p(${IArray[Int](4, 5)}) + p(${IArray[Long](6L, 7L)}) + p(${IArray[Float](2.1f, 3.2f)}) + p(${IArray[Double](2.2, 3.3)}) + p(${IArray("abc", "xyz")}) + } + } +} \ No newline at end of file