编译器崩溃在简单的宏操作匹配语句

时间:2015-01-10 18:46:12

标签: scala pattern-matching scala-macros

def control(x: String): Option[String] = macro controlImpl
def controlImpl(c: Context)(x: c.Expr[String]): c.Expr[Option[String]] = {
    import c.universe._
    val result = x.tree match {
        case Match(expr, cases) =>
            val matchz = Match(q"""List("hello")""", cases)
            q"Some(List(5)).map{a => $matchz}"
        case a => a
    }
    c.Expr[Option[String]](result)
}

此宏在宏扩展期间崩溃,并出现以下错误:

java.lang.IllegalArgumentException: Could not find proxy for val o7: Some in List(value o7, method apply, <$anon: Function1>, value f, method apply, <$anon: Function1>, method apply, <$anon: Function0>, value <local ApplicativeTest>, object ApplicativeTest, package scalaz, package <root>) (currentOwner= value one )

这是宏应用程序点:

val f = IdiomBracket.control {
    a.get match {
        case List(one) => one
        case _ => ""
    }
}

奇怪的是,如果用q"Some(List(5)).map{a => $matchz}"替换q"Some($matchz)",那么编译器崩溃就会消失。

1 个答案:

答案 0 :(得分:2)

&#34;简单的宏&#34;是矛盾的。

坠机是在lambda lift中,表示一个坏的符号所有者。

您可以使用-Ybrowse:typer检查您生成的树。

考虑您想要制作的内容:

class X {
  //def g = List("hello") match { case List(x) => x case _ => "" }
  def f = Some(List(5)).map{a => List("hello") match { case List(x) => x case _ => "" } }
}

案例中的var由您要创建的anonfun拥有:

Symbol: [has] value x
Symbol owner: value $anonfun

您的实际结果:

Symbol: [has] value x
Symbol owner: value <local Controlled>

其中Controlled是我的代码封闭对象的样本。

您可能需要重建案例,而不仅仅是cases map (_.untypecheck)

https://github.com/scala/scala/blob/v2.11.5/src/reflect/scala/reflect/api/Trees.scala#L1100