diff --git a/rustfmt-core/rustfmt-lib/src/formatting/macros.rs b/rustfmt-core/rustfmt-lib/src/formatting/macros.rs index c8fc0f0a0ce..b1e8b669562 100644 --- a/rustfmt-core/rustfmt-lib/src/formatting/macros.rs +++ b/rustfmt-core/rustfmt-lib/src/formatting/macros.rs @@ -497,7 +497,7 @@ pub(crate) fn rewrite_macro_def( } let ts = def.body.inner_tokens(); let mut parser = MacroParser::new(ts.into_trees()); - let parsed_def = match parser.parse() { + let parsed_def = match parser.parse(def.macro_rules) { Some(def) => def, None => return snippet, }; @@ -544,8 +544,12 @@ pub(crate) fn rewrite_macro_def( .collect::>(); let fmt = ListFormatting::new(arm_shape, context.config) - .separator(if def.macro_rules { ";" } else { "" }) - .trailing_separator(SeparatorTactic::Always) + .separator(if def.macro_rules { ";" } else { "," }) + .trailing_separator(if def.macro_rules || multi_branch_style { + SeparatorTactic::Always + } else { + SeparatorTactic::Never + }) .preserve_newline(true); if multi_branch_style { @@ -1250,17 +1254,17 @@ impl MacroParser { } // (`(` ... `)` `=>` `{` ... `}`)* - fn parse(&mut self) -> Option { + fn parse(&mut self, is_macro_rules: bool) -> Option { let mut branches = vec![]; while self.toks.look_ahead(1).is_some() { - branches.push(self.parse_branch()?); + branches.push(self.parse_branch(is_macro_rules)?); } Some(Macro { branches }) } // `(` ... `)` `=>` `{` ... `}` - fn parse_branch(&mut self) -> Option { + fn parse_branch(&mut self, is_macro_rules: bool) -> Option { let tok = self.toks.next()?; let (lo, args_paren_kind) = match tok { TokenTree::Token(..) => return None, @@ -1285,13 +1289,13 @@ impl MacroParser { ) } }; - if let Some(TokenTree::Token(Token { - kind: TokenKind::Semi, - span, - })) = self.toks.look_ahead(0) - { - self.toks.next(); - hi = span.hi(); + if let Some(TokenTree::Token(Token { kind, span })) = self.toks.look_ahead(0) { + if (is_macro_rules && kind == TokenKind::Semi) + || (!is_macro_rules && kind == TokenKind::Comma) + { + self.toks.next(); + hi = span.hi(); + } } Some(MacroBranch { span: mk_sp(lo, hi), diff --git a/rustfmt-core/rustfmt-lib/tests/target/issue-4111.rs b/rustfmt-core/rustfmt-lib/tests/target/issue-4111.rs new file mode 100644 index 00000000000..69fe4ca70f7 --- /dev/null +++ b/rustfmt-core/rustfmt-lib/tests/target/issue-4111.rs @@ -0,0 +1,21 @@ +// rustfmt-format_macro_bodies: true +// rustfmt-format_macro_matchers: true + +pub macro scalar($m:ident, $t:ident) { + pub macro $m { + () => { + Val::$t($t::default()) + }, + ($v: expr) => { + Val::$t($t::new($v)) + }, + } + pub macro a { + () => { + Val::$t($t::default()) + }, + ($v: expr) => { + Val::$t($t::new($v)) + }, + } +} diff --git a/rustfmt-core/rustfmt-lib/tests/target/macro_rules.rs b/rustfmt-core/rustfmt-lib/tests/target/macro_rules.rs index 68052b25f48..a83f334cb63 100644 --- a/rustfmt-core/rustfmt-lib/tests/target/macro_rules.rs +++ b/rustfmt-core/rustfmt-lib/tests/target/macro_rules.rs @@ -102,21 +102,21 @@ macro m2 { ($expr:expr, $($func:ident)*) => {{ let x = $expr; $func(x) - }} + }}, /* b */ () => { /* c */ - } + }, - (@tag) => {} + (@tag) => {}, // d ($item:ident) => { mod macro_item { struct $item; } - } + }, } // #2438, #2476