Skip to content

Commit e32da05

Browse files
committed
Add isExprOf and toExprOf to allow safe Expr casting
Currently we can only call `asExprOf` but have no simple way to check that the expression is in fact of some type.
1 parent c20be38 commit e32da05

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,26 @@ abstract class Expr[+T] private[scala] {
2525
/** Checked cast to a `quoted.Expr[U]` */
2626
def cast[U](using tp: scala.quoted.Type[U])(using qctx: QuoteContext): scala.quoted.Expr[U] = asExprOf[U]
2727

28+
/** Checks is the `quoted.Expr[?]` is valid expression of type `X` */
29+
def isExprOf[X](using tp: scala.quoted.Type[X])(using qctx: QuoteContext): Boolean =
30+
this.unseal.tpe <:< tp.unseal.tpe
31+
32+
/** Convert this to an `Some[quoted.Expr[X]]` if this expression is a valid expression of type `X`.
33+
* Otherwise returns None.
34+
*/
35+
def toExprOf[X](using tp: scala.quoted.Type[X])(using qctx: QuoteContext): Option[scala.quoted.Expr[X]] =
36+
if isExprOf[X] then Some(this.asInstanceOf[scala.quoted.Expr[X]])
37+
else None
38+
2839
/** Convert this to an `quoted.Expr[X]` if this expression is a valid expression of type `X` or throws */
2940
def asExprOf[X](using tp: scala.quoted.Type[X])(using qctx: QuoteContext): scala.quoted.Expr[X] = {
30-
val tree = this.unseal
31-
val expectedType = tp.unseal.tpe
32-
if (tree.tpe <:< expectedType)
41+
if isExprOf[X] then
3342
this.asInstanceOf[scala.quoted.Expr[X]]
3443
else
35-
throw new scala.tasty.reflect.ExprCastError(
36-
s"""Expr: ${tree.show}
37-
|of type: ${tree.tpe.show}
38-
|did not conform to type: ${expectedType.show}
44+
throw new tasty.reflect.ExprCastError(
45+
s"""Expr: ${this.show}
46+
|of type: ${this.unseal.tpe.show}
47+
|did not conform to type: ${tp.unseal.tpe.show}
3948
|""".stripMargin
4049
)
4150
}

0 commit comments

Comments
 (0)