Skip to content

Commit 7ae7f1f

Browse files
Merge pull request #9513 from dotty-staging/fix-unliftable
Fix Expr.{unlift, unliftOrError} and add missing Unliftables
2 parents 1dd94b1 + 9cba8f5 commit 7ae7f1f

File tree

6 files changed

+352
-80
lines changed

6 files changed

+352
-80
lines changed

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

+21-16
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,6 @@ abstract class Expr[+T] private[scala] {
1313
def showWith(syntaxHighlight: SyntaxHighlight)(using qctx: QuoteContext): String =
1414
this.unseal.showWith(syntaxHighlight)
1515

16-
/** Return the unlifted value of this expression.
17-
*
18-
* Returns `None` if the expression does not contain a value or contains side effects.
19-
* Otherwise returns the `Some` of the value.
20-
*/
21-
final def unlift[U >: T](using qctx: QuoteContext, unlift: Unliftable[U]): Option[U] =
22-
unlift(this)
23-
24-
/** Return the unlifted value of this expression.
25-
*
26-
* Emits an error and throws if the expression does not contain a value or contains side effects.
27-
* Otherwise returns the value.
28-
*/
29-
final def unliftOrError[U >: T](using qctx: QuoteContext, unlift: Unliftable[U]): U =
30-
unlift(this).getOrElse(report.throwError(s"Expected a known value. \n\nThe value of: $show\ncould not be unlifted using $unlift", this))
31-
3216
/** Pattern matches `this` against `that`. Effectively performing a deep equality check.
3317
* It does the equivalent of
3418
* ```
@@ -64,6 +48,27 @@ abstract class Expr[+T] private[scala] {
6448

6549
object Expr {
6650

51+
extension [T](expr: Expr[T]):
52+
/** Return the unlifted value of this expression.
53+
*
54+
* Returns `None` if the expression does not contain a value or contains side effects.
55+
* Otherwise returns the `Some` of the value.
56+
*/
57+
def unlift(using qctx: QuoteContext, unlift: Unliftable[T]): Option[T] =
58+
unlift(expr)
59+
60+
/** Return the unlifted value of this expression.
61+
*
62+
* Emits an error and throws if the expression does not contain a value or contains side effects.
63+
* Otherwise returns the value.
64+
*/
65+
def unliftOrError(using qctx: QuoteContext, unlift: Unliftable[T]): T =
66+
def reportError =
67+
val msg = s"Expected a known value. \n\nThe value of: ${expr.show}\ncould not be unlifted using $unlift"
68+
report.throwError(msg, expr)
69+
unlift(expr).getOrElse(reportError)
70+
end extension
71+
6772
/** `e.betaReduce` returns an expression that is functionally equivalent to `e`,
6873
* however if `e` is of the form `((y1, ..., yn) => e2)(x1, ..., xn)`
6974
* then it optimizes this the top most call by returning the result of beta-reducing the application.

0 commit comments

Comments
 (0)