Skip to content

Can't match on a pattern val def in quote #8179

Closed
@bishabosha

Description

@bishabosha

in Dotty 0.23.x

minimized code

package example

import quoted._

object TypeTraverser with

  case class ![A](a: A)

  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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions