aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-05-04 15:35:52 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-05-04 15:35:52 +0100
commitfcdb387f0d7e76f325a858e4463efd5d7ed3efc3 (patch)
treee30057667232f29d867dcf1432831e686a686b08
parentb1febf2e6d4606a7e0eb422cdeba5dd286b10794 (diff)
parent50f288db925c5473f45d43d355e6819032298d37 (diff)
Merge #1237
1237: Improve $ Handling in mbe parser r=matklad a=edwin0cheng This PR improve the $ handling in mbe parser. In some rare case, the `$` may not be following an `ident` or a `Subtree`. ( For example, a macro_rules inside a macro rules). Related issue: #1236 Co-authored-by: Edwin Cheng <[email protected]>
-rw-r--r--crates/ra_mbe/src/mbe_parser.rs11
1 files changed, 8 insertions, 3 deletions
diff --git a/crates/ra_mbe/src/mbe_parser.rs b/crates/ra_mbe/src/mbe_parser.rs
index c7ab463e2..8e1e31e7d 100644
--- a/crates/ra_mbe/src/mbe_parser.rs
+++ b/crates/ra_mbe/src/mbe_parser.rs
@@ -34,11 +34,14 @@ fn parse_subtree(tt: &tt::Subtree, transcriber: bool) -> Result<crate::Subtree,
34 while let Some(tt) = p.eat() { 34 while let Some(tt) = p.eat() {
35 let child: crate::TokenTree = match tt { 35 let child: crate::TokenTree = match tt {
36 tt::TokenTree::Leaf(leaf) => match leaf { 36 tt::TokenTree::Leaf(leaf) => match leaf {
37 tt::Leaf::Punct(tt::Punct { char: '$', .. }) => { 37 tt::Leaf::Punct(tt::Punct { char: '$', spacing }) => {
38 if p.at_ident().is_some() { 38 if p.at_ident().is_some() {
39 crate::Leaf::from(parse_var(&mut p, transcriber)?).into() 39 crate::Leaf::from(parse_var(&mut p, transcriber)?).into()
40 } else { 40 } else if let Some(tt::TokenTree::Subtree(_)) = p.current() {
41 parse_repeat(&mut p, transcriber)?.into() 41 parse_repeat(&mut p, transcriber)?.into()
42 } else {
43 // Treat it as normal punct
44 crate::Leaf::from(tt::Punct { char: '$', spacing: *spacing }).into()
42 } 45 }
43 } 46 }
44 tt::Leaf::Punct(punct) => crate::Leaf::from(*punct).into(), 47 tt::Leaf::Punct(punct) => crate::Leaf::from(*punct).into(),
@@ -89,7 +92,7 @@ fn mk_repeat(
89} 92}
90 93
91fn parse_repeat(p: &mut TtCursor, transcriber: bool) -> Result<crate::Repeat, ParseError> { 94fn parse_repeat(p: &mut TtCursor, transcriber: bool) -> Result<crate::Repeat, ParseError> {
92 let subtree = p.eat_subtree().unwrap(); 95 let subtree = p.eat_subtree()?;
93 let mut subtree = parse_subtree(subtree, transcriber)?; 96 let mut subtree = parse_subtree(subtree, transcriber)?;
94 subtree.delimiter = crate::Delimiter::None; 97 subtree.delimiter = crate::Delimiter::None;
95 98
@@ -121,6 +124,8 @@ mod tests {
121 expect_err("invalid", "subtree"); 124 expect_err("invalid", "subtree");
122 125
123 is_valid("($i:ident) => ()"); 126 is_valid("($i:ident) => ()");
127 is_valid("($($i:ident)*) => ($_)");
128
124 expect_err("$i:ident => ()", "subtree"); 129 expect_err("$i:ident => ()", "subtree");
125 expect_err("($i:ident) ()", "`=`"); 130 expect_err("($i:ident) ()", "`=`");
126 expect_err("($($i:ident)_) => ()", "repeat"); 131 expect_err("($($i:ident)_) => ()", "repeat");