For the time being, you can get close to this with crates such as macro_rules_attribute - Rust. You'll just have to write something like #[apply(foo)] instead of #[foo].
While nobody tried to write an RFC so I can't be sure, I'm afraid this is quite unusable since declarative macros cannot easily parse e.g. generics without tt munching.
It is not entirely unusable. Attributes like #[tokio::main] only wrap the function body in something that calls a special function. No parsing of the function body needed for that and it can be done without parsing generics I think. There is also #[bevy::main] which just adds a couple of functions for iOS and Android entry points while leaving the main function intact.
You still need to parse the function signature. And main() is indeed special in that it can't have generic parameters and/or parameters (these also cannot be parsed accurately by macro_rules!), but should we add this feature for that (and tests!) or just let them write a little proc macro?
You can restrict the argument pattern to just a literal name instead of accepting arbitrary patterns and then do something like Rust Playground to emulate #[tracing::instrument].
I'm really worried about that. Because if macros will not support patterns in parameter positions, people will just not use it (there is already a demand for not using it because it is not supported well by rustdoc, and that makes me sad). So we will end up with worse code and unecessary feature that needs to be maintained forever.
If macros cannot parse the full syntax, I don't want them at supported where they need to parse it, because people will just not use the full syntax, effectively splitting the language and creating dialects. If anything, we need macros to be able to parse the full syntax and only then think about allowing them at attribute position.