Would it be possible to make all macros procedural, so that pattern-based macros are just procedural macros that don’t run any Rust code directly? Perhaps by providing the current token tree match-like syntax as a macro that generates code to operate on libsyntax types?
Since new macros are already changing the syntax, it shouldn’t hurt too much to go all the way and just use the macro keyword for procedural macros. I imagine it might look something like this:
pub macro foo(...) -> ... {
rules! ... {
(...) => { ... }
(...) => { ... }
}
}
The complication here is forcing all macros to talk about contexts and spans in their arguments, though on the other hand I can see it solving two other problems.
First, one-pattern macros could be simpler if these procedural macro items allow token tree patterns in argument position, like pub macro foo($x:ident). Since macros are a new item type it might also make sense just to refer to contexts and spans differently, though I don’t know how much sense that makes.
Second, the different types of macros could be distinguished by which libsyntax types are specified for arguments and/or return values, rather than by a separate set of attributes.
Overall, I think unifying both types of macros would be a lot more convenient for macro authors and for people learning how macros work.