diff options
Diffstat (limited to 'crates/ra_mbe/src/mbe_expander')
-rw-r--r-- | crates/ra_mbe/src/mbe_expander/matcher.rs | 34 |
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() |