diff --git a/compiler/src/dotty/tools/dotc/transform/SeqLiterals.scala b/compiler/src/dotty/tools/dotc/transform/SeqLiterals.scala index b6daa0f1388c..46c3a6617088 100644 --- a/compiler/src/dotty/tools/dotc/transform/SeqLiterals.scala +++ b/compiler/src/dotty/tools/dotc/transform/SeqLiterals.scala @@ -31,6 +31,6 @@ class SeqLiterals extends MiniPhase { val arr = JavaSeqLiteral(tree.elems, tree.elemtpt) //println(i"trans seq $tree, arr = $arr: ${arr.tpe} ${arr.tpe.elemType}") val elemtp = tree.elemtpt.tpe - wrapArray(arr, elemtp) + wrapArray(arr, elemtp).withSpan(tree.span) } } diff --git a/library/src-bootstrapped/scala/quoted/package.scala b/library/src-bootstrapped/scala/quoted/package.scala index 125a87dafc96..7a1448e939ab 100644 --- a/library/src-bootstrapped/scala/quoted/package.scala +++ b/library/src-bootstrapped/scala/quoted/package.scala @@ -54,10 +54,34 @@ package object quoted { implicit object ExprOps { def (x: T) toExpr[T: Liftable] given QuoteContext: Expr[T] = the[Liftable[T]].toExpr(x) - def (list: List[Expr[T]]) toExprOfList[T: Type] given QuoteContext: Expr[List[T]] = list match { - case x :: xs => '{ $x :: ${xs.toExprOfList} } - case Nil => '{ Nil } + /** Lifts this sequence of expressions into an expression of a sequence + * + * Transforms a list of expression + * `Seq(e1, e2, ...)` where `ei: Expr[T]` + * to an expression equivalent to + * `'{ Seq($e1, $e2, ...) }` typed as an `Expr[Seq[T]]` + * + * Usage: + * ```scala + * '{ List(${List(1, 2, 3).toExprOfSeq}: _*) } // equvalent to '{ List(1, 2, 3) } + * ``` + */ + def (seq: Seq[Expr[T]]) toExprOfSeq[T] given (tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = { + import qctx.tasty._ + Repeated(seq.map(_.unseal).toList, tp.unseal).seal.asInstanceOf[Expr[Seq[T]]] } + + /** Lifts this list of expressions into an expression of a list + * + * Transforms a list of expression + * `List(e1, e2, ...)` where `ei: Expr[T]` + * to an expression equivalent to + * `'{ List($e1, $e2, ...) }` typed as an `Expr[List[T]]` + */ + def (list: List[Expr[T]]) toExprOfList[T] given Type[T], QuoteContext: Expr[List[T]] = + if (list.isEmpty) '{ Nil } else '{ List(${list.toExprOfSeq}: _*) } + + } } diff --git a/tests/run-macros/i6765-b.check b/tests/run-macros/i6765-b.check index 2d03ff93827f..901cc3d4c685 100644 --- a/tests/run-macros/i6765-b.check +++ b/tests/run-macros/i6765-b.check @@ -1,8 +1,2 @@ -{ - val x$3: java.lang.String = "One" - scala.Nil.::[java.lang.String](x$3) -} -{ - val x$3: java.lang.String = "One" - scala.Nil.::[java.lang.String](x$3) -} +scala.List.apply[java.lang.String]("One": _*) +scala.List.apply[java.lang.String]("One": _*) diff --git a/tests/run-macros/i6765-c.check b/tests/run-macros/i6765-c.check new file mode 100644 index 000000000000..70fd221e7a5d --- /dev/null +++ b/tests/run-macros/i6765-c.check @@ -0,0 +1,18 @@ +scala.Nil +List() + +scala.List.apply[java.lang.String]("#0": _*) +List(#0) + +scala.List.apply[java.lang.String]("#0", "#1": _*) +List(#0, #1) + +scala.List.apply[java.lang.String]("#0", "#1", "#2": _*) +List(#0, #1, #2) + +scala.List.apply[java.lang.String]("#0", "#1", "#2", "#3": _*) +List(#0, #1, #2, #3) + +scala.List.apply[java.lang.String]("#0", "#1", "#2", "#3", "#4": _*) +List(#0, #1, #2, #3, #4) + diff --git a/tests/run-macros/i6765-c/Macro_1.scala b/tests/run-macros/i6765-c/Macro_1.scala new file mode 100644 index 000000000000..9f280d575fdc --- /dev/null +++ b/tests/run-macros/i6765-c/Macro_1.scala @@ -0,0 +1,9 @@ +import scala.quoted._ +import delegate scala.quoted._ + +inline def foo(inline n: Int) = ${fooImpl(n)} + +def fooImpl(n: Int) given (qctx: QuoteContext) = { + val res = List.tabulate(n)(i => ("#" + i).toExpr).toExprOfList + '{ ${res.show.toExpr} + "\n" + $res.toString + "\n" } +} diff --git a/tests/run-macros/i6765-c/Test_2.scala b/tests/run-macros/i6765-c/Test_2.scala new file mode 100644 index 000000000000..f21e25acf8c8 --- /dev/null +++ b/tests/run-macros/i6765-c/Test_2.scala @@ -0,0 +1,10 @@ +object Test { + def main(args: Array[String]): Unit = { + println(foo(0)) + println(foo(1)) + println(foo(2)) + println(foo(3)) + println(foo(4)) + println(foo(5)) + } +} diff --git a/tests/run-macros/i6765.check b/tests/run-macros/i6765.check index 2d03ff93827f..901cc3d4c685 100644 --- a/tests/run-macros/i6765.check +++ b/tests/run-macros/i6765.check @@ -1,8 +1,2 @@ -{ - val x$3: java.lang.String = "One" - scala.Nil.::[java.lang.String](x$3) -} -{ - val x$3: java.lang.String = "One" - scala.Nil.::[java.lang.String](x$3) -} +scala.List.apply[java.lang.String]("One": _*) +scala.List.apply[java.lang.String]("One": _*) diff --git a/tests/run-macros/quote-toExprOfSeq.check b/tests/run-macros/quote-toExprOfSeq.check new file mode 100644 index 000000000000..bba4602df214 --- /dev/null +++ b/tests/run-macros/quote-toExprOfSeq.check @@ -0,0 +1,4 @@ +WrappedArray(1, 2, 3) +WrappedArray(1, 2, 3) +List(1, 2, 3) +2 diff --git a/tests/run-macros/quote-toExprOfSeq/Macro_1.scala b/tests/run-macros/quote-toExprOfSeq/Macro_1.scala new file mode 100644 index 000000000000..fe3b6b090ce6 --- /dev/null +++ b/tests/run-macros/quote-toExprOfSeq/Macro_1.scala @@ -0,0 +1,8 @@ +import scala.quoted._ +import delegate scala.quoted._ + +inline def seq = ${fooImpl} + +def fooImpl given (qctx: QuoteContext) = { + List('{1}, '{2}, '{3}).toExprOfSeq +} diff --git a/tests/run-macros/quote-toExprOfSeq/Test_2.scala b/tests/run-macros/quote-toExprOfSeq/Test_2.scala new file mode 100644 index 000000000000..e45e19af1776 --- /dev/null +++ b/tests/run-macros/quote-toExprOfSeq/Test_2.scala @@ -0,0 +1,9 @@ +object Test { + def main(args: Array[String]): Unit = { + println(seq) + val s: Seq[Int] = seq + println(s) + println(List(seq: _*)) + println(seq(1)) + } +}