diff options
author | Kevin Mehall <[email protected]> | 2021-03-20 23:43:51 +0000 |
---|---|---|
committer | Kevin Mehall <[email protected]> | 2021-03-20 23:54:57 +0000 |
commit | 0a7f28620a7002f47890c2030862052bcbf25cdb (patch) | |
tree | de1a04ded1589c0a3fa504cba606bfc8d89b3aa2 /crates | |
parent | 0a0e22235b7ad222be1aaa7765b580f4096c9aeb (diff) |
Fix and test edge cases of `_` as ident
Diffstat (limited to 'crates')
-rw-r--r-- | crates/mbe/src/expander/matcher.rs | 5 | ||||
-rw-r--r-- | crates/mbe/src/tests/rule.rs | 4 | ||||
-rw-r--r-- | crates/mbe/src/tt_iter.rs | 7 |
3 files changed, 13 insertions, 3 deletions
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs index 3c53960ce..1682b21b0 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<Option<Fragmen | |||
710 | let tt_result = match kind { | 710 | let tt_result = match kind { |
711 | "ident" => input | 711 | "ident" => input |
712 | .expect_ident() | 712 | .expect_ident() |
713 | .and_then(|ident| if ident.text == "_" { Err(()) } else { Ok(ident) }) | ||
714 | .map(|ident| Some(tt::Leaf::from(ident.clone()).into())) | 713 | .map(|ident| Some(tt::Leaf::from(ident.clone()).into())) |
715 | .map_err(|()| err!("expected ident")), | 714 | .map_err(|()| err!("expected ident")), |
716 | "tt" => input.expect_tt().map(Some).map_err(|()| err!()), | 715 | "tt" => input.expect_tt().map(Some).map_err(|()| err!()), |
@@ -763,7 +762,7 @@ impl<'a> TtIter<'a> { | |||
763 | fn expect_separator(&mut self, separator: &Separator, idx: usize) -> bool { | 762 | fn expect_separator(&mut self, separator: &Separator, idx: usize) -> bool { |
764 | let mut fork = self.clone(); | 763 | let mut fork = self.clone(); |
765 | let ok = match separator { | 764 | 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() { |
767 | Ok(rhs) => rhs.text == lhs.text, | 766 | Ok(rhs) => rhs.text == lhs.text, |
768 | _ => false, | 767 | _ => false, |
769 | }, | 768 | }, |
@@ -853,7 +852,7 @@ impl<'a> TtIter<'a> { | |||
853 | if punct.char != '\'' { | 852 | if punct.char != '\'' { |
854 | return Err(()); | 853 | return Err(()); |
855 | } | 854 | } |
856 | let ident = self.expect_ident()?; | 855 | let ident = self.expect_ident_or_underscore()?; |
857 | 856 | ||
858 | Ok(tt::Subtree { | 857 | Ok(tt::Subtree { |
859 | delimiter: None, | 858 | delimiter: None, |
diff --git a/crates/mbe/src/tests/rule.rs b/crates/mbe/src/tests/rule.rs index 07277966d..bf48112b3 100644 --- a/crates/mbe/src/tests/rule.rs +++ b/crates/mbe/src/tests/rule.rs | |||
@@ -12,6 +12,9 @@ fn test_valid_arms() { | |||
12 | } | 12 | } |
13 | 13 | ||
14 | check("($i:ident) => ()"); | 14 | check("($i:ident) => ()"); |
15 | check("($(x),*) => ()"); | ||
16 | check("($(x)_*) => ()"); | ||
17 | check("($(x)i*) => ()"); | ||
15 | check("($($i:ident)*) => ($_)"); | 18 | check("($($i:ident)*) => ($_)"); |
16 | check("($($true:ident)*) => ($true)"); | 19 | check("($($true:ident)*) => ($true)"); |
17 | check("($($false:ident)*) => ($false)"); | 20 | check("($($false:ident)*) => ($false)"); |
@@ -32,6 +35,7 @@ fn test_invalid_arms() { | |||
32 | 35 | ||
33 | check("($i) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into())); | 36 | check("($i) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into())); |
34 | check("($i:) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into())); | 37 | check("($i:) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into())); |
38 | check("($i:_) => ()", ParseError::UnexpectedToken("bad fragment specifier 1".into())); | ||
35 | } | 39 | } |
36 | 40 | ||
37 | fn parse_macro_arm(arm_definition: &str) -> Result<crate::MacroRules, ParseError> { | 41 | fn parse_macro_arm(arm_definition: &str) -> Result<crate::MacroRules, ParseError> { |
diff --git a/crates/mbe/src/tt_iter.rs b/crates/mbe/src/tt_iter.rs index a362d31fc..319a40f2a 100644 --- a/crates/mbe/src/tt_iter.rs +++ b/crates/mbe/src/tt_iter.rs | |||
@@ -50,6 +50,13 @@ impl<'a> TtIter<'a> { | |||
50 | 50 | ||
51 | pub(crate) fn expect_ident(&mut self) -> Result<&'a tt::Ident, ()> { | 51 | pub(crate) fn expect_ident(&mut self) -> Result<&'a tt::Ident, ()> { |
52 | match self.expect_leaf()? { | 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, ()> { | ||
59 | match self.expect_leaf()? { | ||
53 | tt::Leaf::Ident(it) => Ok(it), | 60 | tt::Leaf::Ident(it) => Ok(it), |
54 | _ => Err(()), | 61 | _ => Err(()), |
55 | } | 62 | } |