aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-05-04 17:55:53 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-05-04 17:55:53 +0100
commitb6ffb1d2a3bcc94e41c95c7a086117e11ce487e5 (patch)
tree71841463e340082843d15adefbcd52c29dea73dc
parente1ea2500fcc5e136fbe6a14c488f558e28519c45 (diff)
parent1a3800df60ca789f858dcf40edff4aee01b53188 (diff)
Merge #1239
1239: Fix `$true` and `$false` as $var name error r=matklad a=edwin0cheng This PR fixed a bug which cannot use `$true` and `$false` as `$var` name in mbe. Co-authored-by: Edwin Cheng <[email protected]>
-rw-r--r--crates/ra_mbe/src/mbe_parser.rs27
1 files changed, 24 insertions, 3 deletions
diff --git a/crates/ra_mbe/src/mbe_parser.rs b/crates/ra_mbe/src/mbe_parser.rs
index 8e1e31e7d..797c70bc7 100644
--- a/crates/ra_mbe/src/mbe_parser.rs
+++ b/crates/ra_mbe/src/mbe_parser.rs
@@ -28,6 +28,16 @@ fn parse_rule(p: &mut TtCursor) -> Result<crate::Rule, ParseError> {
28 Ok(crate::Rule { lhs, rhs }) 28 Ok(crate::Rule { lhs, rhs })
29} 29}
30 30
31fn is_boolean_literal(lit: Option<&tt::TokenTree>) -> bool {
32 if let Some(tt::TokenTree::Leaf(tt::Leaf::Literal(lit))) = lit {
33 if lit.text == "true" || lit.text == "false" {
34 return true;
35 }
36 }
37
38 false
39}
40
31fn parse_subtree(tt: &tt::Subtree, transcriber: bool) -> Result<crate::Subtree, ParseError> { 41fn parse_subtree(tt: &tt::Subtree, transcriber: bool) -> Result<crate::Subtree, ParseError> {
32 let mut token_trees = Vec::new(); 42 let mut token_trees = Vec::new();
33 let mut p = TtCursor::new(tt); 43 let mut p = TtCursor::new(tt);
@@ -35,7 +45,8 @@ fn parse_subtree(tt: &tt::Subtree, transcriber: bool) -> Result<crate::Subtree,
35 let child: crate::TokenTree = match tt { 45 let child: crate::TokenTree = match tt {
36 tt::TokenTree::Leaf(leaf) => match leaf { 46 tt::TokenTree::Leaf(leaf) => match leaf {
37 tt::Leaf::Punct(tt::Punct { char: '$', spacing }) => { 47 tt::Leaf::Punct(tt::Punct { char: '$', spacing }) => {
38 if p.at_ident().is_some() { 48 // mbe var can be an ident or keyword, including `true` and `false`
49 if p.at_ident().is_some() || is_boolean_literal(p.current()) {
39 crate::Leaf::from(parse_var(&mut p, transcriber)?).into() 50 crate::Leaf::from(parse_var(&mut p, transcriber)?).into()
40 } else if let Some(tt::TokenTree::Subtree(_)) = p.current() { 51 } else if let Some(tt::TokenTree::Subtree(_)) = p.current() {
41 parse_repeat(&mut p, transcriber)?.into() 52 parse_repeat(&mut p, transcriber)?.into()
@@ -60,8 +71,16 @@ fn parse_subtree(tt: &tt::Subtree, transcriber: bool) -> Result<crate::Subtree,
60} 71}
61 72
62fn parse_var(p: &mut TtCursor, transcriber: bool) -> Result<crate::Var, ParseError> { 73fn parse_var(p: &mut TtCursor, transcriber: bool) -> Result<crate::Var, ParseError> {
63 let ident = p.eat_ident().unwrap(); 74 let text = {
64 let text = ident.text.clone(); 75 if is_boolean_literal(p.current()) {
76 let lit = p.eat_literal().unwrap();
77 lit.text.clone()
78 } else {
79 let ident = p.eat_ident().unwrap();
80 ident.text.clone()
81 }
82 };
83
65 let kind = if !transcriber && p.at_char(':') { 84 let kind = if !transcriber && p.at_char(':') {
66 p.bump(); 85 p.bump();
67 if let Some(ident) = p.eat_ident() { 86 if let Some(ident) = p.eat_ident() {
@@ -125,6 +144,8 @@ mod tests {
125 144
126 is_valid("($i:ident) => ()"); 145 is_valid("($i:ident) => ()");
127 is_valid("($($i:ident)*) => ($_)"); 146 is_valid("($($i:ident)*) => ($_)");
147 is_valid("($($true:ident)*) => ($true)");
148 is_valid("($($false:ident)*) => ($false)");
128 149
129 expect_err("$i:ident => ()", "subtree"); 150 expect_err("$i:ident => ()", "subtree");
130 expect_err("($i:ident) ()", "`=`"); 151 expect_err("($i:ident) ()", "`=`");