diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-04-18 18:56:54 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-04-18 18:56:54 +0100 |
commit | 98819d89199c5138cc5018b036b0ec5d3fade77e (patch) | |
tree | 77b293ab5eb3a99f70082efe9cb66784f71f3343 /crates/ra_mbe/src/subtree_source.rs | |
parent | 84e3304a9bf0d68e30d58b1e37a6db2e9ec97525 (diff) | |
parent | 72bba9882889b2e20fd91e3c6c3a97debbbe6543 (diff) |
Merge #4029
4029: Fix various proc-macro bugs r=matklad a=edwin0cheng
This PRs does the following things:
1. Fixed #4001 by splitting `LIFETIME` lexer token to two mbe tokens. It is because rustc token stream expects `LIFETIME` as a combination of punct and ident, but RA `tt:TokenTree` treats it as a single `Ident` previously.
2. Fixed #4003, by skipping `proc-macro` for completion. It is because currently we don't have `AstNode` for `proc-macro`. We would need to redesign how to implement `HasSource` for `proc-macro`.
3. Fixed a bug how empty `TokenStream` merging in `proc-macro-srv` such that no L_DOLLAR and R_DOLLAR will be emitted accidentally.
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_mbe/src/subtree_source.rs')
-rw-r--r-- | crates/ra_mbe/src/subtree_source.rs | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs index 91e324db9..46791efaa 100644 --- a/crates/ra_mbe/src/subtree_source.rs +++ b/crates/ra_mbe/src/subtree_source.rs | |||
@@ -50,6 +50,26 @@ impl<'a> SubtreeTokenSource<'a> { | |||
50 | } | 50 | } |
51 | 51 | ||
52 | fn get(&self, pos: usize) -> Ref<Option<TtToken>> { | 52 | fn get(&self, pos: usize) -> Ref<Option<TtToken>> { |
53 | fn is_lifetime(c: Cursor) -> Option<(Cursor, SmolStr)> { | ||
54 | let tkn = c.token_tree(); | ||
55 | |||
56 | if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = tkn { | ||
57 | if punct.char == '\'' { | ||
58 | let next = c.bump(); | ||
59 | if let Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) = next.token_tree() { | ||
60 | let res_cursor = next.bump(); | ||
61 | let text = SmolStr::new("'".to_string() + &ident.to_string()); | ||
62 | |||
63 | return Some((res_cursor, text)); | ||
64 | } else { | ||
65 | panic!("Next token must be ident : {:#?}", next.token_tree()); | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | |||
70 | None | ||
71 | } | ||
72 | |||
53 | if pos < self.cached.borrow().len() { | 73 | if pos < self.cached.borrow().len() { |
54 | return Ref::map(self.cached.borrow(), |c| &c[pos]); | 74 | return Ref::map(self.cached.borrow(), |c| &c[pos]); |
55 | } | 75 | } |
@@ -63,6 +83,12 @@ impl<'a> SubtreeTokenSource<'a> { | |||
63 | continue; | 83 | continue; |
64 | } | 84 | } |
65 | 85 | ||
86 | if let Some((curr, text)) = is_lifetime(cursor) { | ||
87 | cached.push(Some(TtToken { kind: LIFETIME, is_joint_to_next: false, text })); | ||
88 | self.cached_cursor.set(curr); | ||
89 | continue; | ||
90 | } | ||
91 | |||
66 | match cursor.token_tree() { | 92 | match cursor.token_tree() { |
67 | Some(tt::TokenTree::Leaf(leaf)) => { | 93 | Some(tt::TokenTree::Leaf(leaf)) => { |
68 | cached.push(Some(convert_leaf(&leaf))); | 94 | cached.push(Some(convert_leaf(&leaf))); |
@@ -152,7 +178,11 @@ fn convert_ident(ident: &tt::Ident) -> TtToken { | |||
152 | } | 178 | } |
153 | 179 | ||
154 | fn convert_punct(p: tt::Punct) -> TtToken { | 180 | fn convert_punct(p: tt::Punct) -> TtToken { |
155 | let kind = SyntaxKind::from_char(p.char).unwrap(); | 181 | let kind = match SyntaxKind::from_char(p.char) { |
182 | None => panic!("{:#?} is not a valid punct", p), | ||
183 | Some(kind) => kind, | ||
184 | }; | ||
185 | |||
156 | let text = { | 186 | let text = { |
157 | let mut buf = [0u8; 4]; | 187 | let mut buf = [0u8; 4]; |
158 | let s: &str = p.char.encode_utf8(&mut buf); | 188 | let s: &str = p.char.encode_utf8(&mut buf); |