Files
rust/tests/pretty/macro-fragment-specifier-whitespace.rs
Andrew V. Teylu c77768590d Fix whitespace after fragment specifiers in macro pretty printing
When a macro-generating-macro captures fragment specifier tokens (like
`$x:ident`) as `tt` metavariables and replays them before a keyword
(like `where`), the pretty printer concatenates them into an invalid
fragment specifier (e.g. `$x:identwhere` instead of `$x:ident where`).

This happens because `tt` captures preserve the original token spacing.
When the fragment specifier name (e.g. `ident`) was originally the last
token before a closing delimiter, it retains `JointHidden` spacing. The
`print_tts` function only checks `space_between` for `Spacing::Alone`
tokens, so `JointHidden` tokens skip the space check entirely, causing
adjacent identifier-like tokens to merge.

The fix adds a check in `print_tts` to insert a space between adjacent
identifier-like tokens (identifiers and keywords) regardless of the
original spacing, preventing them from being concatenated into invalid
tokens.

This is similar to the existing `space_between` mechanism that prevents
token merging for `Spacing::Alone` tokens, extended to also handle
`Joint`/`JointHidden` cases where two identifier-like tokens would merge.

Signed-off-by: Andrew V. Teylu <andrew.teylu@vector.com>
2026-03-19 10:35:43 +00:00

20 lines
591 B
Rust

//@ pretty-mode:expanded
//@ pp-exact:macro-fragment-specifier-whitespace.pp
// Test that fragment specifier names in macro definitions are properly
// separated from the following keyword/identifier token when pretty-printed.
// This is a regression test for a bug where `$x:ident` followed by `where`
// was pretty-printed as `$x:identwhere` (an invalid fragment specifier).
macro_rules! outer {
($d:tt $($params:tt)*) => {
#[macro_export]
macro_rules! inner {
($($params)* where $d($rest:tt)*) => {};
}
};
}
outer!($ $x:ident);
fn main() {}