Skip to content

Remove quoted.Const.unapply #10516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/docs/reference/metaprogramming/macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -634,15 +634,15 @@ It is possible to deconstruct or extract values out of `Expr` using pattern matc

* `scala.quoted.Expr`/`scala.quoted.Exprs`: matches an expression of a value (or list of values) and returns the value (or list of values).
* `scala.quoted.Const`/`scala.quoted.Consts`: Same as `Expr`/`Exprs` but only works on primitive values.
* `scala.quoted.Varargs`: matches an explicit sequence of expressions and returns them. These sequences are useful to get individual `Expr[T]` out of a varargs expression of type `Expr[Seq[T]]`.
* `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 Quotes): Expr[Int] = argsExpr match {
case Varargs(args @ Exprs(argValues)) =>
// args is of type Seq[Expr[Int]]
case Varargs(argExprs @ Exprs(argValues)) =>
// argExprs is of type Seq[Expr[Int]]
// argValues is of type Seq[Int]
Expr(argValues.sum) // precompute result of sum
case Varargs(argExprs) => // argExprs is of type Seq[Expr[Int]]
Expand Down
2 changes: 1 addition & 1 deletion library/src-bootstrapped/scala/quoted/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ object Expr {
Block(statements.map(Term.of), Term.of(expr)).asExpr.asInstanceOf[Expr[T]]
}

/** Creates an expression that will construct the value `x` */
/** Lift a value into an expression containing the construction of that value */
def apply[T](x: T)(using ToExpr[T])(using Quotes): Expr[T] =
scala.Predef.summon[ToExpr[T]].apply(x)

Expand Down
4 changes: 2 additions & 2 deletions library/src-bootstrapped/scala/quoted/FromExpr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ object FromExpr {
*/
given StringContextFromExpr: FromExpr[StringContext] with {
def unapply(x: Expr[StringContext])(using Quotes) = x match {
case '{ new StringContext(${Varargs(Consts(args))}: _*) } => Some(StringContext(args: _*))
case '{ StringContext(${Varargs(Consts(args))}: _*) } => Some(StringContext(args: _*))
case '{ new StringContext(${Varargs(Exprs(args))}: _*) } => Some(StringContext(args: _*))
case '{ StringContext(${Varargs(Exprs(args))}: _*) } => Some(StringContext(args: _*))
case _ => None
}
}
Expand Down
4 changes: 4 additions & 0 deletions library/src-non-bootstrapped/scala/quoted/Expr.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
package scala.quoted

abstract class Expr[+T] private[scala]

object Expr:
def apply[T](x: T)(using ToExpr[T])(using Quotes): Expr[T] = ???
def unapply[T](x: Expr[T])(using FromExpr[T])(using Quotes): Option[T] = ???
4 changes: 4 additions & 0 deletions library/src-non-bootstrapped/scala/quoted/ToExpr.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package scala.quoted

trait ToExpr[T]:
def apply(x: T)(using Quotes): T
38 changes: 0 additions & 38 deletions library/src/scala/quoted/Const.scala

This file was deleted.

28 changes: 0 additions & 28 deletions library/src/scala/quoted/Consts.scala

This file was deleted.

2 changes: 1 addition & 1 deletion library/src/scala/quoted/Exprs.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package scala.quoted

/** Value expressions */
object Exprs:

/** Matches literal sequence of literal constant value expressions and return a sequence of values.
Expand All @@ -9,7 +10,6 @@ object Exprs:
* inline def sum(args: Int*): Int = ${ sumExpr('args) }
* def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match
* case Varargs(Exprs(args)) =>
* case Varargs(Exprs(args)) =>
* // args: Seq[Int]
* ...
* }
Expand Down
2 changes: 1 addition & 1 deletion tests/bench/string-interpolation-macro/Macro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ object Macro {
var res: Expr[String] = null
for _ <- 0 to 5_000 do
(strCtxExpr, argsExpr) match {
case ('{ StringContext(${Varargs(Consts(parts))}: _*) }, Varargs(Consts(args))) =>
case ('{ StringContext(${Varargs(Exprs(parts))}: _*) }, Varargs(Exprs(args))) =>
res = Expr(StringContext(parts: _*).s(args: _*))
case _ => ???
}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/i6432/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ object Macro {
import quotes.reflect._
sc match {
case '{ StringContext(${Varargs(parts)}: _*) } =>
for (part @ Const(s) <- parts)
for (part @ Expr(s) <- parts)
report.error(s, Term.of(part).pos)
}
'{}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/i6432b/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ object Macro {
import quotes.reflect._
sc match {
case '{ StringContext(${Varargs(parts)}: _*) } =>
for (part @ Const(s) <- parts)
for (part @ Expr(s) <- parts)
report.error(s, Term.of(part).pos)
}
'{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object E {

implicit def ev1[T: Type]: FromExpr[E[T]] = new FromExpr {
def unapply(x: Expr[E[T]])(using Quotes) = x match {
case '{ I(${Const(n)}) } => Some(I(n).asInstanceOf[E[T]])
case '{ I(${Expr(n)}) } => Some(I(n).asInstanceOf[E[T]])
case '{ Plus[T](${Value(x)}, ${Value(y)})(using $op) } if op.matches('{Plus2.IPlus}) => Some(Plus(x, y)(using Plus2.IPlus.asInstanceOf[Plus2[T]]).asInstanceOf[E[T]])
case _ => None
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import scala.quoted._
import Even._

object EvenFromDigitsImpl:
def apply(digits: Expr[String])(using Quotes): Expr[Even] = digits match {
case Const(ds) =>
def apply(digits: Expr[String])(using Quotes): Expr[Even] = digits.unlift match {
case Some(ds) =>
val ev =
try evenFromDigits(ds)
catch {
Expand Down
2 changes: 1 addition & 1 deletion tests/run-macros/expr-map-1/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ private def stringRewriter(e: Expr[Any])(using Quotes): Expr[Any] =
private object StringRewriter extends ExprMap {

def transform[T](e: Expr[T])(using Type[T])(using Quotes): Expr[T] = e match
case Const(s: String) =>
case '{ ${Expr(s)}: String } =>
Expr(s.reverse) match
case '{ $x: T } => x
case _ => e // e had a singlton String type
Expand Down
4 changes: 2 additions & 2 deletions tests/run-macros/flops-rewrite-2/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ private def rewriteMacro[T: Type](x: Expr[T])(using Quotes): Expr[T] = {
case (_, Some(_)) => '{ $y * $x }
case _ => '{ $x * $y }
}
case '{ power(${Const(x)}, ${Const(y)}) } =>
case '{ power(${Expr(x)}, ${Expr(y)}) } =>
Expr(power(x, y))
case '{ power($x, ${Const(y)}) } =>
case '{ power($x, ${Expr(y)}) } =>
if y == 0 then '{1}
else '{ times($x, power($x, ${Expr(y-1)})) }
}),
Expand Down
4 changes: 2 additions & 2 deletions tests/run-macros/flops-rewrite-3/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ private def rewriteMacro[T: Type](x: Expr[T])(using Quotes): Expr[T] = {
case (_, Some(_)) => '{ $y * $x }
case _ => '{ $x * $y }
}
case '{ power(${Const(x)}, ${Const(y)}) } =>
case '{ power(${Expr(x)}, ${Expr(y)}) } =>
Expr(power(x, y))
case '{ power($x, ${Const(y)}) } =>
case '{ power($x, ${Expr(y)}) } =>
if y == 0 then '{1}
else '{ times($x, power($x, ${Expr(y-1)})) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ object E {

implicit def ev1[T: Type]: FromExpr[E[T]] = new FromExpr { // TODO use type class derivation
def unapply(x: Expr[E[T]])(using Quotes) = (x match {
case '{ I(${Const(n)}) } => Some(I(n))
case '{ D(${Const(n)}) } => Some(D(n))
case '{ I(${Expr(n)}) } => Some(I(n))
case '{ D(${Expr(n)}) } => Some(D(n))
case '{ Plus[Int](${Value(x)}, ${Value(y)})(using $op) } => Some(Plus(x, y)(using Plus2.IPlus))
case '{ Plus[Double](${Value(x)}, ${Value(y)})(using $op) } => Some(Plus(x, y)(using Plus2.DPlus))
case '{ Times[Int](${Value(x)}, ${Value(y)})(using $op) } => Some(Times(x, y)(using Times2.ITimes))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ object Macros {

private def impl(self: Expr[StringContext], args: Expr[Seq[String]])(using Quotes): Expr[String] = {
self match {
case '{ StringContext(${Varargs(Consts(parts))}: _*) } =>
case '{ StringContext(${Varargs(Exprs(parts))}: _*) } =>
val upprerParts: List[String] = parts.toList.map(_.toUpperCase)
val upprerPartsExpr: Expr[List[String]] = Expr.ofList(upprerParts.map(Expr(_)))
'{ StringContext($upprerPartsExpr: _*).s($args: _*) }
Expand Down
2 changes: 1 addition & 1 deletion tests/run-macros/quote-matcher-symantics-1/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object Macros {

def lift(e: Expr[DSL]): Expr[T] = e match {

case '{ LitDSL(${ Const(c) }) } =>
case '{ LitDSL(${ Expr(c) }) } =>
'{ $sym.value(${Expr(c)}) }

case '{ ($x: DSL) + ($y: DSL) } =>
Expand Down
4 changes: 2 additions & 2 deletions tests/run-macros/quote-matcher-symantics-2/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ object Macros {

def lift(e: Expr[DSL])(implicit env: Map[Int, Expr[T]]): Expr[T] = e match {

case '{ LitDSL(${Const(c)}) } => sym.value(c)
case '{ LitDSL(${Expr(c)}) } => sym.value(c)

case '{ ($x: DSL) + ($y: DSL) } => sym.plus(lift(x), lift(y))

Expand All @@ -35,7 +35,7 @@ object Macros {
lift(close(body1)(nEnvVar))(env + (i -> lift(value)))
}

case '{ envVar(${Const(i)}) } => env(i)
case '{ envVar(${Expr(i)}) } => env(i)

case _ =>
import quotes.reflect._
Expand Down
6 changes: 3 additions & 3 deletions tests/run-macros/quote-matcher-symantics-3/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ object Macros {
object FromEnv {
def unapply[T](e: Expr[Any])(using env: Env): Option[Expr[R[T]]] =
e match
case '{envVar[t](${Const(id)})} =>
case '{envVar[t](${Expr(id)})} =>
env.get(id).asInstanceOf[Option[Expr[R[T]]]] // We can only add binds that have the same type as the refs
case _ =>
None
}

def lift[T: Type](e: Expr[T])(using env: Env): Expr[R[T]] = ((e: Expr[Any]) match {
case Const(e: Int) => '{ $sym.int(${Expr(e)}).asInstanceOf[R[T]] }
case Const(e: Boolean) => '{ $sym.bool(${Expr(e)}).asInstanceOf[R[T]] }
case '{ ${Expr(e)}: Int } => '{ $sym.int(${Expr(e)}).asInstanceOf[R[T]] }
case '{ ${Expr(e)}: Boolean } => '{ $sym.bool(${Expr(e)}).asInstanceOf[R[T]] }

case '{ ($x: Int) + ($y: Int) } =>
'{ $sym.add(${lift(x)}, ${lift(y)}).asInstanceOf[R[T]] }
Expand Down
2 changes: 1 addition & 1 deletion tests/run-macros/quoted-matching-docs/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ private def sumExprShow(argsExpr: Expr[Seq[Int]]) (using Quotes): Expr[String] =

private def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes) : Expr[Int] = {
UnsafeExpr.underlyingArgument(argsExpr) match {
case Varargs(Consts(args)) => // args is of type Seq[Int]
case Varargs(Exprs(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(_.value.getOrElse(0)).sum
Expand Down
1 change: 0 additions & 1 deletion tests/run-macros/tasty-extractors-constants-1.check
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@
4
abc
null
OK
8 changes: 4 additions & 4 deletions tests/run-macros/tasty-extractors-constants-1/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ object Macros {
val buff = new StringBuilder
def stagedPrintln(x: Any): Unit = buff append java.util.Objects.toString(x) append "\n"

Expr(3) match { case Const(n) => stagedPrintln(n) }
'{4} match { case Const(n) => stagedPrintln(n) }
'{"abc"} match { case Const(n) => stagedPrintln(n) }
Expr(3) match { case Expr(n) => stagedPrintln(n) }
'{4} match { case Expr(n) => stagedPrintln(n) }
'{"abc"} match { case Expr(n) => stagedPrintln(n) }
'{null} match { case '{null} => stagedPrintln(null) }

'{new Object} match { case Const(n) => println(n); case _ => stagedPrintln("OK") }
// '{new Object} match { case Expr(n) => println(n); case _ => stagedPrintln("OK") }

'{print(${Expr(buff.result())})}
}
Expand Down