How to handle gaps in procedural macros?

I want my procedural macro to replace some BinaryOps methods. How to set intervals so that when errors occur, my users are not completely confused?

+5
source share
1 answer

After some study of the source of rustc I came to the conclusion that after the β€œextension model” the best results. Therefore, we keep the original Span , but for expn_id , which we can get by calling ExtCtxt::backtrace() .

It seems like a good idea to establish this in both cases outlined in the question. An operator can be considered as extended to a path (function call) and the original expression of a binary operation extended to a function call. In code:

 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 } .. } 
+1
source

All Articles