diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs index 3c53960ced..1682b21b08 100644 --- a/crates/mbe/src/expander/matcher.rs +++ b/crates/mbe/src/expander/matcher.rs @@ -710,7 +710,6 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult input .expect_ident() - .and_then(|ident| if ident.text == "_" { Err(()) } else { Ok(ident) }) .map(|ident| Some(tt::Leaf::from(ident.clone()).into())) .map_err(|()| err!("expected ident")), "tt" => input.expect_tt().map(Some).map_err(|()| err!()), @@ -763,7 +762,7 @@ impl<'a> TtIter<'a> { fn expect_separator(&mut self, separator: &Separator, idx: usize) -> bool { let mut fork = self.clone(); let ok = match separator { - Separator::Ident(lhs) if idx == 0 => match fork.expect_ident() { + Separator::Ident(lhs) if idx == 0 => match fork.expect_ident_or_underscore() { Ok(rhs) => rhs.text == lhs.text, _ => false, }, @@ -853,7 +852,7 @@ impl<'a> TtIter<'a> { if punct.char != '\'' { return Err(()); } - let ident = self.expect_ident()?; + let ident = self.expect_ident_or_underscore()?; Ok(tt::Subtree { delimiter: None, diff --git a/crates/mbe/src/tests/rule.rs b/crates/mbe/src/tests/rule.rs index 07277966d4..bf48112b3a 100644 --- a/crates/mbe/src/tests/rule.rs +++ b/crates/mbe/src/tests/rule.rs @@ -12,6 +12,9 @@ fn test_valid_arms() { } check("($i:ident) => ()"); + check("($(x),*) => ()"); + check("($(x)_*) => ()"); + check("($(x)i*) => ()"); check("($($i:ident)*) => ($_)"); check("($($true:ident)*) => ($true)"); check("($($false:ident)*) => ($false)"); @@ -32,6 +35,7 @@ fn test_invalid_arms() { check("($i) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into())); check("($i:) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into())); + check("($i:_) => ()", ParseError::UnexpectedToken("bad fragment specifier 1".into())); } fn parse_macro_arm(arm_definition: &str) -> Result { diff --git a/crates/mbe/src/tt_iter.rs b/crates/mbe/src/tt_iter.rs index a362d31fcf..319a40f2aa 100644 --- a/crates/mbe/src/tt_iter.rs +++ b/crates/mbe/src/tt_iter.rs @@ -49,6 +49,13 @@ impl<'a> TtIter<'a> { } pub(crate) fn expect_ident(&mut self) -> Result<&'a tt::Ident, ()> { + match self.expect_leaf()? { + tt::Leaf::Ident(it) if it.text != "_" => Ok(it), + _ => Err(()), + } + } + + pub(crate) fn expect_ident_or_underscore(&mut self) -> Result<&'a tt::Ident, ()> { match self.expect_leaf()? { tt::Leaf::Ident(it) => Ok(it), _ => Err(()),