rustmacrosrust-proc-macros

Proc macro execution order


I have one proc macro that looks like this:

#[proc_macro_attribute]
pub fn my_macro(_meta: CompilerTokenStream, input: CompilerTokenStream) -> CompilerTokenStream { //* bits of code */ }

Then I have a derive macro:

#[proc_macro_derive(Operations)]
pub fn operations(input: proc_macro::TokenStream) -> proc_macro::TokenStream { //* bits of code */ }

Is it possible to make the derive macro being expanded after the attribute one?

The reason is that I have a crate with some static variables to track data. And I need to read the data in the derive macro (the attribute macro is the writer)


Solution

  • Macros are expanded starting outside-in in the syntax tree (because the outermost macro is free to rewrite the inner code so that it has more or fewer macro calls); for attributes this means expansion starts with the topmost attribute first. So, you should get the expansion order you want by writing the attributes in this order:

    #[my_macro]
    #[derive(Operations)]
    

    However, you should not do this at all — you should not use static variables in your macro crate to communicate information. It will work, right now, but the Rust compiler does not promise not to cache macro invocations, run each macro expansion in a separate process/sandbox, or make other such changes to macro expansion that would break your macro's communication path.

    (Therefore, the expansion order should not matter to you, except that you can know that your macro won't ever see another macro's expansion in your own macro's input.)