我的代码编译出现以下错误:Macro expansion contains free term variable Hello ...
我已将其简化为最小的示例:
class Hello(val hi: String) {
val xx = reify(hi)
var yy = q""
}
def setYYImpl(c: Context)(hExpr: c.Expr[Hello]): c.Expr[Hello] = {
import c.universe._
val hello = c.eval(c.Expr[Hello](c.untypecheck(hExpr.tree.duplicate)))
val xxVal = c.internal.createImporter(u).importTree(hello.xx.tree)
c.Expr(q"""{val h = new Hello("HO"); h.yy=$xxVal; h}""") // it should set `h.yy` to Tree:"HO"
}
def setYY(hExpr: Hello): Hello = macro setYYImpl
setYY(new Hello("HI"))
在检查了类似的问题后:Can this free-term-variable error (produced at macro expansion) be avoided?
我已经得出结论,问题是reify(hi)
,它涉及编译时间值Hello.hi
。
是否可以解决此问题? reify(hi)
返回Expr Hello.hi
,我可以以某种方式删除Hello.
前缀吗?
答案 0 :(得分:0)
尝试更换
val xx = reify(hi)
使用
val xx = Literal(Constant(hi))
即手动构建树(和
.importTree(hello.xx.tree)
与
.importTree(hello.xx)
。
(如果仅在您的示例中为Literal(Constant...
,而在实际用例中为更复杂的树,则无论如何都应尝试手动构建它,而不要使用reify
。)
然后您将遇到其他错误
Error: type mismatch;
found : String("HI")
required: reflect.runtime.universe.Tree
setYY(new Hello("HI"))
因为您的宏返回了
Expr[Hello]({
val h = new Hello("HO");
h.yy = "HI"; // h.yy is q"" i.e. Tree, "HI" is String
h
})