Open
Description
For a struct-like macro:
macro_rules! foo {
(
foo: $foo:literal,
bar: $bar:literal,
baz: $baz:literal,
qux: $qux:literal,
quux: $quux:literal,
corge: $corge:literal,
) => {};
}
Formatting with format_macro_matchers = true
produces weird results:
macro_rules! foo {
(
foo:
$foo:literal,bar:
$bar:literal,baz:
$baz:literal,qux:
$qux:literal,quux:
$quux:literal,corge:
$corge:literal,
) => {};
}
It seems like it always removes whitespace after a comma rather than using it as a possible break location. Single-line macros have similarly weird results:
macro_rules! foo {
(foo: $foo:ident,bar: $bar:ident,baz: $baz:ident,qux: $qux:ident,) => {};
}
rustfmt 1.7.0-nightly (f704f3b9 2023-12-19)
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
ytmimi commentedon Dec 21, 2023
Linking the tracking issue for
format_macro_matchers
(#3354)InsertCreativityHere commentedon Apr 15, 2024
Problem
This seems to be caused by the intersection of 2 things:
an assumption in the macro parsing code, where we always insert a 'separator' before parsing a meta-variable (
$foo
):rustfmt/src/macros.rs
Lines 907 to 910 in 7289391
$ident
s at the start of each line.and, what seems to me, like a bug in the token rules. Running the provided snippet through the macro parser gives the following tokens.
What Happens
I believe these are the root of the problem:
ParsedMacroArg { kind: Separator(", bar:", "") },
This expression (
, bar:
) should be getting parsed into aSeparator(", ")
and anOther("bar:")
, but they're not.And because of this the entire thing gets treated like it's just a comma.
This is why when it's rewriting the expression, it emits:
$foo:literal,bar:
Because as far as it knows it's writing
$foo:literal,
.The solution (Part of it at least)
I'm going to try and update the token rules, so that
, bar:
gets parsed like I suggested:into
Separator(", ")
and anOther("bar:")
.ytmimi commentedon Apr 15, 2024
@InsertCreativityHere thanks for taking the time to look into this, and for the clear explanation of the issue