Skip to content

Commit 0a7f286

Browse files
committed
Fix and test edge cases of _ as ident
1 parent 0a0e222 commit 0a7f286

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

crates/mbe/src/expander/matcher.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,6 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen
710710
let tt_result = match kind {
711711
"ident" => input
712712
.expect_ident()
713-
.and_then(|ident| if ident.text == "_" { Err(()) } else { Ok(ident) })
714713
.map(|ident| Some(tt::Leaf::from(ident.clone()).into()))
715714
.map_err(|()| err!("expected ident")),
716715
"tt" => input.expect_tt().map(Some).map_err(|()| err!()),
@@ -763,7 +762,7 @@ impl<'a> TtIter<'a> {
763762
fn expect_separator(&mut self, separator: &Separator, idx: usize) -> bool {
764763
let mut fork = self.clone();
765764
let ok = match separator {
766-
Separator::Ident(lhs) if idx == 0 => match fork.expect_ident() {
765+
Separator::Ident(lhs) if idx == 0 => match fork.expect_ident_or_underscore() {
767766
Ok(rhs) => rhs.text == lhs.text,
768767
_ => false,
769768
},
@@ -853,7 +852,7 @@ impl<'a> TtIter<'a> {
853852
if punct.char != '\'' {
854853
return Err(());
855854
}
856-
let ident = self.expect_ident()?;
855+
let ident = self.expect_ident_or_underscore()?;
857856

858857
Ok(tt::Subtree {
859858
delimiter: None,

crates/mbe/src/tests/rule.rs

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ fn test_valid_arms() {
1212
}
1313

1414
check("($i:ident) => ()");
15+
check("($(x),*) => ()");
16+
check("($(x)_*) => ()");
17+
check("($(x)i*) => ()");
1518
check("($($i:ident)*) => ($_)");
1619
check("($($true:ident)*) => ($true)");
1720
check("($($false:ident)*) => ($false)");
@@ -32,6 +35,7 @@ fn test_invalid_arms() {
3235

3336
check("($i) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into()));
3437
check("($i:) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into()));
38+
check("($i:_) => ()", ParseError::UnexpectedToken("bad fragment specifier 1".into()));
3539
}
3640

3741
fn parse_macro_arm(arm_definition: &str) -> Result<crate::MacroRules, ParseError> {

crates/mbe/src/tt_iter.rs

+7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ impl<'a> TtIter<'a> {
4949
}
5050

5151
pub(crate) fn expect_ident(&mut self) -> Result<&'a tt::Ident, ()> {
52+
match self.expect_leaf()? {
53+
tt::Leaf::Ident(it) if it.text != "_" => Ok(it),
54+
_ => Err(()),
55+
}
56+
}
57+
58+
pub(crate) fn expect_ident_or_underscore(&mut self) -> Result<&'a tt::Ident, ()> {
5259
match self.expect_leaf()? {
5360
tt::Leaf::Ident(it) => Ok(it),
5461
_ => Err(()),

0 commit comments

Comments
 (0)