-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle macro_rules!
tokens consistently across crates
#73569
Conversation
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'TokenStream
for its body, which has allNonterminal
s 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 bodyTokenStream
than 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 converingNonterminal
s to theproc_macro
crate's structs), but noNone
-delimited group in the cross-crate case.To fix this inconsistency, we now insert
None
-delimited groups when 'lowering' aNonterminal
macro_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 thatDisplay
output of aTokenStream
does not depend on which crate amacro_rules!
macro was invoked from.This PR is necessary in order to patch the
solana-genesis-programs
for the upcoming hygiene serialization breakage (#72121 (comment)). Thesolana-genesis-programs
crate 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.rs
for an example of the kind of nestedmacro_rules!
affected by this crate.