aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorKevin Mehall <[email protected]>2021-03-20 23:43:51 +0000
committerKevin Mehall <[email protected]>2021-03-20 23:54:57 +0000
commit0a7f28620a7002f47890c2030862052bcbf25cdb (patch)
treede1a04ded1589c0a3fa504cba606bfc8d89b3aa2 /crates
parent0a0e22235b7ad222be1aaa7765b580f4096c9aeb (diff)
Fix and test edge cases of `_` as ident
Diffstat (limited to 'crates')
-rw-r--r--crates/mbe/src/expander/matcher.rs5
-rw-r--r--crates/mbe/src/tests/rule.rs4
-rw-r--r--crates/mbe/src/tt_iter.rs7
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
37fn parse_macro_arm(arm_definition: &str) -> Result<crate::MacroRules, ParseError> { 41fn 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 }