aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/mbe_expander
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-18 18:56:54 +0100
committerGitHub <[email protected]>2020-04-18 18:56:54 +0100
commit98819d89199c5138cc5018b036b0ec5d3fade77e (patch)
tree77b293ab5eb3a99f70082efe9cb66784f71f3343 /crates/ra_mbe/src/mbe_expander
parent84e3304a9bf0d68e30d58b1e37a6db2e9ec97525 (diff)
parent72bba9882889b2e20fd91e3c6c3a97debbbe6543 (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/mbe_expander')
-rw-r--r--crates/ra_mbe/src/mbe_expander/matcher.rs34
1 files changed, 26 insertions, 8 deletions
diff --git a/crates/ra_mbe/src/mbe_expander/matcher.rs b/crates/ra_mbe/src/mbe_expander/matcher.rs
index 2579382da..9485c62b8 100644
--- a/crates/ra_mbe/src/mbe_expander/matcher.rs
+++ b/crates/ra_mbe/src/mbe_expander/matcher.rs
@@ -202,6 +202,13 @@ impl<'a> TtIter<'a> {
202 } 202 }
203 203
204 pub(crate) fn expect_tt(&mut self) -> Result<tt::TokenTree, ()> { 204 pub(crate) fn expect_tt(&mut self) -> Result<tt::TokenTree, ()> {
205 match self.peek_n(0) {
206 Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) if punct.char == '\'' => {
207 return self.expect_lifetime();
208 }
209 _ => (),
210 }
211
205 let tt = self.next().ok_or_else(|| ())?.clone(); 212 let tt = self.next().ok_or_else(|| ())?.clone();
206 let punct = match tt { 213 let punct = match tt {
207 tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if punct.spacing == tt::Spacing::Joint => { 214 tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if punct.spacing == tt::Spacing::Joint => {
@@ -255,13 +262,21 @@ impl<'a> TtIter<'a> {
255 } 262 }
256 } 263 }
257 264
258 pub(crate) fn expect_lifetime(&mut self) -> Result<&tt::Ident, ()> { 265 pub(crate) fn expect_lifetime(&mut self) -> Result<tt::TokenTree, ()> {
259 let ident = self.expect_ident()?; 266 let punct = self.expect_punct()?;
260 // check if it start from "`" 267 if punct.char != '\'' {
261 if !ident.text.starts_with('\'') {
262 return Err(()); 268 return Err(());
263 } 269 }
264 Ok(ident) 270 let ident = self.expect_ident()?;
271
272 Ok(tt::Subtree {
273 delimiter: None,
274 token_trees: vec![
275 tt::Leaf::Punct(punct.clone()).into(),
276 tt::Leaf::Ident(ident.clone()).into(),
277 ],
278 }
279 .into())
265 } 280 }
266 281
267 pub(crate) fn expect_fragment( 282 pub(crate) fn expect_fragment(
@@ -274,7 +289,10 @@ impl<'a> TtIter<'a> {
274 } 289 }
275 290
276 impl<'a> TreeSink for OffsetTokenSink<'a> { 291 impl<'a> TreeSink for OffsetTokenSink<'a> {
277 fn token(&mut self, _kind: SyntaxKind, n_tokens: u8) { 292 fn token(&mut self, kind: SyntaxKind, mut n_tokens: u8) {
293 if kind == SyntaxKind::LIFETIME {
294 n_tokens = 2;
295 }
278 for _ in 0..n_tokens { 296 for _ in 0..n_tokens {
279 self.cursor = self.cursor.bump_subtree(); 297 self.cursor = self.cursor.bump_subtree();
280 } 298 }
@@ -286,7 +304,7 @@ impl<'a> TtIter<'a> {
286 } 304 }
287 } 305 }
288 306
289 let buffer = TokenBuffer::new(self.inner.as_slice()); 307 let buffer = TokenBuffer::new(&self.inner.as_slice());
290 let mut src = SubtreeTokenSource::new(&buffer); 308 let mut src = SubtreeTokenSource::new(&buffer);
291 let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false }; 309 let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false };
292 310
@@ -422,7 +440,7 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen
422 "tt" => input.expect_tt().map(Some).map_err(|()| err!()), 440 "tt" => input.expect_tt().map(Some).map_err(|()| err!()),
423 "lifetime" => input 441 "lifetime" => input
424 .expect_lifetime() 442 .expect_lifetime()
425 .map(|ident| Some(tt::Leaf::Ident(ident.clone()).into())) 443 .map(|tt| Some(tt))
426 .map_err(|()| err!("expected lifetime")), 444 .map_err(|()| err!("expected lifetime")),
427 "literal" => input 445 "literal" => input
428 .expect_literal() 446 .expect_literal()