From cde14640b7afaa70bf96e658a4956290ecbf9b09 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Mar 2020 09:54:04 +0100 Subject: [PATCH 1/9] Refactor scala.quoted.matching Importing `scala.quoted._` should give access to all the basic functionalities, but currently some half of them need the extra import for `scala.quoted.matching._`. * Move `scala.quoted.matching.summonExpr` to `scala.quoted.Expr.summon` * Move basic quote extractors from `scala.quoted.matching` to `scala.quoted` --- .../dotty/internal/StringContextMacro.scala | 2 -- .../dotty/internal/StringContextMacro.scala | 2 -- .../scala/quoted/{matching => }/Const.scala | 1 - .../quoted/{matching => }/ConstSeq.scala | 1 - library/src/scala/quoted/Expr.scala | 18 ++++++++++- .../scala/quoted/{matching => }/ExprSeq.scala | 1 - .../scala/quoted/{matching => }/Lambda.scala | 1 - .../scala/quoted/{matching => }/Value.scala | 1 - library/src/scala/quoted/ValueOfExpr.scala | 4 +-- .../quoted/{matching => }/ValueSeq.scala | 1 - .../src/scala/quoted/matching/package.scala | 31 ++++++++++++++----- tests/neg-macros/GenericNumLits/Even_1.scala | 2 +- .../neg-macros/delegate-match-1/Macro_1.scala | 2 +- .../neg-macros/delegate-match-2/Macro_1.scala | 2 +- .../neg-macros/delegate-match-3/Macro_1.scala | 2 +- tests/neg-macros/i6432/Macro_1.scala | 2 +- tests/neg-macros/i6432b/Macro_1.scala | 2 +- .../Macro_1.scala | 2 +- .../GenericNumLits/Even_1.scala | 2 +- tests/neg/BigFloat/BigFloat_1.scala | 2 +- tests/neg/i6325.scala | 1 - tests/neg/i6436.scala | 2 +- tests/neg/i8052.scala | 2 +- .../i7853/SummonJsonEncoderTest_2.scala | 4 +-- tests/pos-macros/i8325/Macro_1.scala | 2 +- tests/pos-macros/i8325b/Macro_1.scala | 2 +- tests/pos/i6435.scala | 2 +- tests/pos/i8052.scala | 2 +- tests/run-macros/BigFloat/BigFloat_1.scala | 2 +- tests/run-macros/expr-map-1/Macro_1.scala | 2 +- tests/run-macros/expr-map-2/Macro_1.scala | 2 +- .../f-interpolator-neg/Macros_1.scala | 2 +- .../run-macros/flops-rewrite-2/Macro_1.scala | 2 +- .../run-macros/flops-rewrite-3/Macro_1.scala | 2 +- tests/run-macros/i6253-b/quoted_1.scala | 2 +- tests/run-macros/i6253/quoted_1.scala | 2 +- tests/run-macros/i7987/Macros_1.scala | 4 +-- tests/run-macros/i8007/Macro_1.scala | 4 +-- tests/run-macros/i8007/Macro_2.scala | 4 +-- tests/run-macros/i8007/Macro_3.scala | 4 +-- .../Macro_1.scala | 2 +- .../lambda-extractor-1/Macro_1.scala | 2 +- .../lambda-extractor-2/Macro_1.scala | 2 +- .../quote-implicitMatch/Macro_1.scala | 8 ++--- .../quote-matcher-power/Macro_1.scala | 2 +- .../quoted_1.scala | 2 +- .../quoted_1.scala | 2 +- .../quoted_1.scala | 2 +- .../quote-matcher-symantics-1/quoted_1.scala | 2 +- .../quote-matcher-symantics-2/quoted_1.scala | 2 +- .../quote-matcher-symantics-3/quoted_1.scala | 2 +- .../quote-matcher-type-bind/Macro_1.scala | 2 +- .../quoted-matching-docs-2/Macro_1.scala | 2 +- .../quoted-matching-docs/Macro_1.scala | 2 +- .../string-context-implicits/Macro_1.scala | 4 +-- .../quoted_1.scala | 2 +- .../Macros_1.scala | 2 +- 57 files changed, 96 insertions(+), 76 deletions(-) rename library/src/scala/quoted/{matching => }/Const.scala (97%) rename library/src/scala/quoted/{matching => }/ConstSeq.scala (98%) rename library/src/scala/quoted/{matching => }/ExprSeq.scala (98%) rename library/src/scala/quoted/{matching => }/Lambda.scala (98%) rename library/src/scala/quoted/{matching => }/Value.scala (95%) rename library/src/scala/quoted/{matching => }/ValueSeq.scala (98%) diff --git a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala index 8eead6a9ec9e..275f894a0099 100644 --- a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala +++ b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala @@ -3,8 +3,6 @@ package dotty.internal import scala.quoted._ -import scala.quoted.matching._ -import reflect._ object StringContextMacro { diff --git a/library/src-non-bootstrapped/dotty/internal/StringContextMacro.scala b/library/src-non-bootstrapped/dotty/internal/StringContextMacro.scala index 0f6a2bcf87dc..d72c594dda09 100644 --- a/library/src-non-bootstrapped/dotty/internal/StringContextMacro.scala +++ b/library/src-non-bootstrapped/dotty/internal/StringContextMacro.scala @@ -3,8 +3,6 @@ package dotty.internal import scala.quoted._ -import scala.quoted.matching._ -import reflect._ object StringContextMacro { diff --git a/library/src/scala/quoted/matching/Const.scala b/library/src/scala/quoted/Const.scala similarity index 97% rename from library/src/scala/quoted/matching/Const.scala rename to library/src/scala/quoted/Const.scala index e8c91bdcbe63..ea63147ee55b 100644 --- a/library/src/scala/quoted/matching/Const.scala +++ b/library/src/scala/quoted/Const.scala @@ -1,5 +1,4 @@ package scala.quoted -package matching /** Matches expressions containing literal constant values and extracts the value. * It may match expressions of type Boolean, Byte, Short, Int, Long, diff --git a/library/src/scala/quoted/matching/ConstSeq.scala b/library/src/scala/quoted/ConstSeq.scala similarity index 98% rename from library/src/scala/quoted/matching/ConstSeq.scala rename to library/src/scala/quoted/ConstSeq.scala index b76fa1458c7b..e30d66867c7a 100644 --- a/library/src/scala/quoted/matching/ConstSeq.scala +++ b/library/src/scala/quoted/ConstSeq.scala @@ -1,5 +1,4 @@ package scala.quoted -package matching /** Literal sequence of literal constant value expressions */ object ConstSeq { diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index 4ac15be60bbf..220ba23b1dbc 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -100,7 +100,7 @@ object Expr { } /** Lift a value into an expression containing the construction of that value */ - def apply[T: Liftable](x: T)(using qctx: QuoteContext): Expr[T] = summon[Liftable[T]].toExpr(x) + def apply[T](x: T)(using qctx: QuoteContext, lift: Liftable[T]): Expr[T] = lift.toExpr(x) /** Lifts this sequence of expressions into an expression of a sequence * @@ -197,4 +197,20 @@ object Expr { ofTuple(elems).cast[Tuple.InverseMap[T, Expr]] } + /** Find an implicit of type `T` in the current scope given by `qctx`. + * Return `Some` containing the expression of the implicit or + * `None` if implicit resolution failed. + * + * @tparam T type of the implicit parameter + * @param tpe quoted type of the implicit parameter + * @param qctx current context + */ + def summon[T](using tpe: Type[T])(using qctx: QuoteContext): Option[Expr[T]] = { + import qctx.tasty.{_, given _} + searchImplicit(tpe.unseal.tpe) match { + case iss: ImplicitSearchSuccess => Some(iss.tree.seal.asInstanceOf[Expr[T]]) + case isf: ImplicitSearchFailure => None + } + } + } diff --git a/library/src/scala/quoted/matching/ExprSeq.scala b/library/src/scala/quoted/ExprSeq.scala similarity index 98% rename from library/src/scala/quoted/matching/ExprSeq.scala rename to library/src/scala/quoted/ExprSeq.scala index f8a6f28b9671..689a5921ed05 100644 --- a/library/src/scala/quoted/matching/ExprSeq.scala +++ b/library/src/scala/quoted/ExprSeq.scala @@ -1,5 +1,4 @@ package scala.quoted -package matching /** Literal sequence of expressions */ object ExprSeq { diff --git a/library/src/scala/quoted/matching/Lambda.scala b/library/src/scala/quoted/Lambda.scala similarity index 98% rename from library/src/scala/quoted/matching/Lambda.scala rename to library/src/scala/quoted/Lambda.scala index dbc5bb159fe2..dd22aa06a9df 100644 --- a/library/src/scala/quoted/matching/Lambda.scala +++ b/library/src/scala/quoted/Lambda.scala @@ -1,5 +1,4 @@ package scala.quoted -package matching /** Lambda expression extractor */ object Lambda { diff --git a/library/src/scala/quoted/matching/Value.scala b/library/src/scala/quoted/Value.scala similarity index 95% rename from library/src/scala/quoted/matching/Value.scala rename to library/src/scala/quoted/Value.scala index 38472336f03e..5b8ad7e6f3c4 100644 --- a/library/src/scala/quoted/matching/Value.scala +++ b/library/src/scala/quoted/Value.scala @@ -1,5 +1,4 @@ package scala.quoted -package matching /** Value expressions */ object Value { diff --git a/library/src/scala/quoted/ValueOfExpr.scala b/library/src/scala/quoted/ValueOfExpr.scala index 884282d70907..15fd8495ccce 100644 --- a/library/src/scala/quoted/ValueOfExpr.scala +++ b/library/src/scala/quoted/ValueOfExpr.scala @@ -1,7 +1,5 @@ package scala.quoted -import scala.quoted.matching._ - /** A typeclass for types that can be turned from a `quoted.Expr[T]` to a `T` */ trait ValueOfExpr[T] { @@ -29,7 +27,7 @@ object ValueOfExpr { private class PrimitiveValueOfExpr[T <: Unit | Null | Int | Boolean | Byte | Short | Int | Long | Float | Double | Char | String] extends ValueOfExpr[T] { /** Lift a quoted primitive value `'{ n }` into `n` */ - def apply(x: Expr[T])(using qctx: QuoteContext): Option[T] = matching.Const.unapply(x) + def apply(x: Expr[T])(using qctx: QuoteContext): Option[T] = Const.unapply(x) } given Option_delegate[T](using Type[T], ValueOfExpr[T]) as ValueOfExpr[Option[T]] = new { diff --git a/library/src/scala/quoted/matching/ValueSeq.scala b/library/src/scala/quoted/ValueSeq.scala similarity index 98% rename from library/src/scala/quoted/matching/ValueSeq.scala rename to library/src/scala/quoted/ValueSeq.scala index 87d99dcd4242..035fff7968a6 100644 --- a/library/src/scala/quoted/matching/ValueSeq.scala +++ b/library/src/scala/quoted/ValueSeq.scala @@ -1,5 +1,4 @@ package scala.quoted -package matching /** Value sequence of value expressions */ object ValueSeq { diff --git a/library/src/scala/quoted/matching/package.scala b/library/src/scala/quoted/matching/package.scala index 4ddf474f11d7..3ec880c773d5 100644 --- a/library/src/scala/quoted/matching/package.scala +++ b/library/src/scala/quoted/matching/package.scala @@ -10,12 +10,29 @@ package object matching { * @param tpe quoted type of the implicit parameter * @param qctx current context */ - def summonExpr[T](using tpe: Type[T])(using qctx: QuoteContext): Option[Expr[T]] = { - import qctx.tasty.{_, given _} - searchImplicit(tpe.unseal.tpe) match { - case iss: ImplicitSearchSuccess => Some(iss.tree.seal.asInstanceOf[Expr[T]]) - case isf: ImplicitSearchFailure => None - } - } + @deprecated("use scala.quoted.Expr.summon[T] instead", "0.23.0") + def summonExpr[T](using tpe: Type[T])(using qctx: QuoteContext): Option[Expr[T]] = + Expr.summon[T] + + @deprecated("use scala.quoted.Const instead", "0.23.0") + val Const: quoted.Const.type = quoted.Const + + @deprecated("use scala.quoted.ConstSeq instead", "0.23.0") + val ConstSeq: quoted.ConstSeq.type = quoted.ConstSeq + + @deprecated("use scala.quoted.ExprSeq instead", "0.23.0") + val ExprSeq: quoted.ExprSeq.type = quoted.ExprSeq + + @deprecated("use scala.quoted.Lambda instead", "0.23.0") + val Lambda: quoted.Lambda.type = quoted.Lambda + + @deprecated("use scala.quoted.Value instead", "0.23.0") + val Value: quoted.Value.type = quoted.Value + + @deprecated("use scala.quoted.ValueOfExpr instead", "0.23.0") + val ValueOfExpr: quoted.ValueOfExpr.type = quoted.ValueOfExpr + + @deprecated("use scala.quoted.ValueSeq instead", "0.23.0") + val ValueSeq: quoted.ValueSeq.type = quoted.ValueSeq } diff --git a/tests/neg-macros/GenericNumLits/Even_1.scala b/tests/neg-macros/GenericNumLits/Even_1.scala index c3087600865b..fcb3288dd71e 100644 --- a/tests/neg-macros/GenericNumLits/Even_1.scala +++ b/tests/neg-macros/GenericNumLits/Even_1.scala @@ -1,6 +1,6 @@ import scala.util.FromDigits import scala.quoted._ -import scala.quoted.matching._ + case class Even(n: Int) object Even { diff --git a/tests/neg-macros/delegate-match-1/Macro_1.scala b/tests/neg-macros/delegate-match-1/Macro_1.scala index fca80805efe9..b08ab3f342fc 100644 --- a/tests/neg-macros/delegate-match-1/Macro_1.scala +++ b/tests/neg-macros/delegate-match-1/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def f: Any = ${ fImpl } diff --git a/tests/neg-macros/delegate-match-2/Macro_1.scala b/tests/neg-macros/delegate-match-2/Macro_1.scala index 6d596f33ba77..6ac29dea0b32 100644 --- a/tests/neg-macros/delegate-match-2/Macro_1.scala +++ b/tests/neg-macros/delegate-match-2/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def f: Any = ${ fImpl } diff --git a/tests/neg-macros/delegate-match-3/Macro_1.scala b/tests/neg-macros/delegate-match-3/Macro_1.scala index 5c57a978e7d8..e97d1d4329fb 100644 --- a/tests/neg-macros/delegate-match-3/Macro_1.scala +++ b/tests/neg-macros/delegate-match-3/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def f: Any = ${ fImpl } diff --git a/tests/neg-macros/i6432/Macro_1.scala b/tests/neg-macros/i6432/Macro_1.scala index 26af775563c8..f8e2a34322bc 100644 --- a/tests/neg-macros/i6432/Macro_1.scala +++ b/tests/neg-macros/i6432/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ import scala.quoted.autolift.{given _} -import scala.quoted.matching._ + object Macro { inline def (sc: => StringContext).foo(args: String*): Unit = ${ impl('sc) } diff --git a/tests/neg-macros/i6432b/Macro_1.scala b/tests/neg-macros/i6432b/Macro_1.scala index 26af775563c8..f8e2a34322bc 100644 --- a/tests/neg-macros/i6432b/Macro_1.scala +++ b/tests/neg-macros/i6432b/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ import scala.quoted.autolift.{given _} -import scala.quoted.matching._ + object Macro { inline def (sc: => StringContext).foo(args: String*): Unit = ${ impl('sc) } diff --git a/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala b/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala index 2af0b4d287fb..5dcfb3cad816 100644 --- a/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala +++ b/tests/neg-macros/inline-macro-staged-interpreter/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ import scala.quoted.autolift.{given _} -import scala.quoted.matching._ + object E { diff --git a/tests/neg-with-compiler/GenericNumLits/Even_1.scala b/tests/neg-with-compiler/GenericNumLits/Even_1.scala index c3087600865b..fcb3288dd71e 100644 --- a/tests/neg-with-compiler/GenericNumLits/Even_1.scala +++ b/tests/neg-with-compiler/GenericNumLits/Even_1.scala @@ -1,6 +1,6 @@ import scala.util.FromDigits import scala.quoted._ -import scala.quoted.matching._ + case class Even(n: Int) object Even { diff --git a/tests/neg/BigFloat/BigFloat_1.scala b/tests/neg/BigFloat/BigFloat_1.scala index 480e9a78e145..aae96aa5e3f9 100644 --- a/tests/neg/BigFloat/BigFloat_1.scala +++ b/tests/neg/BigFloat/BigFloat_1.scala @@ -1,7 +1,7 @@ package test import scala.util.FromDigits import scala.quoted._ -import scala.quoted.matching._ + case class BigFloat(mantissa: BigInt, exponent: Int) { override def toString = s"${mantissa}e${exponent}" diff --git a/tests/neg/i6325.scala b/tests/neg/i6325.scala index 2e134d1c1478..e925f890a454 100644 --- a/tests/neg/i6325.scala +++ b/tests/neg/i6325.scala @@ -1,4 +1,3 @@ -//import scala.quoted.matching.Bind object Test { def res(x: quoted.Expr[Int])(using tasty.Reflection): quoted.Expr[Int] = x match { case '{ 1 + (${Bind(b)}: Int) } => ??? // error: Not found: Bind diff --git a/tests/neg/i6436.scala b/tests/neg/i6436.scala index 1161a0efaa77..91071f3fb825 100644 --- a/tests/neg/i6436.scala +++ b/tests/neg/i6436.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + def f(sc: quoted.Expr[StringContext]): Unit = { sc match { case '{ StringContext(${ExprSeq(parts)}: _*) } => // error diff --git a/tests/neg/i8052.scala b/tests/neg/i8052.scala index 6f5cddb8b415..acb40dd85f40 100644 --- a/tests/neg/i8052.scala +++ b/tests/neg/i8052.scala @@ -1,6 +1,6 @@ import scala.deriving._ import scala.quoted._ -import scala.quoted.matching._ + object Macro2 { trait TC[T] { diff --git a/tests/pos-macros/i7853/SummonJsonEncoderTest_2.scala b/tests/pos-macros/i7853/SummonJsonEncoderTest_2.scala index 6bcfa59463c7..ce9aa435feb2 100644 --- a/tests/pos-macros/i7853/SummonJsonEncoderTest_2.scala +++ b/tests/pos-macros/i7853/SummonJsonEncoderTest_2.scala @@ -1,6 +1,6 @@ import scala.deriving._ import scala.quoted._ -import scala.quoted.matching._ + import scala.compiletime.{erasedValue, summonFrom} import JsonEncoder.{given _, _} @@ -11,7 +11,7 @@ object SummonJsonEncoderTest { def encodeAndMessAroundTypeImpl[T: Type](value: Expr[T])(using qctx: QuoteContext): Expr[String] = { import qctx.tasty._ - val mirrorExpr = summonExpr[Mirror.Of[T]] match { + val mirrorExpr = Expr.summon[Mirror.Of[T]] match { case Some(mirror) => mirror } diff --git a/tests/pos-macros/i8325/Macro_1.scala b/tests/pos-macros/i8325/Macro_1.scala index f2f85c8746e0..61a939fce11a 100644 --- a/tests/pos-macros/i8325/Macro_1.scala +++ b/tests/pos-macros/i8325/Macro_1.scala @@ -1,7 +1,7 @@ package a import scala.quoted._ -import scala.quoted.matching._ + object A: diff --git a/tests/pos-macros/i8325b/Macro_1.scala b/tests/pos-macros/i8325b/Macro_1.scala index a2f5a101b09a..d66329c531f1 100644 --- a/tests/pos-macros/i8325b/Macro_1.scala +++ b/tests/pos-macros/i8325b/Macro_1.scala @@ -1,7 +1,7 @@ package a import scala.quoted._ -import scala.quoted.matching._ + object A: diff --git a/tests/pos/i6435.scala b/tests/pos/i6435.scala index 25246b260f1b..0a85906acd5d 100644 --- a/tests/pos/i6435.scala +++ b/tests/pos/i6435.scala @@ -1,6 +1,6 @@ class Foo { import scala.quoted._ - import scala.quoted.matching._ + def f(sc: quoted.Expr[StringContext])(using QuoteContext): Unit = { val '{ StringContext(${parts}: _*) } = sc diff --git a/tests/pos/i8052.scala b/tests/pos/i8052.scala index f6ac68657c47..6bae471bdfd8 100644 --- a/tests/pos/i8052.scala +++ b/tests/pos/i8052.scala @@ -1,6 +1,6 @@ import scala.deriving._ import scala.quoted._ -import scala.quoted.matching._ + object Macro2 { trait TC[T] { diff --git a/tests/run-macros/BigFloat/BigFloat_1.scala b/tests/run-macros/BigFloat/BigFloat_1.scala index 480e9a78e145..aae96aa5e3f9 100644 --- a/tests/run-macros/BigFloat/BigFloat_1.scala +++ b/tests/run-macros/BigFloat/BigFloat_1.scala @@ -1,7 +1,7 @@ package test import scala.util.FromDigits import scala.quoted._ -import scala.quoted.matching._ + case class BigFloat(mantissa: BigInt, exponent: Int) { override def toString = s"${mantissa}e${exponent}" diff --git a/tests/run-macros/expr-map-1/Macro_1.scala b/tests/run-macros/expr-map-1/Macro_1.scala index 303e4b2d60c0..3f5ab3b2d1d4 100644 --- a/tests/run-macros/expr-map-1/Macro_1.scala +++ b/tests/run-macros/expr-map-1/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def rewrite[T](inline x: Any): Any = ${ stringRewriter('x) } diff --git a/tests/run-macros/expr-map-2/Macro_1.scala b/tests/run-macros/expr-map-2/Macro_1.scala index bcca9acc50a8..86e5c713d5fe 100644 --- a/tests/run-macros/expr-map-2/Macro_1.scala +++ b/tests/run-macros/expr-map-2/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def rewrite[T](inline x: Any): Any = ${ stringRewriter('x) } diff --git a/tests/run-macros/f-interpolator-neg/Macros_1.scala b/tests/run-macros/f-interpolator-neg/Macros_1.scala index 5fb3ab3421bd..eec44da8a82e 100644 --- a/tests/run-macros/f-interpolator-neg/Macros_1.scala +++ b/tests/run-macros/f-interpolator-neg/Macros_1.scala @@ -1,6 +1,6 @@ import scala.quoted._ import scala.quoted.autolift.{given _} -import scala.quoted.matching._ + import scala.language.implicitConversions diff --git a/tests/run-macros/flops-rewrite-2/Macro_1.scala b/tests/run-macros/flops-rewrite-2/Macro_1.scala index d5cb4c2f6207..2e398cdfb83c 100644 --- a/tests/run-macros/flops-rewrite-2/Macro_1.scala +++ b/tests/run-macros/flops-rewrite-2/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def rewrite[T](inline x: T): T = ${ rewriteMacro('x) } diff --git a/tests/run-macros/flops-rewrite-3/Macro_1.scala b/tests/run-macros/flops-rewrite-3/Macro_1.scala index 004fcf44c9f4..dd6f196ec266 100644 --- a/tests/run-macros/flops-rewrite-3/Macro_1.scala +++ b/tests/run-macros/flops-rewrite-3/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def rewrite[T](inline x: T): T = ${ rewriteMacro('x) } diff --git a/tests/run-macros/i6253-b/quoted_1.scala b/tests/run-macros/i6253-b/quoted_1.scala index 0fca81cf70b8..cadc8730d46c 100644 --- a/tests/run-macros/i6253-b/quoted_1.scala +++ b/tests/run-macros/i6253-b/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + object Macros { diff --git a/tests/run-macros/i6253/quoted_1.scala b/tests/run-macros/i6253/quoted_1.scala index 8abc259ff86c..4c7530698588 100644 --- a/tests/run-macros/i6253/quoted_1.scala +++ b/tests/run-macros/i6253/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + object Macros { diff --git a/tests/run-macros/i7987/Macros_1.scala b/tests/run-macros/i7987/Macros_1.scala index 50962e6bfc48..955f1807d7ca 100644 --- a/tests/run-macros/i7987/Macros_1.scala +++ b/tests/run-macros/i7987/Macros_1.scala @@ -1,12 +1,12 @@ import scala.quoted._ import scala.deriving._ -import scala.quoted.matching._ + object Macros { inline def m(): String = ${ macroImpl() } def macroImpl[T]()(using qctx: QuoteContext): Expr[String] = { - summonExpr[Mirror.Of[Some[Int]]] match + Expr.summon[Mirror.Of[Some[Int]]] match case Some('{ $_ : $t }) => Expr(t.show) } } diff --git a/tests/run-macros/i8007/Macro_1.scala b/tests/run-macros/i8007/Macro_1.scala index 35c125888ba9..53cf0bed25b4 100644 --- a/tests/run-macros/i8007/Macro_1.scala +++ b/tests/run-macros/i8007/Macro_1.scala @@ -1,6 +1,6 @@ import scala.deriving._ import scala.quoted._ -import scala.quoted.matching._ + object Macro1 { @@ -21,7 +21,7 @@ object Macro1 { val mirrorTpe = '[Mirror.Of[T]] - summonExpr(using mirrorTpe).get match { + Expr.summon(using mirrorTpe).get match { case '{ $m: Mirror.ProductOf[T]{ type MirroredElemLabels = $t } } => { Expr(mirrorFields(t)) } diff --git a/tests/run-macros/i8007/Macro_2.scala b/tests/run-macros/i8007/Macro_2.scala index 1eb45b4b3c6a..586c0f86312a 100644 --- a/tests/run-macros/i8007/Macro_2.scala +++ b/tests/run-macros/i8007/Macro_2.scala @@ -1,6 +1,6 @@ import scala.deriving._ import scala.quoted._ -import scala.quoted.matching._ + object Macro2 { @@ -46,7 +46,7 @@ object Macro2 { import qctx.tasty._ val mirrorTpe = '[Mirror.Of[T]] - val mirrorExpr = summonExpr(using mirrorTpe).get + val mirrorExpr = Expr.summon(using mirrorTpe).get val derivedInstance = JsonEncoder.derived(mirrorExpr) '{ diff --git a/tests/run-macros/i8007/Macro_3.scala b/tests/run-macros/i8007/Macro_3.scala index 2e3c7aa305d9..da4353f3073a 100644 --- a/tests/run-macros/i8007/Macro_3.scala +++ b/tests/run-macros/i8007/Macro_3.scala @@ -1,6 +1,6 @@ import scala.deriving._ import scala.quoted._ -import scala.quoted.matching._ + trait Eq[T] { def eqv(x: T, y: T): Boolean @@ -35,7 +35,7 @@ object Eq { given derived[T: Type](using qctx: QuoteContext) as Expr[Eq[T]] = { import qctx.tasty._ - val ev: Expr[Mirror.Of[T]] = summonExpr(using '[Mirror.Of[T]]).get + val ev: Expr[Mirror.Of[T]] = Expr.summon(using '[Mirror.Of[T]]).get ev match { case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = $elementTypes }} => diff --git a/tests/run-macros/inline-macro-staged-interpreter/Macro_1.scala b/tests/run-macros/inline-macro-staged-interpreter/Macro_1.scala index cd03d18aceaa..71cd838ee040 100644 --- a/tests/run-macros/inline-macro-staged-interpreter/Macro_1.scala +++ b/tests/run-macros/inline-macro-staged-interpreter/Macro_1.scala @@ -1,6 +1,6 @@ import scala.quoted._ -import scala.quoted.matching._ + object E { diff --git a/tests/run-macros/lambda-extractor-1/Macro_1.scala b/tests/run-macros/lambda-extractor-1/Macro_1.scala index c191a84c3792..0f720ec28db1 100644 --- a/tests/run-macros/lambda-extractor-1/Macro_1.scala +++ b/tests/run-macros/lambda-extractor-1/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def test(inline f: Int => Int): String = ${ impl('f) } diff --git a/tests/run-macros/lambda-extractor-2/Macro_1.scala b/tests/run-macros/lambda-extractor-2/Macro_1.scala index 0798e9b33990..dc789c45fa6d 100644 --- a/tests/run-macros/lambda-extractor-2/Macro_1.scala +++ b/tests/run-macros/lambda-extractor-2/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def test(inline f: (Int, Int) => Int): String = ${ impl('f) } diff --git a/tests/run-macros/quote-implicitMatch/Macro_1.scala b/tests/run-macros/quote-implicitMatch/Macro_1.scala index 08f317805b5f..bf4f779b5a69 100644 --- a/tests/run-macros/quote-implicitMatch/Macro_1.scala +++ b/tests/run-macros/quote-implicitMatch/Macro_1.scala @@ -1,12 +1,12 @@ import collection.immutable.TreeSet import collection.immutable.HashSet import scala.quoted._ -import scala.quoted.matching._ + inline def f1[T]() = ${ f1Impl[T] } def f1Impl[T: Type](using QuoteContext) = { - summonExpr[Ordering[T]] match { + Expr.summon[Ordering[T]] match { case Some(ord) => '{ new TreeSet[T]()($ord) } case _ => '{ new HashSet[T] } } @@ -18,7 +18,7 @@ class B inline def g = ${ gImpl } def gImpl(using QuoteContext) = { - if (summonExpr[A].isDefined) '{ println("A") } - else if (summonExpr[B].isDefined) '{ println("B") } + if (Expr.summon[A].isDefined) '{ println("A") } + else if (Expr.summon[B].isDefined) '{ println("B") } else throw new MatchError("") } diff --git a/tests/run-macros/quote-matcher-power/Macro_1.scala b/tests/run-macros/quote-matcher-power/Macro_1.scala index d44e957b70b3..c3cef46d9497 100644 --- a/tests/run-macros/quote-matcher-power/Macro_1.scala +++ b/tests/run-macros/quote-matcher-power/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + object Macros { diff --git a/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala index fea93a1fce7e..80e8df81ba44 100644 --- a/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + object Macros { diff --git a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala index 121d2cb8fbf1..b2d899fbc099 100644 --- a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + object Macros { diff --git a/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala index 128d551a34b6..3874602bb939 100644 --- a/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + object Macros { diff --git a/tests/run-macros/quote-matcher-symantics-1/quoted_1.scala b/tests/run-macros/quote-matcher-symantics-1/quoted_1.scala index 548d4f36c3c3..edf9809afcd3 100644 --- a/tests/run-macros/quote-matcher-symantics-1/quoted_1.scala +++ b/tests/run-macros/quote-matcher-symantics-1/quoted_1.scala @@ -1,6 +1,6 @@ import scala.quoted._ -import scala.quoted.matching._ + object Macros { diff --git a/tests/run-macros/quote-matcher-symantics-2/quoted_1.scala b/tests/run-macros/quote-matcher-symantics-2/quoted_1.scala index 6bc1a3f66829..b58deac142a9 100644 --- a/tests/run-macros/quote-matcher-symantics-2/quoted_1.scala +++ b/tests/run-macros/quote-matcher-symantics-2/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + import scala.quoted.unsafe._ object Macros { diff --git a/tests/run-macros/quote-matcher-symantics-3/quoted_1.scala b/tests/run-macros/quote-matcher-symantics-3/quoted_1.scala index 94615a355612..acc7d5829d61 100644 --- a/tests/run-macros/quote-matcher-symantics-3/quoted_1.scala +++ b/tests/run-macros/quote-matcher-symantics-3/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + import scala.quoted.unsafe._ object Macros { diff --git a/tests/run-macros/quote-matcher-type-bind/Macro_1.scala b/tests/run-macros/quote-matcher-type-bind/Macro_1.scala index 63f7e06adeb7..d30b4b16d997 100644 --- a/tests/run-macros/quote-matcher-type-bind/Macro_1.scala +++ b/tests/run-macros/quote-matcher-type-bind/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + object Macros { diff --git a/tests/run-macros/quoted-matching-docs-2/Macro_1.scala b/tests/run-macros/quoted-matching-docs-2/Macro_1.scala index d9f01311b070..cc0d29980413 100644 --- a/tests/run-macros/quoted-matching-docs-2/Macro_1.scala +++ b/tests/run-macros/quoted-matching-docs-2/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + def sum(args: Int*): Int = args.sum diff --git a/tests/run-macros/quoted-matching-docs/Macro_1.scala b/tests/run-macros/quoted-matching-docs/Macro_1.scala index 627ed02e996f..fc5adacdd9aa 100644 --- a/tests/run-macros/quoted-matching-docs/Macro_1.scala +++ b/tests/run-macros/quoted-matching-docs/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + import scala.quoted.unsafe._ inline def sum(args: Int*): Int = ${ sumExpr('args) } diff --git a/tests/run-macros/string-context-implicits/Macro_1.scala b/tests/run-macros/string-context-implicits/Macro_1.scala index 24870d35c0b3..ac9208e46460 100644 --- a/tests/run-macros/string-context-implicits/Macro_1.scala +++ b/tests/run-macros/string-context-implicits/Macro_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ -import scala.quoted.matching._ + inline def (sc: StringContext) showMe(inline args: Any*): String = ${ showMeExpr('sc, 'args) } @@ -9,7 +9,7 @@ private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using val argShowedExprs = argExprs.map { case '{ $arg: $tp } => val showTp = '[Show[$tp]] - summonExpr(using showTp) match { + Expr.summon(using showTp) match { case Some(showExpr) => '{ $showExpr.show($arg) } case None => qctx.error(s"could not find implicit for ${showTp.show}", arg); '{???} } diff --git a/tests/run-macros/tasty-extractors-constants-1/quoted_1.scala b/tests/run-macros/tasty-extractors-constants-1/quoted_1.scala index b012786ba319..f7ebec45890c 100644 --- a/tests/run-macros/tasty-extractors-constants-1/quoted_1.scala +++ b/tests/run-macros/tasty-extractors-constants-1/quoted_1.scala @@ -1,7 +1,7 @@ import scala.quoted._ import scala.quoted.autolift.{given _} -import scala.quoted.matching._ + object Macros { diff --git a/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala b/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala index 8cfe9911c128..ebb394bd92f1 100644 --- a/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala +++ b/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala @@ -1,6 +1,6 @@ import scala.quoted._ import scala.quoted.autolift.{given _} -import scala.quoted.matching._ + import scala.language.implicitConversions From 44f6bd37c0dbc8a55bf283cff77456f327fb7103 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Mar 2020 10:57:27 +0100 Subject: [PATCH 2/9] Update docs --- docs/docs/reference/metaprogramming/macros.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index f34a8a8fc095..bafaa5af79ed 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -565,13 +565,13 @@ sum ### Find implicits within a macro Similarly to the `summonFrom` construct, it is possible to make implicit search available -in a quote context. For this we simply provide `scala.quoted.matching.summonExpr`: +in a quote context. For this we simply provide `scala.quoted.Expr.summon`: ```scala inline def setFor[T]: Set[T] = ${ setForExpr[T] } def setForExpr[T: Type](using QuoteContext): Expr[Set[T]] = { - summonExpr[Ordering[T]] match { + Expr.summon[Ordering[T]] match { case Some(ord) => '{ new TreeSet[T]()($ord) } case _ => '{ new HashSet[T] } } @@ -614,15 +614,13 @@ In case all files are suspended due to cyclic dependencies the compilation will It is possible to deconstruct or extract values out of `Expr` using pattern matching. -#### scala.quoted.matching +`scala.quoted` contains objects that can help extracting values from `Expr`. -`scala.quoted.matching` contains objects that can help extracting values from `Expr`. - -* `scala.quoted.matching.Const`: matches an expression of a literal value and returns the value. -* `scala.quoted.matching.Value`: matches an expression of a value and returns the value. -* `scala.quoted.matching.ExprSeq`: matches an explicit sequence of expresions and returns them. These sequences are useful to get individual `Expr[T]` out of a varargs expression of type `Expr[Seq[T]]`. -* `scala.quoted.matching.ConstSeq`: matches an explicit sequence of literal values and returns them. -* `scala.quoted.matching.ValueSeq`: matches an explicit sequence of values and returns them. +* `scala.quoted.Const`: matches an expression of a literal value and returns the value. +* `scala.quoted.Value`: matches an expression of a value and returns the value. +* `scala.quoted.ExprSeq`: matches an explicit sequence of expresions and returns them. These sequences are useful to get individual `Expr[T]` out of a varargs expression of type `Expr[Seq[T]]`. +* `scala.quoted.ConstSeq`: matches an explicit sequence of literal values and returns them. +* `scala.quoted.ValueSeq`: matches an explicit sequence of values and returns them. These could be used in the following way to optimize any call to `sum` that has statically known values. ```scala From 761405d73555d85704b111334b55d694477d7312 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Mar 2020 11:06:28 +0100 Subject: [PATCH 3/9] Join literal sequence Expr logic into Exprs Currently we have `Expr.ofSeq` and `ExprSeq.unapply` to handle such cases. Instead we provide a single `Exprs` that contains an `apply` and `unapply`. Furthermore having both `Expr.ofSeq` and `Expr.ofList` has lead to confusions on which one to use for varargs. This will help guide users to the correct logic to use for varargs. --- docs/docs/reference/metaprogramming/macros.md | 10 ++++----- .../dotty/internal/StringContextMacro.scala | 4 ++-- library/src/scala/quoted/ConstSeq.scala | 2 +- library/src/scala/quoted/Expr.scala | 14 +++---------- .../quoted/{ExprSeq.scala => Exprs.scala} | 21 +++++++++++++++++-- library/src/scala/quoted/ValueSeq.scala | 2 +- .../src/scala/quoted/matching/package.scala | 4 ++-- tests/neg-macros/i6432/Macro_1.scala | 2 +- tests/neg-macros/i6432b/Macro_1.scala | 2 +- tests/neg/i6436.check | 2 +- tests/neg/i6436.scala | 2 +- tests/pos/i6435.scala | 2 +- .../f-interpolator-neg/Macros_1.scala | 4 ++-- .../quoted_1.scala | 2 +- .../quoted_1.scala | 2 +- .../quoted-matching-docs-2/Macro_1.scala | 4 ++-- .../quoted-matching-docs/Macro_1.scala | 2 +- .../string-context-implicits/Macro_1.scala | 2 +- .../Macros_1.scala | 4 ++-- 19 files changed, 48 insertions(+), 39 deletions(-) rename library/src/scala/quoted/{ExprSeq.scala => Exprs.scala} (55%) diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index bafaa5af79ed..8a2399a0cdcd 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -618,7 +618,7 @@ It is possible to deconstruct or extract values out of `Expr` using pattern matc * `scala.quoted.Const`: matches an expression of a literal value and returns the value. * `scala.quoted.Value`: matches an expression of a value and returns the value. -* `scala.quoted.ExprSeq`: matches an explicit sequence of expresions and returns them. These sequences are useful to get individual `Expr[T]` out of a varargs expression of type `Expr[Seq[T]]`. +* `scala.quoted.Exprs`: matches an explicit sequence of expresions and returns them. These sequences are useful to get individual `Expr[T]` out of a varargs expression of type `Expr[Seq[T]]`. * `scala.quoted.ConstSeq`: matches an explicit sequence of literal values and returns them. * `scala.quoted.ValueSeq`: matches an explicit sequence of values and returns them. @@ -628,7 +628,7 @@ inline def sum(inline args: Int*): Int = ${ sumExpr('args) } private def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match { case ConstSeq(args) => // args is of type Seq[Int] Expr(args.sum) // precompute result of sum - case ExprSeq(argExprs) => // argExprs is of type Seq[Expr[Int]] + case Exprs(argExprs) => // argExprs is of type Seq[Expr[Int]] val staticSum: Int = argExprs.map { case Const(arg) => arg case _ => 0 @@ -664,12 +664,12 @@ private def optimizeExpr(body: Expr[Int])(using QuoteContext): Expr[Int] = body // Match a call to sum with an argument $n of type Int. n will be the Expr[Int] representing the argument. case '{ sum($n) } => n // Match a call to sum and extracts all its args in an `Expr[Seq[Int]]` - case '{ sum(${ExprSeq(args)}: _*) } => sumExpr(args) + case '{ sum(${Exprs(args)}: _*) } => sumExpr(args) case body => body } private def sumExpr(args1: Seq[Expr[Int]])(using QuoteContext): Expr[Int] = { def flatSumArgs(arg: Expr[Int]): Seq[Expr[Int]] = arg match { - case '{ sum(${ExprSeq(subArgs)}: _*) } => subArgs.flatMap(flatSumArgs) + case '{ sum(${Exprs(subArgs)}: _*) } => subArgs.flatMap(flatSumArgs) case arg => Seq(arg) } val args2 = args1.flatMap(flatSumArgs) @@ -707,7 +707,7 @@ inline def (sc: StringContext).showMe(inline args: Any*): String = ${ showMeExpr private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[String] = { argsExpr match { - case ExprSeq(argExprs) => + case Exprs(argExprs) => val argShowedExprs = argExprs.map { case '{ $arg: $tp } => val showTp = '[Show[$tp]] diff --git a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala index 275f894a0099..7dd35ec3302e 100644 --- a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala +++ b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala @@ -64,7 +64,7 @@ object StringContextMacro { def notStatic = qctx.throwError("Expected statically known String Context", strCtxExpr) def splitParts(seq: Expr[Seq[String]]) = (seq, seq) match { - case (ExprSeq(p1), ConstSeq(p2)) => (p1.toList, p2.toList) + case (Exprs(p1), ConstSeq(p2)) => (p1.toList, p2.toList) case (_, _) => notStatic } val (partsExpr, parts) = strCtxExpr match { @@ -74,7 +74,7 @@ object StringContextMacro { } val args = argsExpr match { - case ExprSeq(args) => args + case Exprs(args) => args case _ => qctx.throwError("Expected statically known argument list", argsExpr) } diff --git a/library/src/scala/quoted/ConstSeq.scala b/library/src/scala/quoted/ConstSeq.scala index e30d66867c7a..fb4bb85a5c04 100644 --- a/library/src/scala/quoted/ConstSeq.scala +++ b/library/src/scala/quoted/ConstSeq.scala @@ -16,7 +16,7 @@ object ConstSeq { * ``` */ def unapply[T](expr: Expr[Seq[T]])(using qctx: QuoteContext): Option[Seq[T]] = expr match { - case ExprSeq(elems) => + case Exprs(elems) => elems.foldRight(Option(List.empty[T])) { (elem, acc) => (elem, acc) match { case (Const(value), Some(lst)) => Some(value :: lst) diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index 220ba23b1dbc..8e1882e6f34a 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -108,17 +108,9 @@ object Expr { * `Seq(e1, e2, ...)` where `ei: Expr[T]` * to an expression equivalent to * `'{ Seq($e1, $e2, ...) }` typed as an `Expr[Seq[T]]` - * - * Usage: - * ```scala - * '{ List(${Expr.ofSeq(List(1, 2, 3))}: _*) } // equvalent to '{ List(1, 2, 3) } * ``` */ - def ofSeq[T](xs: Seq[Expr[T]])(using tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = { - import qctx.tasty.{_, given _} - Repeated(xs.map[Term](_.unseal).toList, tp.unseal).seal.asInstanceOf[Expr[Seq[T]]] - } - + def ofSeq[T](xs: Seq[Expr[T]])(using tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = Exprs(xs) /** Lifts this list of expressions into an expression of a list * @@ -128,7 +120,7 @@ object Expr { * `'{ List($e1, $e2, ...) }` typed as an `Expr[List[T]]` */ def ofList[T](xs: Seq[Expr[T]])(using Type[T], QuoteContext): Expr[List[T]] = - if (xs.isEmpty) '{ Nil } else '{ List(${ofSeq(xs)}: _*) } + if (xs.isEmpty) '{ Nil } else '{ List(${Exprs(xs)}: _*) } /** Lifts this sequence of expressions into an expression of a tuple * @@ -186,7 +178,7 @@ object Expr { case Seq('{ $x1: $t1 }, '{ $x2: $t2 }, '{ $x3: $t3 }, '{ $x4: $t4 }, '{ $x5: $t5 }, '{ $x6: $t6 }, '{ $x7: $t7 }, '{ $x8: $t8 }, '{ $x9: $t9 }, '{ $x10: $t10 }, '{ $x11: $t11 }, '{ $x12: $t12 }, '{ $x13: $t13 }, '{ $x14: $t14 }, '{ $x15: $t15 }, '{ $x16: $t16 }, '{ $x17: $t17 }, '{ $x18: $t18 }, '{ $x19: $t19 }, '{ $x20: $t20 }, '{ $x21: $t21 }, '{ $x22: $t22 }) => '{ Tuple22($x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x18, $x19, $x20, $x21, $x22) } case _ => - '{ Tuple.fromIArray(IArray(${ofSeq(seq)}: _*)) } + '{ Tuple.fromIArray(IArray(${Exprs(seq)}: _*)) } } } diff --git a/library/src/scala/quoted/ExprSeq.scala b/library/src/scala/quoted/Exprs.scala similarity index 55% rename from library/src/scala/quoted/ExprSeq.scala rename to library/src/scala/quoted/Exprs.scala index 689a5921ed05..5913e2e59e69 100644 --- a/library/src/scala/quoted/ExprSeq.scala +++ b/library/src/scala/quoted/Exprs.scala @@ -1,7 +1,24 @@ package scala.quoted /** Literal sequence of expressions */ -object ExprSeq { +object Exprs { + + /** Lifts this sequence of expressions into an expression of a sequence + * + * 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]]` + * + * Usage: + * ```scala + * '{ List(${Exprs(List(1, 2, 3))}: _*) } // equvalent to '{ List(1, 2, 3) } + * ``` + */ + def apply[T](xs: Seq[Expr[T]])(using tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = { + import qctx.tasty.{_, given _} + Repeated(xs.map[Term](_.unseal).toList, tp.unseal).seal.asInstanceOf[Expr[Seq[T]]] + } /** Matches a literal sequence of expressions and return a sequence of expressions. * @@ -9,7 +26,7 @@ object ExprSeq { * ```scala * inline def sum(args: Int*): Int = ${ sumExpr('args) } * def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match - * case ExprSeq(argExprs) => + * case Exprs(argExprs) => * // argExprs: Seq[Expr[Int]] * ... * } diff --git a/library/src/scala/quoted/ValueSeq.scala b/library/src/scala/quoted/ValueSeq.scala index 035fff7968a6..ee96da3b0a0e 100644 --- a/library/src/scala/quoted/ValueSeq.scala +++ b/library/src/scala/quoted/ValueSeq.scala @@ -16,7 +16,7 @@ object ValueSeq { * ``` */ def unapply[T](expr: Expr[Seq[T]])(using valueOf: ValueOfExpr[T], qctx: QuoteContext): Option[Seq[T]] = expr match { - case ExprSeq(elems) => + case Exprs(elems) => elems.foldRight(Option(List.empty[T])) { (elem, acc) => (elem, acc) match { case (Value(value), Some(lst)) => Some(value :: lst) diff --git a/library/src/scala/quoted/matching/package.scala b/library/src/scala/quoted/matching/package.scala index 3ec880c773d5..42a5426412ad 100644 --- a/library/src/scala/quoted/matching/package.scala +++ b/library/src/scala/quoted/matching/package.scala @@ -20,8 +20,8 @@ package object matching { @deprecated("use scala.quoted.ConstSeq instead", "0.23.0") val ConstSeq: quoted.ConstSeq.type = quoted.ConstSeq - @deprecated("use scala.quoted.ExprSeq instead", "0.23.0") - val ExprSeq: quoted.ExprSeq.type = quoted.ExprSeq + @deprecated("use scala.quoted.Exprs instead", "0.23.0") + val ExprSeq: quoted.Exprs.type = quoted.Exprs @deprecated("use scala.quoted.Lambda instead", "0.23.0") val Lambda: quoted.Lambda.type = quoted.Lambda diff --git a/tests/neg-macros/i6432/Macro_1.scala b/tests/neg-macros/i6432/Macro_1.scala index f8e2a34322bc..325bef4e2a74 100644 --- a/tests/neg-macros/i6432/Macro_1.scala +++ b/tests/neg-macros/i6432/Macro_1.scala @@ -9,7 +9,7 @@ object Macro { def impl(sc: Expr[StringContext])(using qctx: QuoteContext) : Expr[Unit] = { import qctx.tasty._ sc match { - case '{ StringContext(${ExprSeq(parts)}: _*) } => + case '{ StringContext(${Exprs(parts)}: _*) } => for (part @ Const(s) <- parts) error(s, part.unseal.pos) } diff --git a/tests/neg-macros/i6432b/Macro_1.scala b/tests/neg-macros/i6432b/Macro_1.scala index f8e2a34322bc..325bef4e2a74 100644 --- a/tests/neg-macros/i6432b/Macro_1.scala +++ b/tests/neg-macros/i6432b/Macro_1.scala @@ -9,7 +9,7 @@ object Macro { def impl(sc: Expr[StringContext])(using qctx: QuoteContext) : Expr[Unit] = { import qctx.tasty._ sc match { - case '{ StringContext(${ExprSeq(parts)}: _*) } => + case '{ StringContext(${Exprs(parts)}: _*) } => for (part @ Const(s) <- parts) error(s, part.unseal.pos) } diff --git a/tests/neg/i6436.check b/tests/neg/i6436.check index 234abadcff52..3287068d6e55 100644 --- a/tests/neg/i6436.check +++ b/tests/neg/i6436.check @@ -1,5 +1,5 @@ -- Error: tests/neg/i6436.scala:5:9 ------------------------------------------------------------------------------------ -5 | case '{ StringContext(${ExprSeq(parts)}: _*) } => // error +5 | case '{ StringContext(${Exprs(parts)}: _*) } => // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | no implicit argument of type scala.quoted.QuoteContext was found -- [E006] Unbound Identifier Error: tests/neg/i6436.scala:6:34 --------------------------------------------------------- diff --git a/tests/neg/i6436.scala b/tests/neg/i6436.scala index 91071f3fb825..8f26a500064c 100644 --- a/tests/neg/i6436.scala +++ b/tests/neg/i6436.scala @@ -2,7 +2,7 @@ import scala.quoted._ def f(sc: quoted.Expr[StringContext]): Unit = { sc match { - case '{ StringContext(${ExprSeq(parts)}: _*) } => // error + case '{ StringContext(${Exprs(parts)}: _*) } => // error val ps: Seq[Expr[String]] = parts // error } } \ No newline at end of file diff --git a/tests/pos/i6435.scala b/tests/pos/i6435.scala index 0a85906acd5d..6fca63679a63 100644 --- a/tests/pos/i6435.scala +++ b/tests/pos/i6435.scala @@ -6,7 +6,7 @@ class Foo { val '{ StringContext(${parts}: _*) } = sc val ps0: Expr[Seq[String]] = parts - val '{ StringContext(${ExprSeq(parts2)}: _*) } = sc + val '{ StringContext(${Exprs(parts2)}: _*) } = sc val ps: Seq[Expr[String]] = parts2 } } \ No newline at end of file diff --git a/tests/run-macros/f-interpolator-neg/Macros_1.scala b/tests/run-macros/f-interpolator-neg/Macros_1.scala index eec44da8a82e..8fed3164ef26 100644 --- a/tests/run-macros/f-interpolator-neg/Macros_1.scala +++ b/tests/run-macros/f-interpolator-neg/Macros_1.scala @@ -14,9 +14,9 @@ object Macro { def fooErrors(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using QuoteContext): Expr[List[(Boolean, Int, Int, Int, String)]] = { (strCtxExpr, argsExpr) match { - case ('{ StringContext(${ExprSeq(parts)}: _*) }, ExprSeq(args)) => + case ('{ StringContext(${Exprs(parts)}: _*) }, Exprs(args)) => fooErrorsImpl(parts, args, argsExpr) - case ('{ new StringContext(${ExprSeq(parts)}: _*) }, ExprSeq(args)) => + case ('{ new StringContext(${Exprs(parts)}: _*) }, Exprs(args)) => fooErrorsImpl(parts, args, argsExpr) } } diff --git a/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala index 80e8df81ba44..fc143cff8fe0 100644 --- a/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala @@ -8,7 +8,7 @@ object Macros { private def impl(self: Expr[StringContext], args: Expr[Seq[String]])(using QuoteContext): Expr[String] = { (self, args) match { - case ('{ StringContext(${ExprSeq(parts)}: _*) }, ExprSeq(args1)) => + case ('{ StringContext(${Exprs(parts)}: _*) }, Exprs(args1)) => val strParts = parts.map { case Const(str) => str.reverse } val strArgs = args1.map { case Const(str) => str } Expr(StringContext(strParts: _*).s(strArgs: _*)) diff --git a/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala index 3874602bb939..ef9a62f5db28 100644 --- a/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala @@ -8,7 +8,7 @@ object Macros { private def impl(self: Expr[StringContext], args: Expr[Seq[String]])(using QuoteContext): Expr[String] = { self match { - case '{ StringContext(${ExprSeq(parts)}: _*) } => + case '{ StringContext(${Exprs(parts)}: _*) } => val parts2 = Expr.ofList(parts.map(x => '{ $x.reverse })) '{ StringContext($parts2: _*).s($args: _*) } case _ => diff --git a/tests/run-macros/quoted-matching-docs-2/Macro_1.scala b/tests/run-macros/quoted-matching-docs-2/Macro_1.scala index cc0d29980413..ba067f8cb4e3 100644 --- a/tests/run-macros/quoted-matching-docs-2/Macro_1.scala +++ b/tests/run-macros/quoted-matching-docs-2/Macro_1.scala @@ -15,13 +15,13 @@ private def optimizeExpr(body: Expr[Int])(using QuoteContext): Expr[Int] = body // Match a call to sum with an argument $n of type Int. n will be the Expr[Int] representing the argument. case '{ sum($n) } => n // Match a call to sum and extracts all its args in an `Expr[Seq[Int]]` - case '{ sum(${ExprSeq(args)}: _*) } => sumExpr(args) + case '{ sum(${Exprs(args)}: _*) } => sumExpr(args) case body => body } private def sumExpr(args1: Seq[Expr[Int]])(using QuoteContext): Expr[Int] = { def flatSumArgs(arg: Expr[Int]): Seq[Expr[Int]] = arg match { - case '{ sum(${ExprSeq(subArgs)}: _*) } => subArgs.flatMap(flatSumArgs) + case '{ sum(${Exprs(subArgs)}: _*) } => subArgs.flatMap(flatSumArgs) case arg => Seq(arg) } val args2 = args1.flatMap(flatSumArgs) diff --git a/tests/run-macros/quoted-matching-docs/Macro_1.scala b/tests/run-macros/quoted-matching-docs/Macro_1.scala index fc5adacdd9aa..938b2d579580 100644 --- a/tests/run-macros/quoted-matching-docs/Macro_1.scala +++ b/tests/run-macros/quoted-matching-docs/Macro_1.scala @@ -14,7 +14,7 @@ private def sumExpr(argsExpr: Expr[Seq[Int]])(using qctx: QuoteContext) : Expr[I UnsafeExpr.underlyingArgument(argsExpr) match { case ConstSeq(args) => // args is of type Seq[Int] Expr(args.sum) // precompute result of sum - case ExprSeq(argExprs) => // argExprs is of type Seq[Expr[Int]] + case Exprs(argExprs) => // argExprs is of type Seq[Expr[Int]] val staticSum: Int = argExprs.map { case Const(arg) => arg case _ => 0 diff --git a/tests/run-macros/string-context-implicits/Macro_1.scala b/tests/run-macros/string-context-implicits/Macro_1.scala index ac9208e46460..8838885d25c7 100644 --- a/tests/run-macros/string-context-implicits/Macro_1.scala +++ b/tests/run-macros/string-context-implicits/Macro_1.scala @@ -5,7 +5,7 @@ inline def (sc: StringContext) showMe(inline args: Any*): String = ${ showMeExpr private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[String] = { argsExpr match { - case ExprSeq(argExprs) => + case Exprs(argExprs) => val argShowedExprs = argExprs.map { case '{ $arg: $tp } => val showTp = '[Show[$tp]] diff --git a/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala b/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala index ebb394bd92f1..69316e87701a 100644 --- a/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala +++ b/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala @@ -21,7 +21,7 @@ object Macro { def foo(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[String] = { (sc, argsExpr) match { - case ('{ StringContext(${ExprSeq(parts)}: _*) }, ExprSeq(args)) => + case ('{ StringContext(${Exprs(parts)}: _*) }, Exprs(args)) => val reporter = new Reporter { def errorOnPart(msg: String, partIdx: Int): Unit = { import qctx.tasty._ @@ -34,7 +34,7 @@ object Macro { def fooErrors(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[List[(Int, Int, Int, String)]] = { (sc, argsExpr) match { - case ('{ StringContext(${ExprSeq(parts)}: _*) }, ExprSeq(args)) => + case ('{ StringContext(${Exprs(parts)}: _*) }, Exprs(args)) => val errors = List.newBuilder[Expr[(Int, Int, Int, String)]] val reporter = new Reporter { def errorOnPart(msg: String, partIdx: Int): Unit = { From 154069d00e33fdbd915f46e3a3679fc24840852e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Mar 2020 11:37:28 +0100 Subject: [PATCH 4/9] Add `Const.unapply(Seq)` and `Value.unapply(Seq)` Instead of having a special concept to extract values out of sequences, with this change, we can take advantage of composition with `Exprs`. The old `ConstSeq` and `ValueSeq` are deprecated to reduce the sumber of concepts in the API. --- docs/docs/reference/metaprogramming/macros.md | 8 ++-- .../dotty/internal/StringContextMacro.scala | 9 ++-- library/src/scala/quoted/Const.scala | 43 ++++++++++++++----- library/src/scala/quoted/Value.scala | 19 ++++++++ library/src/scala/quoted/ValueOfExpr.scala | 10 ++--- .../quoted/{ => matching}/ConstSeq.scala | 17 +++----- .../quoted/{ => matching}/ValueSeq.scala | 17 +++----- .../src/scala/quoted/matching/package.scala | 6 --- .../quoted_1.scala | 2 +- .../quoted-matching-docs/Macro_1.scala | 2 +- 10 files changed, 81 insertions(+), 52 deletions(-) rename library/src/scala/quoted/{ => matching}/ConstSeq.scala (66%) rename library/src/scala/quoted/{ => matching}/ValueSeq.scala (63%) diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 8a2399a0cdcd..09f26f8a3e3b 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -616,17 +616,15 @@ It is possible to deconstruct or extract values out of `Expr` using pattern matc `scala.quoted` contains objects that can help extracting values from `Expr`. -* `scala.quoted.Const`: matches an expression of a literal value and returns the value. -* `scala.quoted.Value`: matches an expression of a value and returns the value. +* `scala.quoted.Const`: matches an expression of a literal value (or list of values) and returns the value (or list of values). +* `scala.quoted.Value`: matches an expression of a value (or list of values) and returns the value (or list of values). * `scala.quoted.Exprs`: matches an explicit sequence of expresions and returns them. These sequences are useful to get individual `Expr[T]` out of a varargs expression of type `Expr[Seq[T]]`. -* `scala.quoted.ConstSeq`: matches an explicit sequence of literal values and returns them. -* `scala.quoted.ValueSeq`: matches an explicit sequence of values and returns them. These could be used in the following way to optimize any call to `sum` that has statically known values. ```scala inline def sum(inline args: Int*): Int = ${ sumExpr('args) } private def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match { - case ConstSeq(args) => // args is of type Seq[Int] + case Exprs(Const(args)) => // args is of type Seq[Int] Expr(args.sum) // precompute result of sum case Exprs(argExprs) => // argExprs is of type Seq[Expr[Int]] val staticSum: Int = argExprs.map { diff --git a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala index 7dd35ec3302e..9ac2210b523e 100644 --- a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala +++ b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala @@ -63,9 +63,12 @@ object StringContextMacro { def notStatic = qctx.throwError("Expected statically known String Context", strCtxExpr) - def splitParts(seq: Expr[Seq[String]]) = (seq, seq) match { - case (Exprs(p1), ConstSeq(p2)) => (p1.toList, p2.toList) - case (_, _) => notStatic + def splitParts(seq: Expr[Seq[String]]) = seq match { + case Exprs(p1) => + p1 match + case Const(p2) => (p1.toList, p2.toList) + case _ => notStatic + case _ => notStatic } val (partsExpr, parts) = strCtxExpr match { case '{ StringContext($parts: _*) } => splitParts(parts) diff --git a/library/src/scala/quoted/Const.scala b/library/src/scala/quoted/Const.scala index ea63147ee55b..cc9349eef8b7 100644 --- a/library/src/scala/quoted/Const.scala +++ b/library/src/scala/quoted/Const.scala @@ -1,18 +1,19 @@ package scala.quoted -/** Matches expressions containing literal constant values and extracts the value. - * It may match expressions of type Boolean, Byte, Short, Int, Long, - * Float, Double, Char, String, ClassTag, scala.Symbol, Null and Unit. - * - * Usage: - * ``` - * (x: Expr[B]) match { - * case Const(value: B) => ... - * } - * ``` - */ +/** MLiteral constant values */ object Const { + /** Matches expressions containing literal constant values and extracts the value. + * It may match expressions of type Boolean, Byte, Short, Int, Long, + * Float, Double, Char, String, ClassTag, scala.Symbol, Null and Unit. + * + * Usage: + * ``` + * (x: Expr[B]) match { + * case Const(value: B) => ... + * } + * ``` + */ def unapply[T](expr: Expr[T])(using qctx: QuoteContext): Option[T] = { import qctx.tasty.{_, given _} def rec(tree: Term): Option[T] = tree match { @@ -25,4 +26,24 @@ object Const { rec(expr.unseal) } + /** Matches literal sequence of literal constant value expressions and return a sequence of values. + * + * Usage: + * ```scala + * inline def sum(args: Int*): Int = ${ sumExpr('args) } + * def sumExpr(argsExpr: Expr[Seq[Int]])(usingusing QuoteContext): Expr[Int] = argsExpr match + * case Exprs(Const(args)) => + * // args: Seq[Int] + * ... + * } + * ``` + */ + def unapply[T](exprs: Seq[Expr[T]])(using qctx: QuoteContext): Option[Seq[T]] = + exprs.foldRight(Option(List.empty[T])) { (elem, acc) => + (elem, acc) match { + case (Const(value), Some(lst)) => Some(value :: lst) + case (_, _) => None + } + } + } diff --git a/library/src/scala/quoted/Value.scala b/library/src/scala/quoted/Value.scala index 5b8ad7e6f3c4..a43c367c2a84 100644 --- a/library/src/scala/quoted/Value.scala +++ b/library/src/scala/quoted/Value.scala @@ -15,4 +15,23 @@ object Value { def unapply[T](expr: Expr[T])(using valueOf: ValueOfExpr[T], qxtc: QuoteContext): Option[T] = valueOf(expr) + /** Matches literal sequence of literal constant value expressions and return a sequence of values. + * + * Usage: + * ```scala + * inline def sum(args: Int*): Int = ${ sumExpr('args) } + * def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match + * case Exprs(Value(args)) => + * // args: Seq[Int] + * ... + * } + * ``` + */ + def unapply[T](exprs: Seq[Expr[T]])(using valueOf: ValueOfExpr[T], qctx: QuoteContext): Option[Seq[T]] = + exprs.foldRight(Option(List.empty[T])) { (elem, acc) => + (elem, acc) match { + case (Value(value), Some(lst)) => Some(value :: lst) + case (_, _) => None + } + } } diff --git a/library/src/scala/quoted/ValueOfExpr.scala b/library/src/scala/quoted/ValueOfExpr.scala index 15fd8495ccce..ef8ec95ef093 100644 --- a/library/src/scala/quoted/ValueOfExpr.scala +++ b/library/src/scala/quoted/ValueOfExpr.scala @@ -42,8 +42,8 @@ object ValueOfExpr { given StringContext_delegate as ValueOfExpr[StringContext] = new { def apply(x: Expr[StringContext])(using qctx: QuoteContext): Option[StringContext] = x match { - case '{ new StringContext(${ConstSeq(args)}: _*) } => Some(StringContext(args: _*)) - case '{ StringContext(${ConstSeq(args)}: _*) } => Some(StringContext(args: _*)) + case '{ new StringContext(${Exprs(Const(args))}: _*) } => Some(StringContext(args: _*)) + case '{ StringContext(${Exprs(Const(args))}: _*) } => Some(StringContext(args: _*)) case _ => None } override def toString(): String = "scala.quoted.ValueOfExpr.Tuple1_delegate" @@ -270,9 +270,9 @@ object ValueOfExpr { given Seq_delegate[T](using Type[T], ValueOfExpr[T]) as ValueOfExpr[Seq[T]] = new { def apply(x: Expr[Seq[T]])(using qctx: QuoteContext): Option[Seq[T]] = x match { - case ValueSeq(elems) => Some(elems) - case '{ scala.collection.Seq[T](${ValueSeq(elems)}: _*) } => Some(elems) - case '{ scala.collection.immutable.Seq[T](${ValueSeq(elems)}: _*) } => Some(elems) + case Exprs(Value(elems)) => Some(elems) + case '{ scala.collection.Seq[T](${Exprs(Value(elems))}: _*) } => Some(elems) + case '{ scala.collection.immutable.Seq[T](${Exprs(Value(elems))}: _*) } => Some(elems) case _ => None } override def toString(): String = "scala.quoted.ValueOfExpr.Seq_delegate" diff --git a/library/src/scala/quoted/ConstSeq.scala b/library/src/scala/quoted/matching/ConstSeq.scala similarity index 66% rename from library/src/scala/quoted/ConstSeq.scala rename to library/src/scala/quoted/matching/ConstSeq.scala index fb4bb85a5c04..1ab711739b48 100644 --- a/library/src/scala/quoted/ConstSeq.scala +++ b/library/src/scala/quoted/matching/ConstSeq.scala @@ -1,4 +1,5 @@ package scala.quoted +package matching /** Literal sequence of literal constant value expressions */ object ConstSeq { @@ -15,15 +16,11 @@ object ConstSeq { * } * ``` */ - def unapply[T](expr: Expr[Seq[T]])(using qctx: QuoteContext): Option[Seq[T]] = expr match { - case Exprs(elems) => - elems.foldRight(Option(List.empty[T])) { (elem, acc) => - (elem, acc) match { - case (Const(value), Some(lst)) => Some(value :: lst) - case (_, _) => None - } - } - case _ => None - } + @deprecated("use scala.quoted.Exprs(scala.quoted.Const(_)) instead", "0.23.0") + def unapply[T](expr: Expr[Seq[T]])(using qctx: QuoteContext): Option[Seq[T]] = + import scala.quoted.Const + expr match + case Exprs(Const(elems)) => Some(elems) + case _ => None } diff --git a/library/src/scala/quoted/ValueSeq.scala b/library/src/scala/quoted/matching/ValueSeq.scala similarity index 63% rename from library/src/scala/quoted/ValueSeq.scala rename to library/src/scala/quoted/matching/ValueSeq.scala index ee96da3b0a0e..29fc823bef1f 100644 --- a/library/src/scala/quoted/ValueSeq.scala +++ b/library/src/scala/quoted/matching/ValueSeq.scala @@ -1,4 +1,5 @@ package scala.quoted +package matching /** Value sequence of value expressions */ object ValueSeq { @@ -15,15 +16,11 @@ object ValueSeq { * } * ``` */ - def unapply[T](expr: Expr[Seq[T]])(using valueOf: ValueOfExpr[T], qctx: QuoteContext): Option[Seq[T]] = expr match { - case Exprs(elems) => - elems.foldRight(Option(List.empty[T])) { (elem, acc) => - (elem, acc) match { - case (Value(value), Some(lst)) => Some(value :: lst) - case (_, _) => None - } - } - case _ => None - } + @deprecated("use scala.quoted.Exprs(scala.quoted.Value(_)) instead", "0.23.0") + def unapply[T](expr: Expr[Seq[T]])(using valueOf: ValueOfExpr[T], qctx: QuoteContext): Option[Seq[T]] = + import scala.quoted.Const + expr match + case Exprs(Value(elems)) => Some(elems) + case _ => None } diff --git a/library/src/scala/quoted/matching/package.scala b/library/src/scala/quoted/matching/package.scala index 42a5426412ad..e0aca49d239f 100644 --- a/library/src/scala/quoted/matching/package.scala +++ b/library/src/scala/quoted/matching/package.scala @@ -17,9 +17,6 @@ package object matching { @deprecated("use scala.quoted.Const instead", "0.23.0") val Const: quoted.Const.type = quoted.Const - @deprecated("use scala.quoted.ConstSeq instead", "0.23.0") - val ConstSeq: quoted.ConstSeq.type = quoted.ConstSeq - @deprecated("use scala.quoted.Exprs instead", "0.23.0") val ExprSeq: quoted.Exprs.type = quoted.Exprs @@ -32,7 +29,4 @@ package object matching { @deprecated("use scala.quoted.ValueOfExpr instead", "0.23.0") val ValueOfExpr: quoted.ValueOfExpr.type = quoted.ValueOfExpr - @deprecated("use scala.quoted.ValueSeq instead", "0.23.0") - val ValueSeq: quoted.ValueSeq.type = quoted.ValueSeq - } diff --git a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala index b2d899fbc099..eb3c9e0cb9ac 100644 --- a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala @@ -8,7 +8,7 @@ object Macros { private def impl(self: Expr[StringContext], args: Expr[Seq[String]])(using QuoteContext): Expr[String] = { self match { - case '{ StringContext(${ConstSeq(parts)}: _*) } => + case '{ StringContext(${Exprs(Const(parts))}: _*) } => val upprerParts: List[String] = parts.toList.map(_.toUpperCase) val upprerPartsExpr: Expr[List[String]] = Expr.ofList(upprerParts.map(Expr(_))) '{ StringContext($upprerPartsExpr: _*).s($args: _*) } diff --git a/tests/run-macros/quoted-matching-docs/Macro_1.scala b/tests/run-macros/quoted-matching-docs/Macro_1.scala index 938b2d579580..5da7a16ce331 100644 --- a/tests/run-macros/quoted-matching-docs/Macro_1.scala +++ b/tests/run-macros/quoted-matching-docs/Macro_1.scala @@ -12,7 +12,7 @@ private def sumExprShow(argsExpr: Expr[Seq[Int]]) (using QuoteContext): Expr[Str private def sumExpr(argsExpr: Expr[Seq[Int]])(using qctx: QuoteContext) : Expr[Int] = { import qctx.tasty.{given _, _} UnsafeExpr.underlyingArgument(argsExpr) match { - case ConstSeq(args) => // args is of type Seq[Int] + case Exprs(Const(args)) => // args is of type Seq[Int] Expr(args.sum) // precompute result of sum case Exprs(argExprs) => // argExprs is of type Seq[Expr[Int]] val staticSum: Int = argExprs.map { From f5ffa990333eaafb5020a674f469e77fffa88538 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Mar 2020 11:44:07 +0100 Subject: [PATCH 5/9] Update uses of `Expr.ofSeq` --- docs/docs/reference/metaprogramming/macros.md | 2 +- tests/run-macros/i7008/macro_1.scala | 2 +- tests/run-macros/string-context-implicits/Macro_1.scala | 2 +- tests/run-macros/tasty-simplified/quoted_1.scala | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 09f26f8a3e3b..5d5e0f056866 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -714,7 +714,7 @@ private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using case None => qctx.error(s"could not find implicit for ${showTp.show}", arg); '{???} } } - val newArgsExpr = Expr.ofSeq(argShowedExprs) + val newArgsExpr = Exprs(argShowedExprs) '{ $sc.s($newArgsExpr: _*) } case _ => // `new StringContext(...).showMeExpr(args: _*)` not an explicit `showMeExpr"..."` diff --git a/tests/run-macros/i7008/macro_1.scala b/tests/run-macros/i7008/macro_1.scala index 4a0fa0721756..1797ba25d5e4 100644 --- a/tests/run-macros/i7008/macro_1.scala +++ b/tests/run-macros/i7008/macro_1.scala @@ -14,6 +14,6 @@ def mcrProxy(expr: Expr[Boolean])(using QuoteContext): Expr[Unit] = { def mcrImpl[T](func: Expr[Seq[Box[T]] => Unit], expr: Expr[T])(using ctx: QuoteContext, tt: Type[T]): Expr[Unit] = { import ctx.tasty._ - val arg = Expr.ofSeq(Seq('{(Box($expr))})) + val arg = Exprs(Seq('{(Box($expr))})) Expr.betaReduce(func)(arg) } \ No newline at end of file diff --git a/tests/run-macros/string-context-implicits/Macro_1.scala b/tests/run-macros/string-context-implicits/Macro_1.scala index 8838885d25c7..caf103b5a889 100644 --- a/tests/run-macros/string-context-implicits/Macro_1.scala +++ b/tests/run-macros/string-context-implicits/Macro_1.scala @@ -14,7 +14,7 @@ private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using case None => qctx.error(s"could not find implicit for ${showTp.show}", arg); '{???} } } - val newArgsExpr = Expr.ofSeq(argShowedExprs) + val newArgsExpr = Exprs(argShowedExprs) '{ $sc.s($newArgsExpr: _*) } case _ => // `new StringContext(...).showMeExpr(args: _*)` not an explicit `showMeExpr"..."` diff --git a/tests/run-macros/tasty-simplified/quoted_1.scala b/tests/run-macros/tasty-simplified/quoted_1.scala index 3f29aa728669..73298e17b0c1 100644 --- a/tests/run-macros/tasty-simplified/quoted_1.scala +++ b/tests/run-macros/tasty-simplified/quoted_1.scala @@ -19,6 +19,6 @@ object Macros { } val tps = unpackTuple(typeOf[T]) - Expr.ofSeq(tps.map(x => Expr(x.show))) + Exprs(tps.map(x => Expr(x.show))) } } From 667f3e407ffe59d47a2c985b345c199528893f53 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Mar 2020 11:47:52 +0100 Subject: [PATCH 6/9] Update test checkfile --- tests/neg/i6436.check | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/neg/i6436.check b/tests/neg/i6436.check index 3287068d6e55..a98284988d2c 100644 --- a/tests/neg/i6436.check +++ b/tests/neg/i6436.check @@ -1,6 +1,6 @@ -- Error: tests/neg/i6436.scala:5:9 ------------------------------------------------------------------------------------ 5 | case '{ StringContext(${Exprs(parts)}: _*) } => // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | no implicit argument of type scala.quoted.QuoteContext was found -- [E006] Unbound Identifier Error: tests/neg/i6436.scala:6:34 --------------------------------------------------------- 6 | val ps: Seq[Expr[String]] = parts // error From 869b9bd70cad193a7ec4c55e46e4128a1dbce38e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Mar 2020 13:13:45 +0100 Subject: [PATCH 7/9] Rename `Exprs` to `Varargs` --- docs/docs/reference/metaprogramming/macros.md | 12 ++++++------ .../dotty/internal/StringContextMacro.scala | 4 ++-- library/src/scala/quoted/Const.scala | 2 +- library/src/scala/quoted/Expr.scala | 6 +++--- library/src/scala/quoted/Value.scala | 2 +- library/src/scala/quoted/ValueOfExpr.scala | 10 +++++----- .../src/scala/quoted/{Exprs.scala => Varargs.scala} | 8 ++++---- library/src/scala/quoted/matching/ConstSeq.scala | 4 ++-- library/src/scala/quoted/matching/ValueSeq.scala | 4 ++-- library/src/scala/quoted/matching/package.scala | 4 ++-- tests/neg-macros/i6432/Macro_1.scala | 2 +- tests/neg-macros/i6432b/Macro_1.scala | 2 +- tests/neg/i6436.check | 4 ++-- tests/neg/i6436.scala | 2 +- tests/pos/i6435.scala | 2 +- tests/run-macros/f-interpolator-neg/Macros_1.scala | 4 ++-- tests/run-macros/i7008/macro_1.scala | 2 +- .../quoted_1.scala | 2 +- .../quoted_1.scala | 2 +- .../quote-matcher-string-interpolator/quoted_1.scala | 2 +- .../run-macros/quoted-matching-docs-2/Macro_1.scala | 4 ++-- tests/run-macros/quoted-matching-docs/Macro_1.scala | 4 ++-- .../string-context-implicits/Macro_1.scala | 4 ++-- tests/run-macros/tasty-simplified/quoted_1.scala | 2 +- .../Macros_1.scala | 4 ++-- 25 files changed, 49 insertions(+), 49 deletions(-) rename library/src/scala/quoted/{Exprs.scala => Varargs.scala} (88%) diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 5d5e0f056866..80f3e4f6472c 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -624,9 +624,9 @@ These could be used in the following way to optimize any call to `sum` that has ```scala inline def sum(inline args: Int*): Int = ${ sumExpr('args) } private def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match { - case Exprs(Const(args)) => // args is of type Seq[Int] + case Varargs(Const(args)) => // args is of type Seq[Int] Expr(args.sum) // precompute result of sum - case Exprs(argExprs) => // argExprs is of type Seq[Expr[Int]] + case Varargs(argExprs) => // argExprs is of type Seq[Expr[Int]] val staticSum: Int = argExprs.map { case Const(arg) => arg case _ => 0 @@ -662,12 +662,12 @@ private def optimizeExpr(body: Expr[Int])(using QuoteContext): Expr[Int] = body // Match a call to sum with an argument $n of type Int. n will be the Expr[Int] representing the argument. case '{ sum($n) } => n // Match a call to sum and extracts all its args in an `Expr[Seq[Int]]` - case '{ sum(${Exprs(args)}: _*) } => sumExpr(args) + case '{ sum(${Varargs(args)}: _*) } => sumExpr(args) case body => body } private def sumExpr(args1: Seq[Expr[Int]])(using QuoteContext): Expr[Int] = { def flatSumArgs(arg: Expr[Int]): Seq[Expr[Int]] = arg match { - case '{ sum(${Exprs(subArgs)}: _*) } => subArgs.flatMap(flatSumArgs) + case '{ sum(${Varargs(subArgs)}: _*) } => subArgs.flatMap(flatSumArgs) case arg => Seq(arg) } val args2 = args1.flatMap(flatSumArgs) @@ -705,7 +705,7 @@ inline def (sc: StringContext).showMe(inline args: Any*): String = ${ showMeExpr private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[String] = { argsExpr match { - case Exprs(argExprs) => + case Varargs(argExprs) => val argShowedExprs = argExprs.map { case '{ $arg: $tp } => val showTp = '[Show[$tp]] @@ -714,7 +714,7 @@ private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using case None => qctx.error(s"could not find implicit for ${showTp.show}", arg); '{???} } } - val newArgsExpr = Exprs(argShowedExprs) + val newArgsExpr = Varargs(argShowedExprs) '{ $sc.s($newArgsExpr: _*) } case _ => // `new StringContext(...).showMeExpr(args: _*)` not an explicit `showMeExpr"..."` diff --git a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala index 9ac2210b523e..fd2a03f5d11c 100644 --- a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala +++ b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala @@ -64,7 +64,7 @@ object StringContextMacro { def notStatic = qctx.throwError("Expected statically known String Context", strCtxExpr) def splitParts(seq: Expr[Seq[String]]) = seq match { - case Exprs(p1) => + case Varargs(p1) => p1 match case Const(p2) => (p1.toList, p2.toList) case _ => notStatic @@ -77,7 +77,7 @@ object StringContextMacro { } val args = argsExpr match { - case Exprs(args) => args + case Varargs(args) => args case _ => qctx.throwError("Expected statically known argument list", argsExpr) } diff --git a/library/src/scala/quoted/Const.scala b/library/src/scala/quoted/Const.scala index cc9349eef8b7..cae8794930e1 100644 --- a/library/src/scala/quoted/Const.scala +++ b/library/src/scala/quoted/Const.scala @@ -32,7 +32,7 @@ object Const { * ```scala * inline def sum(args: Int*): Int = ${ sumExpr('args) } * def sumExpr(argsExpr: Expr[Seq[Int]])(usingusing QuoteContext): Expr[Int] = argsExpr match - * case Exprs(Const(args)) => + * case Varargs(Const(args)) => * // args: Seq[Int] * ... * } diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index 8e1882e6f34a..27682a2df6a6 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -110,7 +110,7 @@ object Expr { * `'{ Seq($e1, $e2, ...) }` typed as an `Expr[Seq[T]]` * ``` */ - def ofSeq[T](xs: Seq[Expr[T]])(using tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = Exprs(xs) + def ofSeq[T](xs: Seq[Expr[T]])(using tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = Varargs(xs) /** Lifts this list of expressions into an expression of a list * @@ -120,7 +120,7 @@ object Expr { * `'{ List($e1, $e2, ...) }` typed as an `Expr[List[T]]` */ def ofList[T](xs: Seq[Expr[T]])(using Type[T], QuoteContext): Expr[List[T]] = - if (xs.isEmpty) '{ Nil } else '{ List(${Exprs(xs)}: _*) } + if (xs.isEmpty) '{ Nil } else '{ List(${Varargs(xs)}: _*) } /** Lifts this sequence of expressions into an expression of a tuple * @@ -178,7 +178,7 @@ object Expr { case Seq('{ $x1: $t1 }, '{ $x2: $t2 }, '{ $x3: $t3 }, '{ $x4: $t4 }, '{ $x5: $t5 }, '{ $x6: $t6 }, '{ $x7: $t7 }, '{ $x8: $t8 }, '{ $x9: $t9 }, '{ $x10: $t10 }, '{ $x11: $t11 }, '{ $x12: $t12 }, '{ $x13: $t13 }, '{ $x14: $t14 }, '{ $x15: $t15 }, '{ $x16: $t16 }, '{ $x17: $t17 }, '{ $x18: $t18 }, '{ $x19: $t19 }, '{ $x20: $t20 }, '{ $x21: $t21 }, '{ $x22: $t22 }) => '{ Tuple22($x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x18, $x19, $x20, $x21, $x22) } case _ => - '{ Tuple.fromIArray(IArray(${Exprs(seq)}: _*)) } + '{ Tuple.fromIArray(IArray(${Varargs(seq)}: _*)) } } } diff --git a/library/src/scala/quoted/Value.scala b/library/src/scala/quoted/Value.scala index a43c367c2a84..c573c0678068 100644 --- a/library/src/scala/quoted/Value.scala +++ b/library/src/scala/quoted/Value.scala @@ -21,7 +21,7 @@ object Value { * ```scala * inline def sum(args: Int*): Int = ${ sumExpr('args) } * def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match - * case Exprs(Value(args)) => + * case Varargs(Value(args)) => * // args: Seq[Int] * ... * } diff --git a/library/src/scala/quoted/ValueOfExpr.scala b/library/src/scala/quoted/ValueOfExpr.scala index ef8ec95ef093..81c9e05a6e9f 100644 --- a/library/src/scala/quoted/ValueOfExpr.scala +++ b/library/src/scala/quoted/ValueOfExpr.scala @@ -42,8 +42,8 @@ object ValueOfExpr { given StringContext_delegate as ValueOfExpr[StringContext] = new { def apply(x: Expr[StringContext])(using qctx: QuoteContext): Option[StringContext] = x match { - case '{ new StringContext(${Exprs(Const(args))}: _*) } => Some(StringContext(args: _*)) - case '{ StringContext(${Exprs(Const(args))}: _*) } => Some(StringContext(args: _*)) + case '{ new StringContext(${Varargs(Const(args))}: _*) } => Some(StringContext(args: _*)) + case '{ StringContext(${Varargs(Const(args))}: _*) } => Some(StringContext(args: _*)) case _ => None } override def toString(): String = "scala.quoted.ValueOfExpr.Tuple1_delegate" @@ -270,9 +270,9 @@ object ValueOfExpr { given Seq_delegate[T](using Type[T], ValueOfExpr[T]) as ValueOfExpr[Seq[T]] = new { def apply(x: Expr[Seq[T]])(using qctx: QuoteContext): Option[Seq[T]] = x match { - case Exprs(Value(elems)) => Some(elems) - case '{ scala.collection.Seq[T](${Exprs(Value(elems))}: _*) } => Some(elems) - case '{ scala.collection.immutable.Seq[T](${Exprs(Value(elems))}: _*) } => Some(elems) + case Varargs(Value(elems)) => Some(elems) + case '{ scala.collection.Seq[T](${Varargs(Value(elems))}: _*) } => Some(elems) + case '{ scala.collection.immutable.Seq[T](${Varargs(Value(elems))}: _*) } => Some(elems) case _ => None } override def toString(): String = "scala.quoted.ValueOfExpr.Seq_delegate" diff --git a/library/src/scala/quoted/Exprs.scala b/library/src/scala/quoted/Varargs.scala similarity index 88% rename from library/src/scala/quoted/Exprs.scala rename to library/src/scala/quoted/Varargs.scala index 5913e2e59e69..39034ae6b582 100644 --- a/library/src/scala/quoted/Exprs.scala +++ b/library/src/scala/quoted/Varargs.scala @@ -1,7 +1,7 @@ package scala.quoted /** Literal sequence of expressions */ -object Exprs { +object Varargs { /** Lifts this sequence of expressions into an expression of a sequence * @@ -12,7 +12,7 @@ object Exprs { * * Usage: * ```scala - * '{ List(${Exprs(List(1, 2, 3))}: _*) } // equvalent to '{ List(1, 2, 3) } + * '{ List(${Varargs(List(1, 2, 3))}: _*) } // equvalent to '{ List(1, 2, 3) } * ``` */ def apply[T](xs: Seq[Expr[T]])(using tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = { @@ -26,8 +26,8 @@ object Exprs { * ```scala * inline def sum(args: Int*): Int = ${ sumExpr('args) } * def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match - * case Exprs(argExprs) => - * // argExprs: Seq[Expr[Int]] + * case Varargs(argVarargs) => + * // argVarargs: Seq[Expr[Int]] * ... * } * ``` diff --git a/library/src/scala/quoted/matching/ConstSeq.scala b/library/src/scala/quoted/matching/ConstSeq.scala index 1ab711739b48..715ae5be62d8 100644 --- a/library/src/scala/quoted/matching/ConstSeq.scala +++ b/library/src/scala/quoted/matching/ConstSeq.scala @@ -16,11 +16,11 @@ object ConstSeq { * } * ``` */ - @deprecated("use scala.quoted.Exprs(scala.quoted.Const(_)) instead", "0.23.0") + @deprecated("use scala.quoted.Varargs(scala.quoted.Const(_)) instead", "0.23.0") def unapply[T](expr: Expr[Seq[T]])(using qctx: QuoteContext): Option[Seq[T]] = import scala.quoted.Const expr match - case Exprs(Const(elems)) => Some(elems) + case Varargs(Const(elems)) => Some(elems) case _ => None } diff --git a/library/src/scala/quoted/matching/ValueSeq.scala b/library/src/scala/quoted/matching/ValueSeq.scala index 29fc823bef1f..31195f0dca1f 100644 --- a/library/src/scala/quoted/matching/ValueSeq.scala +++ b/library/src/scala/quoted/matching/ValueSeq.scala @@ -16,11 +16,11 @@ object ValueSeq { * } * ``` */ - @deprecated("use scala.quoted.Exprs(scala.quoted.Value(_)) instead", "0.23.0") + @deprecated("use scala.quoted.Varargs(scala.quoted.Value(_)) instead", "0.23.0") def unapply[T](expr: Expr[Seq[T]])(using valueOf: ValueOfExpr[T], qctx: QuoteContext): Option[Seq[T]] = import scala.quoted.Const expr match - case Exprs(Value(elems)) => Some(elems) + case Varargs(Value(elems)) => Some(elems) case _ => None } diff --git a/library/src/scala/quoted/matching/package.scala b/library/src/scala/quoted/matching/package.scala index e0aca49d239f..21496d4d4db8 100644 --- a/library/src/scala/quoted/matching/package.scala +++ b/library/src/scala/quoted/matching/package.scala @@ -17,8 +17,8 @@ package object matching { @deprecated("use scala.quoted.Const instead", "0.23.0") val Const: quoted.Const.type = quoted.Const - @deprecated("use scala.quoted.Exprs instead", "0.23.0") - val ExprSeq: quoted.Exprs.type = quoted.Exprs + @deprecated("use scala.quoted.Varargs instead", "0.23.0") + val ExprSeq: quoted.Varargs.type = quoted.Varargs @deprecated("use scala.quoted.Lambda instead", "0.23.0") val Lambda: quoted.Lambda.type = quoted.Lambda diff --git a/tests/neg-macros/i6432/Macro_1.scala b/tests/neg-macros/i6432/Macro_1.scala index 325bef4e2a74..7c9b63deb114 100644 --- a/tests/neg-macros/i6432/Macro_1.scala +++ b/tests/neg-macros/i6432/Macro_1.scala @@ -9,7 +9,7 @@ object Macro { def impl(sc: Expr[StringContext])(using qctx: QuoteContext) : Expr[Unit] = { import qctx.tasty._ sc match { - case '{ StringContext(${Exprs(parts)}: _*) } => + case '{ StringContext(${Varargs(parts)}: _*) } => for (part @ Const(s) <- parts) error(s, part.unseal.pos) } diff --git a/tests/neg-macros/i6432b/Macro_1.scala b/tests/neg-macros/i6432b/Macro_1.scala index 325bef4e2a74..7c9b63deb114 100644 --- a/tests/neg-macros/i6432b/Macro_1.scala +++ b/tests/neg-macros/i6432b/Macro_1.scala @@ -9,7 +9,7 @@ object Macro { def impl(sc: Expr[StringContext])(using qctx: QuoteContext) : Expr[Unit] = { import qctx.tasty._ sc match { - case '{ StringContext(${Exprs(parts)}: _*) } => + case '{ StringContext(${Varargs(parts)}: _*) } => for (part @ Const(s) <- parts) error(s, part.unseal.pos) } diff --git a/tests/neg/i6436.check b/tests/neg/i6436.check index a98284988d2c..ec431058c1e1 100644 --- a/tests/neg/i6436.check +++ b/tests/neg/i6436.check @@ -1,6 +1,6 @@ -- Error: tests/neg/i6436.scala:5:9 ------------------------------------------------------------------------------------ -5 | case '{ StringContext(${Exprs(parts)}: _*) } => // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +5 | case '{ StringContext(${Varargs(parts)}: _*) } => // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | no implicit argument of type scala.quoted.QuoteContext was found -- [E006] Unbound Identifier Error: tests/neg/i6436.scala:6:34 --------------------------------------------------------- 6 | val ps: Seq[Expr[String]] = parts // error diff --git a/tests/neg/i6436.scala b/tests/neg/i6436.scala index 8f26a500064c..bd3ff515ca29 100644 --- a/tests/neg/i6436.scala +++ b/tests/neg/i6436.scala @@ -2,7 +2,7 @@ import scala.quoted._ def f(sc: quoted.Expr[StringContext]): Unit = { sc match { - case '{ StringContext(${Exprs(parts)}: _*) } => // error + case '{ StringContext(${Varargs(parts)}: _*) } => // error val ps: Seq[Expr[String]] = parts // error } } \ No newline at end of file diff --git a/tests/pos/i6435.scala b/tests/pos/i6435.scala index 6fca63679a63..6d11809c8f62 100644 --- a/tests/pos/i6435.scala +++ b/tests/pos/i6435.scala @@ -6,7 +6,7 @@ class Foo { val '{ StringContext(${parts}: _*) } = sc val ps0: Expr[Seq[String]] = parts - val '{ StringContext(${Exprs(parts2)}: _*) } = sc + val '{ StringContext(${Varargs(parts2)}: _*) } = sc val ps: Seq[Expr[String]] = parts2 } } \ No newline at end of file diff --git a/tests/run-macros/f-interpolator-neg/Macros_1.scala b/tests/run-macros/f-interpolator-neg/Macros_1.scala index 8fed3164ef26..e0bea018ed54 100644 --- a/tests/run-macros/f-interpolator-neg/Macros_1.scala +++ b/tests/run-macros/f-interpolator-neg/Macros_1.scala @@ -14,9 +14,9 @@ object Macro { def fooErrors(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using QuoteContext): Expr[List[(Boolean, Int, Int, Int, String)]] = { (strCtxExpr, argsExpr) match { - case ('{ StringContext(${Exprs(parts)}: _*) }, Exprs(args)) => + case ('{ StringContext(${Varargs(parts)}: _*) }, Varargs(args)) => fooErrorsImpl(parts, args, argsExpr) - case ('{ new StringContext(${Exprs(parts)}: _*) }, Exprs(args)) => + case ('{ new StringContext(${Varargs(parts)}: _*) }, Varargs(args)) => fooErrorsImpl(parts, args, argsExpr) } } diff --git a/tests/run-macros/i7008/macro_1.scala b/tests/run-macros/i7008/macro_1.scala index 1797ba25d5e4..856b943d526d 100644 --- a/tests/run-macros/i7008/macro_1.scala +++ b/tests/run-macros/i7008/macro_1.scala @@ -14,6 +14,6 @@ def mcrProxy(expr: Expr[Boolean])(using QuoteContext): Expr[Unit] = { def mcrImpl[T](func: Expr[Seq[Box[T]] => Unit], expr: Expr[T])(using ctx: QuoteContext, tt: Type[T]): Expr[Unit] = { import ctx.tasty._ - val arg = Exprs(Seq('{(Box($expr))})) + val arg = Varargs(Seq('{(Box($expr))})) Expr.betaReduce(func)(arg) } \ No newline at end of file diff --git a/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala index fc143cff8fe0..887f2c25605e 100644 --- a/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator-2/quoted_1.scala @@ -8,7 +8,7 @@ object Macros { private def impl(self: Expr[StringContext], args: Expr[Seq[String]])(using QuoteContext): Expr[String] = { (self, args) match { - case ('{ StringContext(${Exprs(parts)}: _*) }, Exprs(args1)) => + case ('{ StringContext(${Varargs(parts)}: _*) }, Varargs(args1)) => val strParts = parts.map { case Const(str) => str.reverse } val strArgs = args1.map { case Const(str) => str } Expr(StringContext(strParts: _*).s(strArgs: _*)) diff --git a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala index eb3c9e0cb9ac..9a4dda0f2a39 100644 --- a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala @@ -8,7 +8,7 @@ object Macros { private def impl(self: Expr[StringContext], args: Expr[Seq[String]])(using QuoteContext): Expr[String] = { self match { - case '{ StringContext(${Exprs(Const(parts))}: _*) } => + case '{ StringContext(${Varargs(Const(parts))}: _*) } => val upprerParts: List[String] = parts.toList.map(_.toUpperCase) val upprerPartsExpr: Expr[List[String]] = Expr.ofList(upprerParts.map(Expr(_))) '{ StringContext($upprerPartsExpr: _*).s($args: _*) } diff --git a/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala index ef9a62f5db28..08950f89e090 100644 --- a/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator/quoted_1.scala @@ -8,7 +8,7 @@ object Macros { private def impl(self: Expr[StringContext], args: Expr[Seq[String]])(using QuoteContext): Expr[String] = { self match { - case '{ StringContext(${Exprs(parts)}: _*) } => + case '{ StringContext(${Varargs(parts)}: _*) } => val parts2 = Expr.ofList(parts.map(x => '{ $x.reverse })) '{ StringContext($parts2: _*).s($args: _*) } case _ => diff --git a/tests/run-macros/quoted-matching-docs-2/Macro_1.scala b/tests/run-macros/quoted-matching-docs-2/Macro_1.scala index ba067f8cb4e3..412c74a547c5 100644 --- a/tests/run-macros/quoted-matching-docs-2/Macro_1.scala +++ b/tests/run-macros/quoted-matching-docs-2/Macro_1.scala @@ -15,13 +15,13 @@ private def optimizeExpr(body: Expr[Int])(using QuoteContext): Expr[Int] = body // Match a call to sum with an argument $n of type Int. n will be the Expr[Int] representing the argument. case '{ sum($n) } => n // Match a call to sum and extracts all its args in an `Expr[Seq[Int]]` - case '{ sum(${Exprs(args)}: _*) } => sumExpr(args) + case '{ sum(${Varargs(args)}: _*) } => sumExpr(args) case body => body } private def sumExpr(args1: Seq[Expr[Int]])(using QuoteContext): Expr[Int] = { def flatSumArgs(arg: Expr[Int]): Seq[Expr[Int]] = arg match { - case '{ sum(${Exprs(subArgs)}: _*) } => subArgs.flatMap(flatSumArgs) + case '{ sum(${Varargs(subArgs)}: _*) } => subArgs.flatMap(flatSumArgs) case arg => Seq(arg) } val args2 = args1.flatMap(flatSumArgs) diff --git a/tests/run-macros/quoted-matching-docs/Macro_1.scala b/tests/run-macros/quoted-matching-docs/Macro_1.scala index 5da7a16ce331..c59156ce3b90 100644 --- a/tests/run-macros/quoted-matching-docs/Macro_1.scala +++ b/tests/run-macros/quoted-matching-docs/Macro_1.scala @@ -12,9 +12,9 @@ private def sumExprShow(argsExpr: Expr[Seq[Int]]) (using QuoteContext): Expr[Str private def sumExpr(argsExpr: Expr[Seq[Int]])(using qctx: QuoteContext) : Expr[Int] = { import qctx.tasty.{given _, _} UnsafeExpr.underlyingArgument(argsExpr) match { - case Exprs(Const(args)) => // args is of type Seq[Int] + case Varargs(Const(args)) => // args is of type Seq[Int] Expr(args.sum) // precompute result of sum - case Exprs(argExprs) => // argExprs is of type Seq[Expr[Int]] + case Varargs(argExprs) => // argExprs is of type Seq[Expr[Int]] val staticSum: Int = argExprs.map { case Const(arg) => arg case _ => 0 diff --git a/tests/run-macros/string-context-implicits/Macro_1.scala b/tests/run-macros/string-context-implicits/Macro_1.scala index caf103b5a889..47fbafe5845b 100644 --- a/tests/run-macros/string-context-implicits/Macro_1.scala +++ b/tests/run-macros/string-context-implicits/Macro_1.scala @@ -5,7 +5,7 @@ inline def (sc: StringContext) showMe(inline args: Any*): String = ${ showMeExpr private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[String] = { argsExpr match { - case Exprs(argExprs) => + case Varargs(argExprs) => val argShowedExprs = argExprs.map { case '{ $arg: $tp } => val showTp = '[Show[$tp]] @@ -14,7 +14,7 @@ private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using case None => qctx.error(s"could not find implicit for ${showTp.show}", arg); '{???} } } - val newArgsExpr = Exprs(argShowedExprs) + val newArgsExpr = Varargs(argShowedExprs) '{ $sc.s($newArgsExpr: _*) } case _ => // `new StringContext(...).showMeExpr(args: _*)` not an explicit `showMeExpr"..."` diff --git a/tests/run-macros/tasty-simplified/quoted_1.scala b/tests/run-macros/tasty-simplified/quoted_1.scala index 73298e17b0c1..c9ef9a10dd43 100644 --- a/tests/run-macros/tasty-simplified/quoted_1.scala +++ b/tests/run-macros/tasty-simplified/quoted_1.scala @@ -19,6 +19,6 @@ object Macros { } val tps = unpackTuple(typeOf[T]) - Exprs(tps.map(x => Expr(x.show))) + Varargs(tps.map(x => Expr(x.show))) } } diff --git a/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala b/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala index 69316e87701a..b638bf23edaa 100644 --- a/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala +++ b/tests/run-macros/tasty-string-interpolation-reporter-test/Macros_1.scala @@ -21,7 +21,7 @@ object Macro { def foo(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[String] = { (sc, argsExpr) match { - case ('{ StringContext(${Exprs(parts)}: _*) }, Exprs(args)) => + case ('{ StringContext(${Varargs(parts)}: _*) }, Varargs(args)) => val reporter = new Reporter { def errorOnPart(msg: String, partIdx: Int): Unit = { import qctx.tasty._ @@ -34,7 +34,7 @@ object Macro { def fooErrors(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[List[(Int, Int, Int, String)]] = { (sc, argsExpr) match { - case ('{ StringContext(${Exprs(parts)}: _*) }, Exprs(args)) => + case ('{ StringContext(${Varargs(parts)}: _*) }, Varargs(args)) => val errors = List.newBuilder[Expr[(Int, Int, Int, String)]] val reporter = new Reporter { def errorOnPart(msg: String, partIdx: Int): Unit = { From be3f2d74603dff468ab7efefc2719a6e17250419 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Mar 2020 13:16:30 +0100 Subject: [PATCH 8/9] Define `Consts` and `Values` --- docs/docs/reference/metaprogramming/macros.md | 8 +++--- .../dotty/internal/StringContextMacro.scala | 2 +- library/src/scala/quoted/Const.scala | 20 -------------- library/src/scala/quoted/Consts.scala | 26 +++++++++++++++++++ library/src/scala/quoted/Value.scala | 19 -------------- library/src/scala/quoted/ValueOfExpr.scala | 10 +++---- library/src/scala/quoted/Values.scala | 25 ++++++++++++++++++ .../src/scala/quoted/matching/ConstSeq.scala | 2 +- .../src/scala/quoted/matching/ValueSeq.scala | 2 +- .../quoted_1.scala | 2 +- .../quoted-matching-docs/Macro_1.scala | 2 +- 11 files changed, 65 insertions(+), 53 deletions(-) create mode 100644 library/src/scala/quoted/Consts.scala create mode 100644 library/src/scala/quoted/Values.scala diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 80f3e4f6472c..e6b85438a132 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -616,15 +616,15 @@ It is possible to deconstruct or extract values out of `Expr` using pattern matc `scala.quoted` contains objects that can help extracting values from `Expr`. -* `scala.quoted.Const`: matches an expression of a literal value (or list of values) and returns the value (or list of values). -* `scala.quoted.Value`: matches an expression of a value (or list of values) and returns the value (or list of values). -* `scala.quoted.Exprs`: matches an explicit sequence of expresions and returns them. These sequences are useful to get individual `Expr[T]` out of a varargs expression of type `Expr[Seq[T]]`. +* `scala.quoted.Const`/`scala.quoted.Consts`: matches an expression of a literal value (or list of values) and returns the value (or list of values). +* `scala.quoted.Value`/`scala.quoted.Values`: matches an expression of a value (or list of values) and returns the value (or list of values). +* `scala.quoted.Varargs`: matches an explicit sequence of expresions and returns them. These sequences are useful to get individual `Expr[T]` out of a varargs expression of type `Expr[Seq[T]]`. These could be used in the following way to optimize any call to `sum` that has statically known values. ```scala inline def sum(inline args: Int*): Int = ${ sumExpr('args) } private def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match { - case Varargs(Const(args)) => // args is of type Seq[Int] + case Varargs(Consts(args)) => // args is of type Seq[Int] Expr(args.sum) // precompute result of sum case Varargs(argExprs) => // argExprs is of type Seq[Expr[Int]] val staticSum: Int = argExprs.map { diff --git a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala index fd2a03f5d11c..ef13ca71a472 100644 --- a/library/src-bootstrapped/dotty/internal/StringContextMacro.scala +++ b/library/src-bootstrapped/dotty/internal/StringContextMacro.scala @@ -66,7 +66,7 @@ object StringContextMacro { def splitParts(seq: Expr[Seq[String]]) = seq match { case Varargs(p1) => p1 match - case Const(p2) => (p1.toList, p2.toList) + case Consts(p2) => (p1.toList, p2.toList) case _ => notStatic case _ => notStatic } diff --git a/library/src/scala/quoted/Const.scala b/library/src/scala/quoted/Const.scala index cae8794930e1..5067c78918b8 100644 --- a/library/src/scala/quoted/Const.scala +++ b/library/src/scala/quoted/Const.scala @@ -26,24 +26,4 @@ object Const { rec(expr.unseal) } - /** Matches literal sequence of literal constant value expressions and return a sequence of values. - * - * Usage: - * ```scala - * inline def sum(args: Int*): Int = ${ sumExpr('args) } - * def sumExpr(argsExpr: Expr[Seq[Int]])(usingusing QuoteContext): Expr[Int] = argsExpr match - * case Varargs(Const(args)) => - * // args: Seq[Int] - * ... - * } - * ``` - */ - def unapply[T](exprs: Seq[Expr[T]])(using qctx: QuoteContext): Option[Seq[T]] = - exprs.foldRight(Option(List.empty[T])) { (elem, acc) => - (elem, acc) match { - case (Const(value), Some(lst)) => Some(value :: lst) - case (_, _) => None - } - } - } diff --git a/library/src/scala/quoted/Consts.scala b/library/src/scala/quoted/Consts.scala new file mode 100644 index 000000000000..6955c435379e --- /dev/null +++ b/library/src/scala/quoted/Consts.scala @@ -0,0 +1,26 @@ +package scala.quoted + +/** MLiteral constant values */ +object Consts { + + /** Matches literal sequence of literal constant value expressions and return a sequence of values. + * + * Usage: + * ```scala + * inline def sum(args: Int*): Int = ${ sumExpr('args) } + * def sumExpr(argsExpr: Expr[Seq[Int]])(usingusing QuoteContext): Expr[Int] = argsExpr match + * case Varargs(Consts(args)) => + * // args: Seq[Int] + * ... + * } + * ``` + */ + def unapply[T](exprs: Seq[Expr[T]])(using qctx: QuoteContext): Option[Seq[T]] = + exprs.foldRight(Option(List.empty[T])) { (elem, acc) => + (elem, acc) match { + case (Const(value), Some(lst)) => Some(value :: lst) + case (_, _) => None + } + } + +} diff --git a/library/src/scala/quoted/Value.scala b/library/src/scala/quoted/Value.scala index c573c0678068..5b8ad7e6f3c4 100644 --- a/library/src/scala/quoted/Value.scala +++ b/library/src/scala/quoted/Value.scala @@ -15,23 +15,4 @@ object Value { def unapply[T](expr: Expr[T])(using valueOf: ValueOfExpr[T], qxtc: QuoteContext): Option[T] = valueOf(expr) - /** Matches literal sequence of literal constant value expressions and return a sequence of values. - * - * Usage: - * ```scala - * inline def sum(args: Int*): Int = ${ sumExpr('args) } - * def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match - * case Varargs(Value(args)) => - * // args: Seq[Int] - * ... - * } - * ``` - */ - def unapply[T](exprs: Seq[Expr[T]])(using valueOf: ValueOfExpr[T], qctx: QuoteContext): Option[Seq[T]] = - exprs.foldRight(Option(List.empty[T])) { (elem, acc) => - (elem, acc) match { - case (Value(value), Some(lst)) => Some(value :: lst) - case (_, _) => None - } - } } diff --git a/library/src/scala/quoted/ValueOfExpr.scala b/library/src/scala/quoted/ValueOfExpr.scala index 81c9e05a6e9f..1fc01a6fbedc 100644 --- a/library/src/scala/quoted/ValueOfExpr.scala +++ b/library/src/scala/quoted/ValueOfExpr.scala @@ -42,8 +42,8 @@ object ValueOfExpr { given StringContext_delegate as ValueOfExpr[StringContext] = new { def apply(x: Expr[StringContext])(using qctx: QuoteContext): Option[StringContext] = x match { - case '{ new StringContext(${Varargs(Const(args))}: _*) } => Some(StringContext(args: _*)) - case '{ StringContext(${Varargs(Const(args))}: _*) } => Some(StringContext(args: _*)) + case '{ new StringContext(${Varargs(Consts(args))}: _*) } => Some(StringContext(args: _*)) + case '{ StringContext(${Varargs(Consts(args))}: _*) } => Some(StringContext(args: _*)) case _ => None } override def toString(): String = "scala.quoted.ValueOfExpr.Tuple1_delegate" @@ -270,9 +270,9 @@ object ValueOfExpr { given Seq_delegate[T](using Type[T], ValueOfExpr[T]) as ValueOfExpr[Seq[T]] = new { def apply(x: Expr[Seq[T]])(using qctx: QuoteContext): Option[Seq[T]] = x match { - case Varargs(Value(elems)) => Some(elems) - case '{ scala.collection.Seq[T](${Varargs(Value(elems))}: _*) } => Some(elems) - case '{ scala.collection.immutable.Seq[T](${Varargs(Value(elems))}: _*) } => Some(elems) + case Varargs(Values(elems)) => Some(elems) + case '{ scala.collection.Seq[T](${Varargs(Values(elems))}: _*) } => Some(elems) + case '{ scala.collection.immutable.Seq[T](${Varargs(Values(elems))}: _*) } => Some(elems) case _ => None } override def toString(): String = "scala.quoted.ValueOfExpr.Seq_delegate" diff --git a/library/src/scala/quoted/Values.scala b/library/src/scala/quoted/Values.scala new file mode 100644 index 000000000000..d60c5200b8a4 --- /dev/null +++ b/library/src/scala/quoted/Values.scala @@ -0,0 +1,25 @@ +package scala.quoted + +/** Value expressions */ +object Values { + + /** Matches literal sequence of literal constant value expressions and return a sequence of values. + * + * Usage: + * ```scala + * inline def sum(args: Int*): Int = ${ sumExpr('args) } + * def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match + * case Varargs(Values(args)) => + * // args: Seq[Int] + * ... + * } + * ``` + */ + def unapply[T](exprs: Seq[Expr[T]])(using valueOf: ValueOfExpr[T], qctx: QuoteContext): Option[Seq[T]] = + exprs.foldRight(Option(List.empty[T])) { (elem, acc) => + (elem, acc) match { + case (Value(value), Some(lst)) => Some(value :: lst) + case (_, _) => None + } + } +} diff --git a/library/src/scala/quoted/matching/ConstSeq.scala b/library/src/scala/quoted/matching/ConstSeq.scala index 715ae5be62d8..cd3ba8ea3a02 100644 --- a/library/src/scala/quoted/matching/ConstSeq.scala +++ b/library/src/scala/quoted/matching/ConstSeq.scala @@ -20,7 +20,7 @@ object ConstSeq { def unapply[T](expr: Expr[Seq[T]])(using qctx: QuoteContext): Option[Seq[T]] = import scala.quoted.Const expr match - case Varargs(Const(elems)) => Some(elems) + case Varargs(Consts(elems)) => Some(elems) case _ => None } diff --git a/library/src/scala/quoted/matching/ValueSeq.scala b/library/src/scala/quoted/matching/ValueSeq.scala index 31195f0dca1f..f7f801eec710 100644 --- a/library/src/scala/quoted/matching/ValueSeq.scala +++ b/library/src/scala/quoted/matching/ValueSeq.scala @@ -20,7 +20,7 @@ object ValueSeq { def unapply[T](expr: Expr[Seq[T]])(using valueOf: ValueOfExpr[T], qctx: QuoteContext): Option[Seq[T]] = import scala.quoted.Const expr match - case Varargs(Value(elems)) => Some(elems) + case Varargs(Values(elems)) => Some(elems) case _ => None } diff --git a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala index 9a4dda0f2a39..079cdebc51ab 100644 --- a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala +++ b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala @@ -8,7 +8,7 @@ object Macros { private def impl(self: Expr[StringContext], args: Expr[Seq[String]])(using QuoteContext): Expr[String] = { self match { - case '{ StringContext(${Varargs(Const(parts))}: _*) } => + case '{ StringContext(${Varargs(Consts(parts))}: _*) } => val upprerParts: List[String] = parts.toList.map(_.toUpperCase) val upprerPartsExpr: Expr[List[String]] = Expr.ofList(upprerParts.map(Expr(_))) '{ StringContext($upprerPartsExpr: _*).s($args: _*) } diff --git a/tests/run-macros/quoted-matching-docs/Macro_1.scala b/tests/run-macros/quoted-matching-docs/Macro_1.scala index c59156ce3b90..6aaade5c99bc 100644 --- a/tests/run-macros/quoted-matching-docs/Macro_1.scala +++ b/tests/run-macros/quoted-matching-docs/Macro_1.scala @@ -12,7 +12,7 @@ private def sumExprShow(argsExpr: Expr[Seq[Int]]) (using QuoteContext): Expr[Str private def sumExpr(argsExpr: Expr[Seq[Int]])(using qctx: QuoteContext) : Expr[Int] = { import qctx.tasty.{given _, _} UnsafeExpr.underlyingArgument(argsExpr) match { - case Varargs(Const(args)) => // args is of type Seq[Int] + case Varargs(Consts(args)) => // args is of type Seq[Int] Expr(args.sum) // precompute result of sum case Varargs(argExprs) => // argExprs is of type Seq[Expr[Int]] val staticSum: Int = argExprs.map { From 7d86a210aec2b9e867d17e05157e6f63abf4e4bd Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Mar 2020 15:01:27 +0100 Subject: [PATCH 9/9] Apply suggestions from code review Co-Authored-By: Fengyun Liu --- library/src/scala/quoted/Const.scala | 2 +- library/src/scala/quoted/Consts.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/src/scala/quoted/Const.scala b/library/src/scala/quoted/Const.scala index 5067c78918b8..bf38d07fcae5 100644 --- a/library/src/scala/quoted/Const.scala +++ b/library/src/scala/quoted/Const.scala @@ -1,6 +1,6 @@ package scala.quoted -/** MLiteral constant values */ +/** Literal constant values */ object Const { /** Matches expressions containing literal constant values and extracts the value. diff --git a/library/src/scala/quoted/Consts.scala b/library/src/scala/quoted/Consts.scala index 6955c435379e..46db54f52f53 100644 --- a/library/src/scala/quoted/Consts.scala +++ b/library/src/scala/quoted/Consts.scala @@ -1,6 +1,6 @@ package scala.quoted -/** MLiteral constant values */ +/** Literal constant values */ object Consts { /** Matches literal sequence of literal constant value expressions and return a sequence of values.