diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index afa116ce1bccd..5b466cec8e15b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2051,6 +2051,10 @@ impl<'a> Parser<'a> { if self.token.kind == TokenKind::Semi && matches!(self.token_cursor.frame.delim_sp, Some((Delimiter::Parenthesis, _))) + // HACK: This is needed so we can detect whether we're inside a macro, + // where regular assumptions about what tokens can follow other tokens + // don't necessarily apply. + && self.subparser_name.is_none() { // It is likely that the closure body is a block but where the // braces have been removed. We will recover and eat the next diff --git a/src/test/ui/parser/semi-after-closure-in-macro.rs b/src/test/ui/parser/semi-after-closure-in-macro.rs new file mode 100644 index 0000000000000..14efb6100b0a5 --- /dev/null +++ b/src/test/ui/parser/semi-after-closure-in-macro.rs @@ -0,0 +1,14 @@ +// check-pass + +// Checks that the fix in #103222 doesn't also disqualify semicolons after +// closures within parentheses *in macros*, where they're totally allowed. + +macro_rules! m { + (($expr:expr ; )) => { + $expr + }; +} + +fn main() { + let x = m!(( ||() ; )); +}