what should a scala implicit macro have to return to tell the compiler “forget my result, continue your search”

不羁的心 提交于 2021-02-10 12:42:39

问题


I have an implicit macro with a greedy signature

implicit def materializeHelper[C <: Any]: Helper[C] = macro materializeHelperImpl[C]

def materializeHelperImpl[C <: Any: ctx.WeakTypeTag](ctx: blackbox.Context): ctx.Expr[Helper[C]] = ???

According to it's signature it would materialize a Helper[C] for any C. But the body is much more picky. It only accepts Cs which are sealed traits. What should the macro return to tell the compiler "forget my result, continue your implicit search as if I didn't exist"?

Currently I am returning an empty block (q""), which is not ideal because the compiler materializes a null when said implicit is used as an intermediate rule. For example, in the following line, the helper parameter is set to null when the macro returns empty (q"").

implicit def parser[C <: Any](implicit helper: Helper[C]): Parser[C] = new Parser[C](helper)

And my intention is that, in the case that C is not a sealed trait, the compiler discards both beforementioned implicit and continue the search for another more specific implicit value.


回答1:


You didn't make your macro materializing type class 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

It's more idiomatical to call c.abort with custom error message. Throwing an exception, calling c.error, returning EmptyTree (it just doesn't typecheck in such case) are also possible although they seem a little less idiomatical (it's better to have clear compile error message).



来源:https://stackoverflow.com/questions/64538997/what-should-a-scala-implicit-macro-have-to-return-to-tell-the-compiler-forget-m

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!