aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/mbe_expander
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_mbe/src/mbe_expander')
-rw-r--r--crates/ra_mbe/src/mbe_expander/matcher.rs40
1 files changed, 31 insertions, 9 deletions
diff --git a/crates/ra_mbe/src/mbe_expander/matcher.rs b/crates/ra_mbe/src/mbe_expander/matcher.rs
index 2579382da..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() {
@@ -202,6 +206,13 @@ impl<'a> TtIter<'a> {
202 } 206 }
203 207
204 pub(crate) fn expect_tt(&mut self) -> Result<tt::TokenTree, ()> { 208 pub(crate) fn expect_tt(&mut self) -> Result<tt::TokenTree, ()> {
209 match self.peek_n(0) {
210 Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) if punct.char == '\'' => {
211 return self.expect_lifetime();
212 }
213 _ => (),
214 }
215
205 let tt = self.next().ok_or_else(|| ())?.clone(); 216 let tt = self.next().ok_or_else(|| ())?.clone();
206 let punct = match tt { 217 let punct = match tt {
207 tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if punct.spacing == tt::Spacing::Joint => { 218 tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if punct.spacing == tt::Spacing::Joint => {
@@ -255,13 +266,21 @@ impl<'a> TtIter<'a> {
255 } 266 }
256 } 267 }
257 268
258 pub(crate) fn expect_lifetime(&mut self) -> Result<&tt::Ident, ()> { 269 pub(crate) fn expect_lifetime(&mut self) -> Result<tt::TokenTree, ()> {
259 let ident = self.expect_ident()?; 270 let punct = self.expect_punct()?;
260 // check if it start from "`" 271 if punct.char != '\'' {
261 if !ident.text.starts_with('\'') {
262 return Err(()); 272 return Err(());
263 } 273 }
264 Ok(ident) 274 let ident = self.expect_ident()?;
275
276 Ok(tt::Subtree {
277 delimiter: None,
278 token_trees: vec![
279 tt::Leaf::Punct(punct.clone()).into(),
280 tt::Leaf::Ident(ident.clone()).into(),
281 ],
282 }
283 .into())
265 } 284 }
266 285
267 pub(crate) fn expect_fragment( 286 pub(crate) fn expect_fragment(
@@ -274,7 +293,10 @@ impl<'a> TtIter<'a> {
274 } 293 }
275 294
276 impl<'a> TreeSink for OffsetTokenSink<'a> { 295 impl<'a> TreeSink for OffsetTokenSink<'a> {
277 fn token(&mut self, _kind: SyntaxKind, n_tokens: u8) { 296 fn token(&mut self, kind: SyntaxKind, mut n_tokens: u8) {
297 if kind == SyntaxKind::LIFETIME {
298 n_tokens = 2;
299 }
278 for _ in 0..n_tokens { 300 for _ in 0..n_tokens {
279 self.cursor = self.cursor.bump_subtree(); 301 self.cursor = self.cursor.bump_subtree();
280 } 302 }
@@ -286,7 +308,7 @@ impl<'a> TtIter<'a> {
286 } 308 }
287 } 309 }
288 310
289 let buffer = TokenBuffer::new(self.inner.as_slice()); 311 let buffer = TokenBuffer::new(&self.inner.as_slice());
290 let mut src = SubtreeTokenSource::new(&buffer); 312 let mut src = SubtreeTokenSource::new(&buffer);
291 let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false }; 313 let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false };
292 314
@@ -422,7 +444,7 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen
422 "tt" => input.expect_tt().map(Some).map_err(|()| err!()), 444 "tt" => input.expect_tt().map(Some).map_err(|()| err!()),
423 "lifetime" => input 445 "lifetime" => input
424 .expect_lifetime() 446 .expect_lifetime()
425 .map(|ident| Some(tt::Leaf::Ident(ident.clone()).into())) 447 .map(|tt| Some(tt))
426 .map_err(|()| err!("expected lifetime")), 448 .map_err(|()| err!("expected lifetime")),
427 "literal" => input 449 "literal" => input
428 .expect_literal() 450 .expect_literal()