非平凡 lambda 上的宏编译错误

Macro compilation error on non-trivial lambda

我想编写一个宏来检查和修改 lamba。 现在宏看起来像这样(它没有做任何修改):

object Macro {
  def literalInt(c: blackbox.Context)(func: c.Expr[Int => Int]): c.Expr[Int => Int] = {
    import c.universe._

    val Function(params, body) = func.tree

    c.Expr(Function(params, body))
  }
  
  def lit(func: Int => Int): Int => Int = macro literalInt

}

它适用于琐碎的 lambda,例如:

Macro.lit(_ + 19)

但它在

上失败了
Macro.lit { args =>
    val temp = 10
    args + temp * 2
}

有错误:

scalac: Error while emitting App.scala
value temp

有人知道这是怎么回事吗?

阅读 Macrology 201 关于所有者链损坏的内容

https://github.com/scalamacros/macrology201/tree/part1

https://github.com/scalamacros/macrology201/commits/part1(特别是第 21 步及之后)

An easy workaround to the owner chain corruption problem is erasing the chunk of the symbol table whose corresponding code is undergoing radical transformations. After the symbols in the problematic trees are erased, post-expansion typecheck is going to recreate them from scratch, keeping the symbol table consistent. This is done by a dedicated macro API called c.untypecheck in Scala 2.11* and c.resetLocalAttrs in Scala 2.10.

(*) 和 Scala 2.12-2.13.

尝试取消对传入树的类型检查(在简单的情况下这应该足够了)

def literalInt(c: blackbox.Context)(func: c.Expr[Int => Int]): c.Expr[Int => Int] = {
  import c.universe._

  val Function(params, body) = c.untypecheck(func.tree)

  c.Expr(Function(params, body))
}

What is wrong with this def macro?