Handle macro_rules! tokens consistently across crates#73569
Handle macro_rules! tokens consistently across crates#73569bors merged 3 commits intorust-lang:masterfrom
macro_rules! tokens consistently across crates#73569Conversation
|
r? @eddyb (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
c2a6042 to
e0cccf5
Compare
This comment has been minimized.
This comment has been minimized.
|
I'm not quite sure what the best way to handle pretty-printing is. There seems to be a few options:
|
|
Hi, Just throwing my two cents here. I heard about Any chances that this PR fixes some of these issues raised there? |
e0cccf5 to
2faaf6d
Compare
|
I've switched to removing the extra spaces printed for |
|
@bors try |
|
⌛ Trying commit 2faaf6dc571385cea3f0ba0094beb1c4e7414b28 with merge 4a152b6bdae9e6d4a77446a19ff11d26b8d2b536... |
|
☀️ Try build successful - checks-azure |
This is a great catch, I never noticed we forget to wrap tokens into a group during "lowering" nonterminals to HIR. One problem here is that rustc parser is entirely unready to encounter |
2faaf6d to
991caff
Compare
|
@petrochenkov: I've added additional test cases |
991caff to
f1008d2
Compare
|
@bors try |
|
⌛ Trying commit b35cb0aeb8e0f095fa9a2506ee438dc4d4c63a07 with merge 433da287daece77315c0cb8c4eb03b037342c115... |
|
Seems ok to patch @bors r+ |
|
📌 Commit 4cd31965c91c7eefff880075426e35846e2ec22e has been approved by |
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 rust-lang#73569 (comment) 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
4cd3196 to
1ded7a5
Compare
|
Squashed into more meaningful commits @bors r=petrochenkov |
|
📌 Commit 1ded7a5 has been approved by |
…petrochenkov Handle `macro_rules!` tokens consistently across crates When we serialize a `macro_rules!` macro, we used a 'lowered' `TokenStream` for its body, which has all `Nonterminal`s expanded in-place via `nt_to_tokenstream`. This matters when an 'outer' `macro_rules!` macro expands to an 'inner' `macro_rules!` macro - the inner macro may use tokens captured from the 'outer' macro in its definition. This means that invoking a foreign `macro_rules!` macro may use a different body `TokenStream` than when the same `macro_rules!` macro is invoked in the same crate. This difference is observable by proc-macros invoked by a `macro_rules!` macro - a `None`-delimited group will be seen in the same-crate case (inserted when convering `Nonterminal`s to the `proc_macro` crate's structs), but no `None`-delimited group in the cross-crate case. To fix this inconsistency, we now insert `None`-delimited groups when 'lowering' a `Nonterminal` `macro_rules!` body, just as we do in `proc_macro_server`. Additionally, we no longer print extra spaces for `None`-delimited groups - as far as pretty-printing is concerned, they don't exist (only their contents do). This ensures that `Display` output of a `TokenStream` does not depend on which crate a `macro_rules!` macro was invoked from. This PR is necessary in order to patch the `solana-genesis-programs` for the upcoming hygiene serialization breakage (rust-lang#72121 (comment)). The `solana-genesis-programs` crate will need to use a proc macro to re-span certain tokens in a nested `macro_rules!`, which requires us to consistently use a `None`-delimited group. See `src/test/ui/proc-macro/nested-macro-rules.rs` for an example of the kind of nested `macro_rules!` affected by this crate.
…petrochenkov Handle `macro_rules!` tokens consistently across crates When we serialize a `macro_rules!` macro, we used a 'lowered' `TokenStream` for its body, which has all `Nonterminal`s expanded in-place via `nt_to_tokenstream`. This matters when an 'outer' `macro_rules!` macro expands to an 'inner' `macro_rules!` macro - the inner macro may use tokens captured from the 'outer' macro in its definition. This means that invoking a foreign `macro_rules!` macro may use a different body `TokenStream` than when the same `macro_rules!` macro is invoked in the same crate. This difference is observable by proc-macros invoked by a `macro_rules!` macro - a `None`-delimited group will be seen in the same-crate case (inserted when convering `Nonterminal`s to the `proc_macro` crate's structs), but no `None`-delimited group in the cross-crate case. To fix this inconsistency, we now insert `None`-delimited groups when 'lowering' a `Nonterminal` `macro_rules!` body, just as we do in `proc_macro_server`. Additionally, we no longer print extra spaces for `None`-delimited groups - as far as pretty-printing is concerned, they don't exist (only their contents do). This ensures that `Display` output of a `TokenStream` does not depend on which crate a `macro_rules!` macro was invoked from. This PR is necessary in order to patch the `solana-genesis-programs` for the upcoming hygiene serialization breakage (rust-lang#72121 (comment)). The `solana-genesis-programs` crate will need to use a proc macro to re-span certain tokens in a nested `macro_rules!`, which requires us to consistently use a `None`-delimited group. See `src/test/ui/proc-macro/nested-macro-rules.rs` for an example of the kind of nested `macro_rules!` affected by this crate.
…petrochenkov Handle `macro_rules!` tokens consistently across crates When we serialize a `macro_rules!` macro, we used a 'lowered' `TokenStream` for its body, which has all `Nonterminal`s expanded in-place via `nt_to_tokenstream`. This matters when an 'outer' `macro_rules!` macro expands to an 'inner' `macro_rules!` macro - the inner macro may use tokens captured from the 'outer' macro in its definition. This means that invoking a foreign `macro_rules!` macro may use a different body `TokenStream` than when the same `macro_rules!` macro is invoked in the same crate. This difference is observable by proc-macros invoked by a `macro_rules!` macro - a `None`-delimited group will be seen in the same-crate case (inserted when convering `Nonterminal`s to the `proc_macro` crate's structs), but no `None`-delimited group in the cross-crate case. To fix this inconsistency, we now insert `None`-delimited groups when 'lowering' a `Nonterminal` `macro_rules!` body, just as we do in `proc_macro_server`. Additionally, we no longer print extra spaces for `None`-delimited groups - as far as pretty-printing is concerned, they don't exist (only their contents do). This ensures that `Display` output of a `TokenStream` does not depend on which crate a `macro_rules!` macro was invoked from. This PR is necessary in order to patch the `solana-genesis-programs` for the upcoming hygiene serialization breakage (rust-lang#72121 (comment)). The `solana-genesis-programs` crate will need to use a proc macro to re-span certain tokens in a nested `macro_rules!`, which requires us to consistently use a `None`-delimited group. See `src/test/ui/proc-macro/nested-macro-rules.rs` for an example of the kind of nested `macro_rules!` affected by this crate.
…arth Rollup of 16 pull requests Successful merges: - rust-lang#72569 (Remove legacy InnoSetup GUI installer) - rust-lang#73306 (Don't implement Fn* traits for #[target_feature] functions) - rust-lang#73345 (expand: Stop using nonterminals for passing tokens to attribute and derive macros) - rust-lang#73449 (Provide more information on duplicate lang item error.) - rust-lang#73569 (Handle `macro_rules!` tokens consistently across crates) - rust-lang#73803 (Recover extra trailing angle brackets in struct definition) - rust-lang#73839 (Split and expand nonstandard-style lints unicode unit test.) - rust-lang#73841 (Remove defunct `-Z print-region-graph`) - rust-lang#73848 (Fix markdown rendering in librustc_lexer docs) - rust-lang#73865 (Fix Zulip topic format) - rust-lang#73892 (Clean up E0712 explanation) - rust-lang#73898 (remove duplicate test for rust-lang#61935) - rust-lang#73906 (Add missing backtick in `ty_error_with_message`) - rust-lang#73909 (`#[deny(unsafe_op_in_unsafe_fn)]` in libstd/fs.rs) - rust-lang#73910 (Rewrite a few manual index loops with while-let) - rust-lang#73929 (Fix comment typo) Failed merges: r? @ghost
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 rust-lang#73569 (comment) 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
When we serialize a
macro_rules!macro, we used a 'lowered'TokenStreamfor its body, which has allNonterminals expanded in-place viant_to_tokenstream. This matters when an 'outer'macro_rules!macro expands to an 'inner'macro_rules!macro - the inner macro may use tokens captured from the 'outer' macro in its definition.This means that invoking a foreign
macro_rules!macro may use a different bodyTokenStreamthan when the samemacro_rules!macro is invoked in the same crate. This difference is observable by proc-macros invoked by amacro_rules!macro - aNone-delimited group will be seen in the same-crate case (inserted when converingNonterminals to theproc_macrocrate's structs), but noNone-delimited group in the cross-crate case.To fix this inconsistency, we now insert
None-delimited groups when 'lowering' aNonterminalmacro_rules!body, just as we do inproc_macro_server. Additionally, we no longer print extra spaces forNone-delimited groups - as far as pretty-printing is concerned, they don't exist (only their contents do). This ensures thatDisplayoutput of aTokenStreamdoes not depend on which crate amacro_rules!macro was invoked from.This PR is necessary in order to patch the
solana-genesis-programsfor the upcoming hygiene serialization breakage (#72121 (comment)). Thesolana-genesis-programscrate will need to use a proc macro to re-span certain tokens in a nestedmacro_rules!, which requires us to consistently use aNone-delimited group.See
src/test/ui/proc-macro/nested-macro-rules.rsfor an example of the kind of nestedmacro_rules!affected by this crate.