Modify AST after macro expansion in compiler plugin?


#1

I’m writing a compiler plugin to dynamically disable bits of Rust code (e.g., all functions whose names match a particular regex). Everything works great, except for one issue: I want to be able to operate on items that are introduced at macro expansion time, but it seems that my plugin is getting run before that happens. My current approach (thanks to another question on this forum) is to register a syntax extension that gets invoked from a crate-wide decorator (#![disable_code]).

You can see an example of this here:

#![feature(test)]
#![feature(plugin)]
#![plugin(disable_code)]
#![disable_code]

fn foo() {
    bar();
    baz();
}

fn bar() {}

macro_rules! make_fn {
    ($fn:ident) => (
        fn $fn() {}
    )
}

make_fn!(baz);

If I run cargo build, it works fine (as expected). If I run RUST_DISABLE_CODE_FILTER='or(regex("bar"), regex("baz"))' cargo check, I get an error about bar not existing (also as expected), but I don’t get an error about baz not existing, which is evidence of the fact that the deletion is happening pre-macro expansion (also, as a fun extra, RUST_DISABLE_CODE_FILTER='regex("fn")' cargo check causes make_fn!(baz) to fail by not being able to find the make_fn macro).

Is there anything I can do about this? Is there some plugin mechanism I can use that will still allow me to modify the whole crate’s AST but also run after macro expansion?