Handle None-delimited groups when parsing macro_rules! macro

When a `macro_rules!` macro expands to another `macro_rules!` macro, we
may see `None`-delimited groups in odd places when another crate
deserializes the 'inner' macro. This commit 'unwraps' an outer
`None`-delimited group to avoid breaking existing code.

See https://github.com/rust-lang/rust/pull/73569#issuecomment-650860457
for more details.

The proper fix is to handle `None`-delimited groups systematically
throughout the parser, but that will require significant work. In the
meantime, this hack lets us fix important hygiene bugs in macros
This commit is contained in:
Aaron Hill 2020-06-29 09:55:28 -04:00
parent c84402872e
commit 1ded7a5815
No known key found for this signature in database
GPG key ID: B4087E510E98B164
3 changed files with 87 additions and 47 deletions

View file

@ -0,0 +1,12 @@
macro_rules! produce_it {
($dollar_one:tt $foo:ident $my_name:ident) => {
#[macro_export]
macro_rules! meta_delim {
($dollar_one ($dollar_one $my_name:ident)*) => {
stringify!($dollar_one ($dollar_one $my_name)*)
}
}
}
}
produce_it!($my_name name);

View file

@ -0,0 +1,12 @@
// aux-build:meta-delim.rs
// edition:2018
// run-pass
// Tests that we can properly deserialize a macro with strange delimiters
// See https://github.com/rust-lang/rust/pull/73569#issuecomment-650860457
extern crate meta_delim;
fn main() {
assert_eq!("a bunch of idents", meta_delim::meta_delim!(a bunch of idents));
}