diff --git a/library/src/scala/quoted/package.scala b/library/src/scala/quoted/package.scala index 0868eee2188e..71c9a7d97c37 100644 --- a/library/src/scala/quoted/package.scala +++ b/library/src/scala/quoted/package.scala @@ -56,7 +56,7 @@ package object quoted { /** Lifts this sequence of expressions into an expression of a sequence * - * Transforms a list of expression + * Transforms a sequence of expression * `Seq(e1, e2, ...)` where `ei: Expr[T]` * to an expression equivalent to * `'{ Seq($e1, $e2, ...) }` typed as an `Expr[Seq[T]]` @@ -81,7 +81,42 @@ package object quoted { def (list: List[Expr[T]]) toExprOfList[T] given Type[T], QuoteContext: Expr[List[T]] = if (list.isEmpty) '{ Nil } else '{ List(${list.toExprOfSeq}: _*) } + /** Lifts this sequence of expressions into an expression of a tuple + * + * Transforms a sequence of expression + * `Seq(e1, e2, ...)` where `ei: Expr[_]` + * to an expression equivalent to + * `'{ ($e1, $e2, ...) }` typed as an `Expr[Tuple]` + */ + def (seq: Seq[Expr[_]]) toExprOfTuple given QuoteContext: Expr[Tuple] = { + seq.size match { + case 0 => Expr.unitExpr + case 1 => '{ Tuple1( ${seq(0)}) } + case 2 => '{ Tuple2( ${seq(0)}, ${seq(1)}) } + case 3 => '{ Tuple3( ${seq(0)}, ${seq(1)}, ${seq(2)}) } + case 4 => '{ Tuple4( ${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}) } + case 5 => '{ Tuple5( ${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}) } + case 6 => '{ Tuple6( ${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}) } + case 7 => '{ Tuple7( ${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}) } + case 8 => '{ Tuple8( ${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}) } + case 9 => '{ Tuple9( ${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}) } + case 10 => '{ Tuple10(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}) } + case 11 => '{ Tuple11(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}) } + case 12 => '{ Tuple12(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}) } + case 13 => '{ Tuple13(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}) } + case 14 => '{ Tuple14(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}, ${seq(13)}) } + case 15 => '{ Tuple15(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}, ${seq(13)}, ${seq(14)}) } + case 16 => '{ Tuple16(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}, ${seq(13)}, ${seq(14)}, ${seq(15)}) } + case 17 => '{ Tuple17(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}, ${seq(13)}, ${seq(14)}, ${seq(15)}, ${seq(16)}) } + case 18 => '{ Tuple18(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}, ${seq(13)}, ${seq(14)}, ${seq(15)}, ${seq(16)}, ${seq(17)}) } + case 19 => '{ Tuple19(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}, ${seq(13)}, ${seq(14)}, ${seq(15)}, ${seq(16)}, ${seq(17)}, ${seq(18)}) } + case 20 => '{ Tuple20(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}, ${seq(13)}, ${seq(14)}, ${seq(15)}, ${seq(16)}, ${seq(17)}, ${seq(18)}, ${seq(19)}) } + case 21 => '{ Tuple21(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}, ${seq(13)}, ${seq(14)}, ${seq(15)}, ${seq(16)}, ${seq(17)}, ${seq(18)}, ${seq(19)}, ${seq(20)}) } + case 22 => '{ Tuple22(${seq(0)}, ${seq(1)}, ${seq(2)}, ${seq(3)}, ${seq(4)}, ${seq(5)}, ${seq(6)}, ${seq(7)}, ${seq(8)}, ${seq(9)}, ${seq(10)}, ${seq(11)}, ${seq(12)}, ${seq(13)}, ${seq(14)}, ${seq(15)}, ${seq(16)}, ${seq(17)}, ${seq(18)}, ${seq(19)}, ${seq(20)}, ${seq(21)}) } + case _ => '{ Tuple.fromIArray(IArray(${seq.toExprOfSeq}: _*)) } + } + } } } diff --git a/tests/run-with-compiler/quote-toExprOfTuple.check b/tests/run-with-compiler/quote-toExprOfTuple.check new file mode 100644 index 000000000000..a399c027260a --- /dev/null +++ b/tests/run-with-compiler/quote-toExprOfTuple.check @@ -0,0 +1,26 @@ +() +(1) +(1,2) +(1,2,3) +(1,2,3,4) +(1,2,3,4,5) +(1,2,3,4,5,6) +(1,2,3,4,5,6,7) +(1,2,3,4,5,6,7,8) +(1,2,3,4,5,6,7,8,9) +(1,2,3,4,5,6,7,8,9,10) +(1,2,3,4,5,6,7,8,9,10,11) +(1,2,3,4,5,6,7,8,9,10,11,12) +(1,2,3,4,5,6,7,8,9,10,11,12,13) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24) +(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25) diff --git a/tests/run-with-compiler/quote-toExprOfTuple.scala b/tests/run-with-compiler/quote-toExprOfTuple.scala new file mode 100644 index 000000000000..bf11ea82f126 --- /dev/null +++ b/tests/run-with-compiler/quote-toExprOfTuple.scala @@ -0,0 +1,17 @@ + +import scala.quoted._ + +object Test { + implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader) + def main(args: Array[String]): Unit = { + for (n <- 0 to 25) { + prev = 0 + println(run { Seq.fill(n)('{next}).toExprOfTuple }) + } + } + var prev = 0 + def next: Int = { + prev += 1 + prev + } +}