Closed
Description
in Dotty 0.23.x
minimized code
package example
import quoted._
object TypeTraverser with
case class 
extension BangOps on [A](x: A)
def repeatable : ![A] = new !(x)
def traverseTypesImpl[T: Type](expr: Expr[T])(using qctx: QuoteContext): Expr[Unit] =
import qctx.tasty.{Type => TastyType, _, given}
expr match
case '{ type $t; type $u; val $x: `$t` = ($e: ![`$t`]) match { case !($m @ _) => ($m: `$t`) }; ($bodyFn: `$t` => `$u`)(`$x`) } =>
unsafe.UnsafeExpr.open(bodyFn) { (body, close) =>
close(body)('{ ??? }) match
case '{ $body: $b } =>
'{ println(s"let !${${Expr(x.name)}} be (${${Expr(e.show)}} : ![${${Expr(t.show)}}]) in (${${Expr(body.show)}} : ${${Expr(b.show)}})") }
}
case e => '{ println(s"expr ${${Expr(e.unseal.underlyingArgument.show)}} is of type ${${Expr(summon[Type[T]].show)}}") }
inline def traverseTypes[T](inline expr: T): Unit = ${ traverseTypesImpl('expr) }
REPL output
scala> traverseTypes({val !(x @ _) = 1.repeatable; x})
expr {
val x: scala.Int = (example.TypeTraverser.BangOps.repeatable[scala.Int](1): @scala.unchecked) match {
case example.TypeTraverser.!(x) =>
(x: scala.Int)
}
(x: scala.Int)
} is of type scala.Int
expectation
scala> traverseTypes({val !(x) = 1.repeatable; x})
let !x be (1.repeatable: ![Int]) in (x: Int) // paraphrasing