diff --git a/library/src-3.x/scala/tasty/reflect/utils/TreeUtils.scala b/library/src-3.x/scala/tasty/reflect/utils/TreeUtils.scala index d103e5b4c0a7..12fdf72a8dcc 100644 --- a/library/src-3.x/scala/tasty/reflect/utils/TreeUtils.scala +++ b/library/src-3.x/scala/tasty/reflect/utils/TreeUtils.scala @@ -23,4 +23,12 @@ trait TreeUtils { 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-macros/reflect-pos-fun/assert_1.scala b/tests/run-macros/reflect-pos-fun/assert_1.scala new file mode 100644 index 000000000000..298f0891c93d --- /dev/null +++ b/tests/run-macros/reflect-pos-fun/assert_1.scala @@ -0,0 +1,23 @@ +import scala.quoted._ +import scala.tasty._ + +object scalatest { + + inline def assert(condition: => Boolean): Unit = ${ assertImpl('condition) } + + def assertImpl(cond: Expr[Boolean])(implicit refl: Reflection): Expr[Unit] = { + import refl._ + import util._ + + cond.unseal.underlyingArgument match { + case t @ Apply(TypeApply(Select(lhs, op), targs), rhs) => + let(lhs) { left => + lets(rhs) { rs => + val app = Select.overloaded(left, op, targs.map(_.tpe), rs) + val b = app.seal.cast[Boolean] + '{ scala.Predef.assert($b) }.unseal + } + }.seal.cast[Unit] + } + } +} diff --git a/tests/run-macros/reflect-pos-fun/test_2.scala b/tests/run-macros/reflect-pos-fun/test_2.scala new file mode 100644 index 000000000000..b4d32b93a5cf --- /dev/null +++ b/tests/run-macros/reflect-pos-fun/test_2.scala @@ -0,0 +1,8 @@ +object Test { + import scalatest._ + + def main(args: Array[String]): Unit = { + val l = List(3, 5) + assert(l contains 3) + } +}