Skip to content

Commit

Permalink
Fix and test edge cases of _ as ident
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinmehall committed Mar 20, 2021
1 parent 0a0e222 commit 0a7f286
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 3 deletions.
5 changes: 2 additions & 3 deletions crates/mbe/src/expander/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,6 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen
let tt_result = match kind {
"ident" => 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!()),
Expand Down Expand Up @@ -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,
},
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions crates/mbe/src/tests/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)");
Expand All @@ -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<crate::MacroRules, ParseError> {
Expand Down
7 changes: 7 additions & 0 deletions crates/mbe/src/tt_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(()),
Expand Down

0 comments on commit 0a7f286

Please sign in to comment.