rustrust-compiler-plugin

How to process expanded macros from within procedural macros?


For overflower, I'm trying to replace all arithmetic operations (binary +, -, *, /, %, <<, >> and unary -) with corresponding trait method calls. However, I'm hitting a wall with macros. Ideally, I'd work on the already expanded macro, but this does not appear to work.

I've followed the suggestion in syntax::fold::Folder::fold_mac(..) and called noop_fold_mac(mac, self), but that does not appear to do anything to stuff inside a macro, like assert_eq!(2, 1 + 1). I don't care about the code pre-expansion, so how do I have my macro work on the expanded code?

I could probably work on the TokenTrees directly, but that's cumbersome.

I'm using rustc 1.11.0-nightly (915b003e3 2016-06-02)


Solution

  • You can use the expand_expr function to do a full expansion (if let, macros, etc...). You need a MacroExpander, which you can get by passing a mutable reference to the ExtCtxt to the MacroExpander::new method or call the ExtCtxt's expander() method.

    The actual code is:

    fn fold_expr(&mut self, expr: P<Expr>) -> P<Expr> {
        ..
        if let ExprKind::Mac(_) = expr.node {
            let expanded = expand_expr(expr.unwrap(), &mut self.cx.expander());
            return self.fold_expr(expanded);
        }
        ..
    }
    

    Edit: For completeness, one should also expand Items with ItemKind::Mac; there's an syntax::ext::expand::expand_item(..) method working similarly to expand_expr(..).