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)"
,那么编译器崩溃就会消失。
答案 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