diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 4aadb7d7ca5..3e4e9278910 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -830,7 +830,8 @@ impl<'a> Parser<'a> { ) -> PResult<'a, PatKind> { let ident = self.parse_ident()?; - if !matches!(syntax_loc, Some(PatternLocation::FunctionParameter)) + if self.may_recover() + && !matches!(syntax_loc, Some(PatternLocation::FunctionParameter)) && self.check_noexpect(&token::Lt) && self.look_ahead(1, |t| t.can_begin_type()) { diff --git a/tests/ui/parser/issues/issue-115780-pat-lt-bracket-in-macro-call.rs b/tests/ui/parser/issues/issue-115780-pat-lt-bracket-in-macro-call.rs new file mode 100644 index 00000000000..3421333b8a0 --- /dev/null +++ b/tests/ui/parser/issues/issue-115780-pat-lt-bracket-in-macro-call.rs @@ -0,0 +1,21 @@ +// Regression test for issue #115780. +// Ensure that we don't emit a parse error for the token sequence `Ident "<" Ty` in pattern position +// if we are inside a macro call since it can be valid input for a subsequent macro rule. +// See also #103534. + +// check-pass + +macro_rules! mdo { + ($p: pat =<< $e: expr ; $( $t: tt )*) => { + $e.and_then(|$p| mdo! { $( $t )* }) + }; + (ret<$ty: ty> $e: expr;) => { Some::<$ty>($e) }; +} + +fn main() { + mdo! { + x_val =<< Some(0); + y_val =<< Some(1); + ret<(i32, i32)> (x_val, y_val); + }; +}