Invoking more than one attribute macro

Is something like this possible?

#[b]
#[a]
fn do_something(...) {
    ...
}

Will a get invoked first and then b? or b and then a?

Yes, it's totally possible and even is used quite often (#[derive(Serialze, Deserialize)], for example).

The order of proc_macro expansion is undefined currently, so proc_macro implementation should not rely on that anyhow.

Thanks for letting me know.

That issue specifically refers to proc macros on different locations, e.g. proc macro attributes on different type definitions.

IIRC, multiple attributes on a single node are defined to expand in source order. This allows an earlier attribute to modify latter attributes. (Disclaimer: I may be wrong here. But this order I see no reason to diverge from, it's order between different source locations that really matters.)

1 Like

If this is true, this would be very useful.

Do you know what the order of attribute macro expansion is? Top to bottom? or bottom to top?

If my memory serves me, it's guaranteed to be outer to inner. That is, if you have

#[foo]
#[bar]
fn baz() {}

Then foo is called first and passed # [ bar ] fn baz ( ) { }. Attribute macro expansion is then applied to whatever it emits, which may or may not actually include a #[bar] invocation, let alone the actual baz declaration.

Derive macros have no such guarantee of order, as they don't re-emit the actual node they're attached to.

https://github.com/rust-lang/rust/issues/63336 is the issue about application order on a single item at least.

I just submitted the reference issue https://github.com/rust-lang-nursery/reference/issues/692 directly attacking this specific issue.

Thanks for the response and for submitting an issue. It would really be great to know if there is at least some deterministic staging of compilation.