Skip to content

Commit 822be89

Browse files
committed
Add quoted.{Lifted,Unlifted}
As a dual of lifting (Expr.apply), unliftings should be placed consistent namespaces. * Move `Values.unapply to `Unlifted.unapply` * Move `Value.unapply` to `Unlifted.unapply(Seq)` * Move `Expr.unapply` to `Lifted.unapply`
1 parent 800251d commit 822be89

File tree

101 files changed

+347
-340
lines changed

Some content is hidden

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

101 files changed

+347
-340
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ implementation method `fromDigitsImpl`. Here is its definition:
206206
case Const(ds) =>
207207
try {
208208
val BigFloat(m, e) = apply(ds)
209-
'{BigFloat(${Expr(m)}, ${Expr(e)})}
209+
'{BigFloat(${Lifted(m)}, ${Lifted(e)})}
210210
}
211211
catch {
212212
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 qctx: QuoteContext) as 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(Lifted(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(${Lifted(index)})}
56+
val e2 = '{$y.asInstanceOf[Product].productElement(${Lifted(index)})}
5757

5858
'{ $acc && $elem.asInstanceOf[Eq[Any]].eqv($e1, $e2) }
5959
}
@@ -184,10 +184,10 @@ object Eq {
184184
case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = $elementTypes }} =>
185185
val elemInstances = summonAll(elementTypes)
186186
val eqProductBody: (Expr[T], Expr[T]) => Expr[Boolean] = (x, y) => {
187-
elemInstances.zipWithIndex.foldLeft(Expr(true: Boolean)) {
187+
elemInstances.zipWithIndex.foldLeft(Lifted(true: Boolean)) {
188188
case (acc, (elem, index)) =>
189-
val e1 = '{$x.asInstanceOf[Product].productElement(${Expr(index)})}
190-
val e2 = '{$y.asInstanceOf[Product].productElement(${Expr(index)})}
189+
val e1 = '{$x.asInstanceOf[Product].productElement(${Lifted(index)})}
190+
val e2 = '{$y.asInstanceOf[Product].productElement(${Lifted(index)})}
191191

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

docs/docs/reference/metaprogramming/macros.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ import scala.quoted.{given _, _}
225225

226226
def compile(e: Exp, env: Map[String, Expr[Int]])(using QuoteContext): Expr[Int] = e match {
227227
case Num(n) =>
228-
Expr(n)
228+
Lifted(n)
229229
case Plus(e1, e2) =>
230230
'{ ${ compile(e1, env) } + ${ compile(e2, env) } }
231231
case Var(x) =>
@@ -238,19 +238,19 @@ Running `compile(letExp, Map())` would yield the following Scala code:
238238
```scala
239239
'{ val y = 3; (2 + y) + 4 }
240240
```
241-
The body of the first clause, `case Num(n) => Expr(n)`, looks suspicious. `n`
242-
is declared as an `Int`, yet it is converted to an `Expr[Int]` with `Expr()`.
241+
The body of the first clause, `case Num(n) => Lifted(n)`, looks suspicious. `n`
242+
is declared as an `Int`, yet it is converted to an `Expr[Int]` with `Lifted()`.
243243
Shouldn’t `n` be quoted? In fact this would not
244244
work since replacing `n` by `'n` in the clause would not be phase
245245
correct.
246246

247-
The `Expr.apply` method is defined in package `quoted`:
247+
The `Lifted.apply` method is defined in package `quoted`:
248248
```scala
249249
package quoted
250250

251-
object Expr {
251+
object Lifted {
252252
...
253-
def apply[T: Liftable](x: T)(using QuoteContext): Expr[T] = summon[Liftable[T]].toExpr(x)
253+
def apply[T](x: T)(using qctx: QuoteContext, lift: Liftable[T]): Expr[T] = lift.toExpr(x)
254254
...
255255
}
256256
```
@@ -291,7 +291,7 @@ a `List` is liftable if its element type is:
291291
```scala
292292
given [T: Liftable : Type] as Liftable[List[T]] {
293293
def toExpr(xs: List[T]) = xs match {
294-
case head :: tail => '{ ${ Expr(head) } :: ${ toExpr(tail) } }
294+
case head :: tail => '{ ${ Lifted(head) } :: ${ toExpr(tail) } }
295295
case Nil => '{ Nil: List[T] }
296296
}
297297
}
@@ -306,13 +306,13 @@ Using lifting, we can now give the missing definition of `showExpr` in the intro
306306
```scala
307307
def showExpr[T](expr: Expr[T])(using QuoteContext): Expr[String] = {
308308
val code: String = expr.show
309-
Expr(code)
309+
Lifted(code)
310310
}
311311
```
312312
That is, the `showExpr` method converts its `Expr` argument to a string (`code`), and lifts
313-
the result back to an `Expr[String]` using `Expr.apply`.
313+
the result back to an `Expr[String]` using `Lifted.apply`.
314314

315-
**Note**: Lifting `String` to `Expr[String]` using `Expr(code)` can be omitted by importing an implicit
315+
**Note**: Lifting `String` to `Expr[String]` using `Lifted(code)` can be omitted by importing an implicit
316316
conversion with `import scala.quoted.autolift.given`. The programmer is able to
317317
declutter slightly the code at the cost of readable _phase distinction_ between
318318
stages.
@@ -617,15 +617,15 @@ It is possible to deconstruct or extract values out of `Expr` using pattern matc
617617
`scala.quoted` contains objects that can help extracting values from `Expr`.
618618

619619
* `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).
620-
* `scala.quoted.Value`/`scala.quoted.Values`: matches an expression of a value (or list of values) and returns the value (or list of values).
620+
* `scala.quoted.Unlifted`: matches an expression of a value (or list of values) and returns the value (or list of values).
621621
* `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]]`.
622622

623623
These could be used in the following way to optimize any call to `sum` that has statically known values.
624624
```scala
625625
inline def sum(inline args: Int*): Int = ${ sumExpr('args) }
626626
private def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = argsExpr match {
627627
case Varargs(Consts(args)) => // args is of type Seq[Int]
628-
Expr(args.sum) // precompute result of sum
628+
Lifted(args.sum) // precompute result of sum
629629
case Varargs(argExprs) => // argExprs is of type Seq[Expr[Int]]
630630
val staticSum: Int = argExprs.map {
631631
case Const(arg) => arg
@@ -635,7 +635,7 @@ private def sumExpr(argsExpr: Expr[Seq[Int]])(using QuoteContext): Expr[Int] = a
635635
case Const(_) => false
636636
case arg => true
637637
}
638-
dynamicSum.foldLeft(Expr(staticSum))((acc, arg) => '{ $acc + $arg })
638+
dynamicSum.foldLeft(Lifted(staticSum))((acc, arg) => '{ $acc + $arg })
639639
case _ =>
640640
'{ $argsExpr.sum }
641641
}
@@ -658,7 +658,7 @@ def sum(args: Int*): Int = args.sum
658658
inline def optimize(arg: Int): Int = ${ optimizeExpr('arg) }
659659
private def optimizeExpr(body: Expr[Int])(using QuoteContext): Expr[Int] = body match {
660660
// Match a call to sum without any arguments
661-
case '{ sum() } => Expr(0)
661+
case '{ sum() } => Lifted(0)
662662
// Match a call to sum with an argument $n of type Int. n will be the Expr[Int] representing the argument.
663663
case '{ sum($n) } => n
664664
// Match a call to sum and extracts all its args in an `Expr[Seq[Int]]`
@@ -679,7 +679,7 @@ private def sumExpr(args1: Seq[Expr[Int]])(using QuoteContext): Expr[Int] = {
679679
case Const(_) => false
680680
case arg => true
681681
}
682-
dynamicSum.foldLeft(Expr(staticSum))((acc, arg) => '{ $acc + $arg })
682+
dynamicSum.foldLeft(Lifted(staticSum))((acc, arg) => '{ $acc + $arg })
683683
}
684684
```
685685

docs/docs/reference/metaprogramming/tasty-reflect.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ The method `qctx.tasty.Term.seal` provides a way to go back to a
6565
`quoted.Expr[Any]`. Note that the type is `Expr[Any]`. Consequently, the type
6666
must be set explicitly with a checked `cast` call. If the type does not conform
6767
to it an exception will be thrown. In the code above, we could have replaced
68-
`Expr(n)` by `xTree.seal.cast[Int]`.
68+
`Lifted(n)` by `xTree.seal.cast[Int]`.
6969

7070
### Obtaining the underlying argument
7171

library/src-bootstrapped/dotty/internal/StringContextMacro.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,6 @@ object StringContextMacro {
721721
}
722722

723723
// macro expansion
724-
'{(${Expr(parts.mkString)}).format(${argsExpr}: _*)}
724+
'{(${Lifted(parts.mkString)}).format(${argsExpr}: _*)}
725725
}
726726
}

library/src/scala/internal/quoted/showName.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package scala.internal.quoted
66
* Usage:
77
* ```scala
88
* def let(name: String)(value: Expr[Int])(in: Expr[Int] => Expr[Int]): Expr[Int] = '{
9-
* @showName(${Expr(name)})
9+
* @showName(${Lifted(name)})
1010
* val x = $value
1111
* ${ in('x) }
1212
* }

library/src/scala/quoted/Expr.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ object Expr {
9797
Block(statements.map(_.unseal), expr.unseal).seal.asInstanceOf[Expr[T]]
9898
}
9999

100-
/** Lift a value into an expression containing the construction of that value */
101-
def apply[T](x: T)(using qctx: QuoteContext, lift: Liftable[T]): Expr[T] = lift.toExpr(x)
100+
// /** Lift a value into an expression containing the construction of that value */
101+
// @deprecated("Use scala.quoted.Lifted", "0.23")
102+
// def apply[T](x: T)(using qctx: QuoteContext, lift: Liftable[T]): Expr[T] = Lifted(x)
102103

103104
/** Lifts this sequence of expressions into an expression of a sequence
104105
*

0 commit comments

Comments
 (0)