plugins - How to correctly deal with spans in procedural macros? -
i want procedural macro replace binaryops methods. how set spans if errors occur users not confused?
after looking rustc
's source, came conclusion following "expansion" model produces best results. keep original span
expn_id
, can calling extctxt::backtrace()
.
it appears idea set in both cases outlined in question. operator can seen expanded (function call) path, , original binary operation expression expanded function call. in code:
match expr.unwrap() { .. expr { node: exprkind::binary( spanned { node: add, span: op }, l, r), span, .. } => { let bt = self.cx.backtrace(); // 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 } .. }