如何正确处理程序宏中的跨度?

llo*_*giq 5 plugins rust

我希望我的程序宏用方法替换一些BinaryOps.如何设置跨度,以便在发生错误时我的用户不会完全混淆?

llo*_*giq 1

经过一番研究后rustc,我得出的结论是,遵循“扩展”模型会产生最好的结果。因此,我们保留原始文件,Spanexpn_id可以通过致电获取ExtCtxt::backtrace()

在问题中概述的两种情况下设置它似乎是一个好主意。运算可以看作扩展到(函数调用)路径,而原始的二元运算表达式扩展为函数调用。在代码中:

match expr.unwrap() {
    ..
    Expr { node: ExprKind::Binary( Spanned { node: Add, span: op }, l, r), span, .. } => {
        let bt = self.cx.backtrace(); // get the expansion ID
        let path = self.cx.path(Span { expn_id: bt, ..op }, vec![crate_name, trait_name, fn_name]);
        let epath = self.cx.expr_path(path); // path expression
        let args_expanded = self.fold_exprs(args);
        self.cx.expr_call(Span { expn_id: bt, ..span }, epath, args_expanded)
        // ^ outer expression
    }
    ..
}
Run Code Online (Sandbox Code Playgroud)