我有一个带有贪婪签名的隐式宏
implicit def materializeHelper[C <: Any]: Helper[C] = macro materializeHelperImpl[C]
def materializeHelperImpl[C <: Any: ctx.WeakTypeTag](ctx: blackbox.Context): ctx.Expr[Helper[C]] = ???
根据它的签名,它会为任何 C 实现一个 Helper[C]
。但是主体要挑剔得多。它只接受密封特征的 C
。
宏应该返回什么来告诉编译器“忘记我的结果,继续你的隐式搜索,就好像我不存在一样”?
目前我正在返回一个空 block (q""
),这并不理想,因为当将所述隐式用作中间规则时,编译器会具体化一个 null
。例如,在下一行中,当宏返回空 (q""
) 时,helper
参数设置为 null。
implicit def parser[C <: Any](implicit helper: Helper[C]): Parser[C] = new Parser[C](helper)
我的意图是,在 C
不是密封特征的情况下,编译器会丢弃前面提到的隐式值并继续搜索另一个更具体的隐式值。
最佳答案
你没有让你的宏具体化类型类Helper
whitebox。
Normally implicit macros should be whitebox.
If a blackbox macro (even implicit blackbox macro) throws an exception then it will be a compile error during compilation of main code. If a whitebox implicit macro throws an exception then during compilation of main code the implicit will be silently removed from candidates.
Implicit macro. Default implicit value. How?
https://docs.scala-lang.org/overviews/macros/blackbox-whitebox.html
使用自定义错误消息调用c.abort
更为惯用。抛出异常,调用 c.error
,返回 EmptyTree
(在这种情况下它只是不进行类型检查)也是可能的,尽管它们看起来不那么惯用(最好是有明确的编译错误信息)。
关于scala - scala 隐式宏应该返回什么来告诉编译器 "forget my result, continue your search",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64538997/