Skip to content

Commit ec9e8c0

Browse files
committed
Use Values to create and match value Exprs
* Replace `Expr.apply` with `Value.apply` * Replace `Expr.unapply` with `Value.unapply` * Replace `Exprs.unapply` with `Values.unapply` * Aligns with `expr.value` and `expr.valueOrError` * Deprecate old definitions in 3.0.0-M3 and remove them in 3.0.0-RC1 for simpler migration * Add back deprecated `Unlifted`, `unlift` and `unliftOrError` to help migration from 3.0.0-M2 to 3.0.0-M3
1 parent 07eda7c commit ec9e8c0

File tree

209 files changed

+822
-769
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

209 files changed

+822
-769
lines changed

community-build/src/scala/dotty/communitybuild/FieldsImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ object FieldsImpl:
1414
val projectsTree = Term.of(from)
1515
val symbols = TypeTree.of[V].symbol.memberMethods.filter(isProjectField)
1616
val selects = symbols.map(Select(projectsTree, _).asExprOf[T])
17-
'{ println(${Expr(retType.show)}); ${Varargs(selects)} }
17+
'{ println(${Value(retType.show)}); ${Varargs(selects)} }

docs/docs/reference/changed-features/numeric-literals.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ implementation method `fromDigitsImpl`. Here is its definition:
205205
case Some(ds) =>
206206
try {
207207
val BigFloat(m, e) = apply(ds)
208-
'{BigFloat(${Expr(m)}, ${Expr(e)})}
208+
'{BigFloat(${Value(m)}, ${Value(e)})}
209209
}
210210
catch {
211211
case ex: FromDigits.FromDigitsException =>

docs/docs/reference/contextual/derivation-macro.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ given derived[T: Type](using Quotes): Expr[Eq[T]] = {
5050
case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }} =>
5151
val elemInstances = summonAll[elementTypes]
5252
val eqProductBody: (Expr[T], Expr[T]) => Expr[Boolean] = (x, y) => {
53-
elemInstances.zipWithIndex.foldLeft(Expr(true: Boolean)) {
53+
elemInstances.zipWithIndex.foldLeft(Value(true: Boolean)) {
5454
case (acc, (elem, index)) =>
55-
val e1 = '{$x.asInstanceOf[Product].productElement(${Expr(index)})}
56-
val e2 = '{$y.asInstanceOf[Product].productElement(${Expr(index)})}
55+
val e1 = '{$x.asInstanceOf[Product].productElement(${Value(index)})}
56+
val e2 = '{$y.asInstanceOf[Product].productElement(${Value(index)})}
5757

5858
'{ $acc && $elem.asInstanceOf[Eq[Any]].eqv($e1, $e2) }
5959
}
@@ -185,10 +185,10 @@ object Eq {
185185
case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }} =>
186186
val elemInstances = summonAll[elementTypes]
187187
val eqProductBody: (Expr[T], Expr[T]) => Expr[Boolean] = (x, y) => {
188-
elemInstances.zipWithIndex.foldLeft(Expr(true: Boolean)) {
188+
elemInstances.zipWithIndex.foldLeft(Value(true: Boolean)) {
189189
case (acc, (elem, index)) =>
190-
val e1 = '{$x.asInstanceOf[Product].productElement(${Expr(index)})}
191-
val e2 = '{$y.asInstanceOf[Product].productElement(${Expr(index)})}
190+
val e1 = '{$x.asInstanceOf[Product].productElement(${Value(index)})}
191+
val e2 = '{$y.asInstanceOf[Product].productElement(${Value(index)})}
192192

193193
'{ $acc && $elem.asInstanceOf[Eq[Any]].eqv($e1, $e2) }
194194
}

docs/docs/reference/metaprogramming/macros.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ import scala.quoted._
246246

247247
def compile(e: Exp, env: Map[String, Expr[Int]])(using Quotes): Expr[Int] = e match {
248248
case Num(n) =>
249-
Expr(n)
249+
Value(n)
250250
case Plus(e1, e2) =>
251251
'{ ${ compile(e1, env) } + ${ compile(e2, env) } }
252252
case Var(x) =>
@@ -259,8 +259,8 @@ Running `compile(letExp, Map())` would yield the following Scala code:
259259
```scala
260260
'{ val y = 3; (2 + y) + 4 }
261261
```
262-
The body of the first clause, `case Num(n) => Expr(n)`, looks suspicious. `n`
263-
is declared as an `Int`, yet it is converted to an `Expr[Int]` with `Expr()`.
262+
The body of the first clause, `case Num(n) => Value(n)`, looks suspicious. `n`
263+
is declared as an `Int`, yet it is converted to an `Expr[Int]` with `Value()`.
264264
Shouldn’t `n` be quoted? In fact this would not
265265
work since replacing `n` by `'n` in the clause would not be phase
266266
correct.
@@ -312,7 +312,7 @@ a `List` is liftable if its element type is:
312312
```scala
313313
given [T: ToExpr : Type]: ToExpr[List[T]] with
314314
def toExpr(xs: List[T]) = xs match {
315-
case head :: tail => '{ ${ Expr(head) } :: ${ toExpr(tail) } }
315+
case head :: tail => '{ ${ Value(head) } :: ${ toExpr(tail) } }
316316
case Nil => '{ Nil: List[T] }
317317
}
318318
```
@@ -326,7 +326,7 @@ Using lifting, we can now give the missing definition of `showExpr` in the intro
326326
```scala
327327
def showExpr[T](expr: Expr[T])(using Quotes): Expr[String] = {
328328
val code: String = expr.show
329-
Expr(code)
329+
Value(code)
330330
}
331331
```
332332
That is, the `showExpr` method converts its `Expr` argument to a string (`code`), and lifts
@@ -375,7 +375,7 @@ object Macros {
375375
${ assertImpl('expr) }
376376

377377
def assertImpl(expr: Expr[Boolean])(using Quotes) =
378-
val failMsg: Expr[String] = Expr("failed assertion: " + expr.show)
378+
val failMsg: Expr[String] = Value("failed assertion: " + expr.show)
379379
'{ if !($expr) then throw new AssertionError($failMsg) }
380380
}
381381

@@ -641,14 +641,14 @@ These could be used in the following way to optimize any call to `sum` that has
641641
```scala
642642
inline def sum(inline args: Int*): Int = ${ sumExpr('args) }
643643
private def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match {
644-
case Varargs(args @ Exprs(argValues)) =>
644+
case Varargs(args @ Values(argValues)) =>
645645
// args is of type Seq[Expr[Int]]
646646
// argValues is of type Seq[Int]
647-
Expr(argValues.sum) // precompute result of sum
647+
Value(argValues.sum) // precompute result of sum
648648
case Varargs(argExprs) => // argExprs is of type Seq[Expr[Int]]
649649
val staticSum: Int = argExprs.map(_.value.getOrElse(0))
650650
val dynamicSum: Seq[Expr[Int]] = argExprs.filter(_.value.isEmpty)
651-
dynamicSum.foldLeft(Expr(staticSum))((acc, arg) => '{ $acc + $arg })
651+
dynamicSum.foldLeft(Value(staticSum))((acc, arg) => '{ $acc + $arg })
652652
case _ =>
653653
'{ $argsExpr.sum }
654654
}
@@ -671,7 +671,7 @@ def sum(args: Int*): Int = args.sum
671671
inline def optimize(inline arg: Int): Int = ${ optimizeExpr('arg) }
672672
private def optimizeExpr(body: Expr[Int])(using Quotes): Expr[Int] = body match {
673673
// Match a call to sum without any arguments
674-
case '{ sum() } => Expr(0)
674+
case '{ sum() } => Value(0)
675675
// Match a call to sum with an argument $n of type Int. n will be the Expr[Int] representing the argument.
676676
case '{ sum($n) } => n
677677
// Match a call to sum and extracts all its args in an `Expr[Seq[Int]]`
@@ -686,7 +686,7 @@ private def sumExpr(args1: Seq[Expr[Int]])(using Quotes): Expr[Int] = {
686686
val args2 = args1.flatMap(flatSumArgs)
687687
val staticSum: Int = args2.map(_.value.getOrElse(0)).sum
688688
val dynamicSum: Seq[Expr[Int]] = args2.filter(_.value.isEmpty)
689-
dynamicSum.foldLeft(Expr(staticSum))((acc, arg) => '{ $acc + $arg })
689+
dynamicSum.foldLeft(Value(staticSum))((acc, arg) => '{ $acc + $arg })
690690
}
691691
```
692692

@@ -762,7 +762,7 @@ private def evalExpr(e: Expr[Int])(using Quotes): Expr[Int] = {
762762
evalExpr(Expr.betaReduce(body)(evalExpr(x)))
763763
case '{ ($x: Int) * ($y: Int) } =>
764764
(x.value, y.value) match
765-
case (Some(a), Some(b)) => Expr(a * b)
765+
case (Some(a), Some(b)) => Value(a * b)
766766
case _ => e
767767
case _ => e
768768
}

library/src-bootstrapped/scala/quoted/Expr.scala

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,23 @@ object Expr {
3333
}
3434

3535
/** Creates an expression that will construct the value `x` */
36+
@deprecated("Use `scala.quoted.Value.apply` instead. This will be removed in 3.0.0-RC1", "3.0.0-M3")
3637
def apply[T](x: T)(using ToExpr[T])(using Quotes): Expr[T] =
3738
scala.Predef.summon[ToExpr[T]].apply(x)
3839

3940
/** Get `Some` of a copy of the value if the expression contains a literal constant or constructor of `T`.
40-
* Otherwise returns `None`.
41-
*
42-
* Usage:
43-
* ```
44-
* case '{ ... ${expr @ Expr(value)}: T ...} =>
45-
* // expr: Expr[T]
46-
* // value: T
47-
* ```
48-
*
49-
* To directly get the value of an expression `expr: Expr[T]` consider using `expr.value`/`expr.valueOrError` insead.
50-
*/
41+
* Otherwise returns `None`.
42+
*
43+
* Usage:
44+
* ```
45+
* case '{ ... ${expr @ Expr(value)}: T ...} =>
46+
* // expr: Expr[T]
47+
* // value: T
48+
* ```
49+
*
50+
* To directly get the value of an expression `expr: Expr[T]` consider using `expr.value`/`expr.valueOrError` insead.
51+
*/
52+
@deprecated("Use `scala.quoted.Value.unapply` instead. This will be removed in 3.0.0-RC1", "3.0.0-M3")
5153
def unapply[T](x: Expr[T])(using FromExpr[T])(using Quotes): Option[T] =
5254
scala.Predef.summon[FromExpr[T]].unapply(x)
5355

@@ -70,7 +72,7 @@ object Expr {
7072
* `'{ List($e1, $e2, ...) }` typed as an `Expr[List[T]]`
7173
*/
7274
def ofList[T](xs: Seq[Expr[T]])(using Type[T])(using Quotes): Expr[List[T]] =
73-
if (xs.isEmpty) Expr(Nil) else '{ List(${Varargs(xs)}: _*) }
75+
if (xs.isEmpty) Value(Nil) else '{ List(${Varargs(xs)}: _*) }
7476

7577
/** Creates an expression that will construct a copy of this tuple
7678
*

0 commit comments

Comments
 (0)