I think this is a misleading way to put it. When you have multiple attributes on the same item, it is in fact guaranteed that they're evaluated outside-in.
The reason this happens is that as far as the process is concerned,
#[parent] is passed the entire token stream of the item it decorates to do with as it pleases. It can read, strip, and/or add any code and/or attributes it wants, then emit the transformed code. Then, that transformed code is processed; if
#[name] is the outermost attribute, it is then processed.
However! The fact that these are run even in the same process is not guaranteed. Or that #[name]
is run _at all_ isn't guaranteed; if#[parent]` emits an identical tokenstream to one it emitted before, the compiler could reuse its knowledge of what the previous transform was rather than rerunning any further attributes.
So no state can be remembered between the implementation of individual attributes. (Every attribute's implementation has to be "pure".) But the logical ordering of the attributes' application is guaranteed, and outer attributes are guaranteed to see attributes closer to the item (and have the opportunity to remove them).