diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 7d56751dff4e..0acca1b4013b 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -40,9 +40,4 @@ class Reflection(val kernel: Kernel) def typeChecks(code: String)(implicit ctx: Context): Boolean = kernel.typeChecks(code)(ctx) } - // TODO integrate with TreeUtils - val util: reflect.utils.TreeUtils { val reflect: self.type } = new reflect.utils.TreeUtils { - val reflect: self.type = self - } - } diff --git a/library/src/scala/tasty/reflect/TreeUtils.scala b/library/src/scala/tasty/reflect/TreeUtils.scala index 8f7f88235586..5220d25c55e5 100644 --- a/library/src/scala/tasty/reflect/TreeUtils.scala +++ b/library/src/scala/tasty/reflect/TreeUtils.scala @@ -6,7 +6,7 @@ trait TreeUtils extends Core with PatternOps with SymbolOps - with TreeOps { + with TreeOps { self: Reflection => abstract class TreeAccumulator[X] { @@ -283,4 +283,29 @@ trait TreeUtils } + /** Bind the `rhs` to a `val` and use it in `body` */ + def let(rhs: Term)(body: Ident => Term): Term = { + import scala.quoted.QuoteContext + delegate for QuoteContext = new QuoteContext(this) + type T // TODO probably it is better to use the Sealed contruct rather than let the user create their own existential type + implicit val rhsTpe: quoted.Type[T] = rhs.tpe.seal.asInstanceOf[quoted.Type[T]] + val rhsExpr = rhs.seal.cast[T] + val expr = '{ + val x = $rhsExpr + ${ + val id = ('x).unseal.asInstanceOf[Ident] + body(id).seal + } + } + expr.unseal + } + + /** Bind the given `terms` to names and use them in the `body` */ + def lets(terms: List[Term])(body: List[Term] => Term): Term = { + def rec(xs: List[Term], acc: List[Term]): Term = xs match { + case Nil => body(acc) + case x :: xs => let(x) { (x: Term) => rec(xs, x :: acc) } + } + rec(terms, Nil) + } } diff --git a/library/src/scala/tasty/reflect/utils/TreeUtils.scala b/library/src/scala/tasty/reflect/utils/TreeUtils.scala deleted file mode 100644 index 89e67483563f..000000000000 --- a/library/src/scala/tasty/reflect/utils/TreeUtils.scala +++ /dev/null @@ -1,35 +0,0 @@ -package scala.tasty -package reflect.utils - -import scala.quoted._ - -trait TreeUtils { - - val reflect: Reflection - import reflect._ - - /** Bind the `rhs` to a `val` and use it in `body` */ - def let(rhs: Term)(body: Ident => Term): Term = { - delegate for QuoteContext = new QuoteContext(reflect) - type T // TODO probably it is better to use the Sealed contruct rather than let the user create their own existential type - implicit val rhsTpe: quoted.Type[T] = rhs.tpe.seal.asInstanceOf[quoted.Type[T]] - val rhsExpr = rhs.seal.cast[T] - val expr = '{ - val x = $rhsExpr - ${ - val id = ('x).unseal.asInstanceOf[Ident] - body(id).seal - } - } - expr.unseal - } - - /** Bind the given `terms` to names and use them in the `body` */ - def lets(terms: List[Term])(body: List[Term] => Term): Term = { - def rec(xs: List[Term], acc: List[Term]): Term = xs match { - case Nil => body(acc) - case x :: xs => let(x) { (x: Term) => rec(xs, x :: acc) } - } - rec(terms, Nil) - } -} diff --git a/tests/run-with-compiler/tasty-unsafe-let/quoted_1.scala b/tests/run-with-compiler/tasty-unsafe-let/quoted_1.scala index 7a3ccb9f3cde..ede72553b75d 100644 --- a/tests/run-with-compiler/tasty-unsafe-let/quoted_1.scala +++ b/tests/run-with-compiler/tasty-unsafe-let/quoted_1.scala @@ -10,7 +10,7 @@ object Macros { val rhsTerm = rhs.unseal - import qctx.tasty.util.{let => letTerm} + import qctx.tasty.{let => letTerm} letTerm(rhsTerm) { rhsId => body(rhsId.seal.asInstanceOf[Expr[T]]).unseal // Dangerous uncheked cast! }.seal.cast[Unit]