diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c18e8c631fec..437102d549e7 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3464,11 +3464,7 @@ pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> { } pub(crate) fn eat_metavar_guard(&mut self) -> Option> { - self.eat_metavar_seq_with_matcher( - |mv_kind| matches!(mv_kind, MetaVarKind::Guard), - |this| this.parse_match_arm_guard(), - ) - .flatten() + self.eat_metavar_seq(MetaVarKind::Guard, |this| this.parse_match_arm_guard()).flatten() } fn parse_match_arm_guard(&mut self) -> PResult<'a, Option>> { diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index ddf1b10e5235..37b76fc26a48 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -105,7 +105,10 @@ fn may_be_ident(kind: MetaVarKind) -> bool { token::Lifetime(..) | token::NtLifetime(..) => true, _ => false, }, - NonterminalKind::Guard => token.is_keyword(kw::If), + NonterminalKind::Guard => match token.kind { + token::OpenInvisible(InvisibleOrigin::MetaVar(MetaVarKind::Guard)) => true, + _ => token.is_keyword(kw::If), + }, NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => { token.kind.close_delim().is_none() } diff --git a/tests/ui/macros/macro-guard-matcher.rs b/tests/ui/macros/macro-guard-matcher.rs index 81a4412686de..d66bae455c2c 100644 --- a/tests/ui/macros/macro-guard-matcher.rs +++ b/tests/ui/macros/macro-guard-matcher.rs @@ -2,7 +2,7 @@ fn main() { macro_rules! m { - ($x:guard) => {}; + ($g:guard) => {}; } // Accepts @@ -14,4 +14,12 @@ macro_rules! m { // Rejects m!(let Some(x) = Some(1)); //~ERROR no rules expected keyword `let` + + macro_rules! m_m { + ($g:guard) => { m!($g); }; + } + + // Accepted since `m` recognizes that the sequence produced by the expansion of + // metavar `$g` "begins" (i.e., is) a guard since it's of kind `guard`. + m_m!(if true); } diff --git a/tests/ui/macros/macro-guard-matcher.stderr b/tests/ui/macros/macro-guard-matcher.stderr index eddb0de9c4c5..883f80069db8 100644 --- a/tests/ui/macros/macro-guard-matcher.stderr +++ b/tests/ui/macros/macro-guard-matcher.stderr @@ -7,10 +7,10 @@ LL | macro_rules! m { LL | m!(let Some(x) = Some(1)); | ^^^ no rules expected this token in macro call | -note: while trying to match meta-variable `$x:guard` +note: while trying to match meta-variable `$g:guard` --> $DIR/macro-guard-matcher.rs:5:10 | -LL | ($x:guard) => {}; +LL | ($g:guard) => {}; | ^^^^^^^^ error: aborting due to 1 previous error