diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-04-18 20:36:37 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-04-18 20:36:37 +0100 |
commit | 7a59cd49ff2bb47fa0844fcf5f1ec44f32523b1b (patch) | |
tree | 2266a12f833d72faa4c4ba12a997999c7013e975 | |
parent | b95b77f92f4ce73b3c9cc652ac9ae40580d308ce (diff) | |
parent | a1b5cf81ebcac15299cc612b49023bb418507027 (diff) |
Merge #4035
4035: Convert bool to ident instead of literal in mbe r=matklad a=edwin0cheng
Fixed #1249
Currently we treat boolean literal as `tt::Literal` , which makes parsing $lit:lit matcher easily.
However, proc-macro2 treat boolean literal as `ident` :
https://github.com/alexcrichton/proc-macro2/blob/4173a21dc497c67326095e438ff989cc63cd9279/src/lib.rs#L939
OT: I am quite happy we finally need to fix this bug :)
Co-authored-by: Edwin Cheng <[email protected]>
-rw-r--r-- | crates/ra_mbe/src/mbe_expander/matcher.rs | 6 | ||||
-rw-r--r-- | crates/ra_mbe/src/subtree_source.rs | 15 | ||||
-rw-r--r-- | crates/ra_mbe/src/syntax_bridge.rs | 2 | ||||
-rw-r--r-- | crates/ra_mbe/src/tests.rs | 30 | ||||
-rw-r--r-- | crates/ra_mbe/src/tt_iter.rs | 8 |
5 files changed, 47 insertions, 14 deletions
diff --git a/crates/ra_mbe/src/mbe_expander/matcher.rs b/crates/ra_mbe/src/mbe_expander/matcher.rs index 9485c62b8..78f9efa1b 100644 --- a/crates/ra_mbe/src/mbe_expander/matcher.rs +++ b/crates/ra_mbe/src/mbe_expander/matcher.rs | |||
@@ -187,7 +187,11 @@ impl<'a> TtIter<'a> { | |||
187 | _ => false, | 187 | _ => false, |
188 | }, | 188 | }, |
189 | Separator::Literal(lhs) => match fork.expect_literal() { | 189 | Separator::Literal(lhs) => match fork.expect_literal() { |
190 | Ok(rhs) => rhs.text == lhs.text, | 190 | Ok(rhs) => match rhs { |
191 | tt::Leaf::Literal(rhs) => rhs.text == lhs.text, | ||
192 | tt::Leaf::Ident(rhs) => rhs.text == lhs.text, | ||
193 | tt::Leaf::Punct(_) => false, | ||
194 | }, | ||
191 | _ => false, | 195 | _ => false, |
192 | }, | 196 | }, |
193 | Separator::Puncts(lhss) => lhss.iter().all(|lhs| match fork.expect_punct() { | 197 | Separator::Puncts(lhss) => lhss.iter().all(|lhs| match fork.expect_punct() { |
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs index 46791efaa..d7866452d 100644 --- a/crates/ra_mbe/src/subtree_source.rs +++ b/crates/ra_mbe/src/subtree_source.rs | |||
@@ -158,20 +158,17 @@ fn convert_literal(l: &tt::Literal) -> TtToken { | |||
158 | let kind = lex_single_syntax_kind(&l.text) | 158 | let kind = lex_single_syntax_kind(&l.text) |
159 | .map(|(kind, _error)| kind) | 159 | .map(|(kind, _error)| kind) |
160 | .filter(|kind| kind.is_literal()) | 160 | .filter(|kind| kind.is_literal()) |
161 | .unwrap_or_else(|| match l.text.as_ref() { | 161 | .unwrap_or_else(|| panic!("Fail to convert given literal {:#?}", &l)); |
162 | "true" => T![true], | ||
163 | "false" => T![false], | ||
164 | _ => panic!("Fail to convert given literal {:#?}", &l), | ||
165 | }); | ||
166 | 162 | ||
167 | TtToken { kind, is_joint_to_next: false, text: l.text.clone() } | 163 | TtToken { kind, is_joint_to_next: false, text: l.text.clone() } |
168 | } | 164 | } |
169 | 165 | ||
170 | fn convert_ident(ident: &tt::Ident) -> TtToken { | 166 | fn convert_ident(ident: &tt::Ident) -> TtToken { |
171 | let kind = if ident.text.starts_with('\'') { | 167 | let kind = match ident.text.as_ref() { |
172 | LIFETIME | 168 | "true" => T![true], |
173 | } else { | 169 | "false" => T![false], |
174 | SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT) | 170 | i if i.starts_with('\'') => LIFETIME, |
171 | _ => SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT), | ||
175 | }; | 172 | }; |
176 | 173 | ||
177 | TtToken { kind, is_joint_to_next: false, text: ident.text.clone() } | 174 | TtToken { kind, is_joint_to_next: false, text: ident.text.clone() } |
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index 70899bc5d..2b4390eb2 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -376,7 +376,7 @@ trait TokenConvertor { | |||
376 | }; | 376 | }; |
377 | } | 377 | } |
378 | let leaf: tt::Leaf = match k { | 378 | let leaf: tt::Leaf = match k { |
379 | T![true] | T![false] => make_leaf!(Literal), | 379 | T![true] | T![false] => make_leaf!(Ident), |
380 | IDENT => make_leaf!(Ident), | 380 | IDENT => make_leaf!(Ident), |
381 | k if k.is_keyword() => make_leaf!(Ident), | 381 | k if k.is_keyword() => make_leaf!(Ident), |
382 | k if k.is_literal() => make_leaf!(Literal), | 382 | k if k.is_literal() => make_leaf!(Literal), |
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs index f2a726538..100ed41f2 100644 --- a/crates/ra_mbe/src/tests.rs +++ b/crates/ra_mbe/src/tests.rs | |||
@@ -1016,6 +1016,36 @@ fn test_literal() { | |||
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | #[test] | 1018 | #[test] |
1019 | fn test_boolean_is_ident() { | ||
1020 | parse_macro( | ||
1021 | r#" | ||
1022 | macro_rules! foo { | ||
1023 | ($lit0:literal, $lit1:literal) => { const VALUE: (bool,bool) = ($lit0,$lit1); }; | ||
1024 | } | ||
1025 | "#, | ||
1026 | ) | ||
1027 | .assert_expand( | ||
1028 | r#"foo!(true,false);"#, | ||
1029 | r#" | ||
1030 | SUBTREE $ | ||
1031 | IDENT const 14 | ||
1032 | IDENT VALUE 15 | ||
1033 | PUNCH : [alone] 16 | ||
1034 | SUBTREE () 17 | ||
1035 | IDENT bool 18 | ||
1036 | PUNCH , [alone] 19 | ||
1037 | IDENT bool 20 | ||
1038 | PUNCH = [alone] 21 | ||
1039 | SUBTREE () 22 | ||
1040 | IDENT true 29 | ||
1041 | PUNCH , [joint] 25 | ||
1042 | IDENT false 31 | ||
1043 | PUNCH ; [alone] 28 | ||
1044 | "#, | ||
1045 | ); | ||
1046 | } | ||
1047 | |||
1048 | #[test] | ||
1019 | fn test_vis() { | 1049 | fn test_vis() { |
1020 | parse_macro( | 1050 | parse_macro( |
1021 | r#" | 1051 | r#" |
diff --git a/crates/ra_mbe/src/tt_iter.rs b/crates/ra_mbe/src/tt_iter.rs index 100184e66..46c420718 100644 --- a/crates/ra_mbe/src/tt_iter.rs +++ b/crates/ra_mbe/src/tt_iter.rs | |||
@@ -40,9 +40,11 @@ impl<'a> TtIter<'a> { | |||
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
43 | pub(crate) fn expect_literal(&mut self) -> Result<&'a tt::Literal, ()> { | 43 | pub(crate) fn expect_literal(&mut self) -> Result<&'a tt::Leaf, ()> { |
44 | match self.expect_leaf()? { | 44 | let it = self.expect_leaf()?; |
45 | tt::Leaf::Literal(it) => Ok(it), | 45 | match it { |
46 | tt::Leaf::Literal(_) => Ok(it), | ||
47 | tt::Leaf::Ident(ident) if ident.text == "true" || ident.text == "false" => Ok(it), | ||
46 | _ => Err(()), | 48 | _ => Err(()), |
47 | } | 49 | } |
48 | } | 50 | } |