diff options
Diffstat (limited to 'crates/ra_mbe/src/mbe_expander.rs')
-rw-r--r-- | crates/ra_mbe/src/mbe_expander.rs | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index 91b6db522..7411dd8b1 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs | |||
@@ -196,6 +196,7 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
196 | "literal" => { | 196 | "literal" => { |
197 | let literal = | 197 | let literal = |
198 | input.eat_literal().ok_or(ExpandError::UnexpectedToken)?.clone(); | 198 | input.eat_literal().ok_or(ExpandError::UnexpectedToken)?.clone(); |
199 | |||
199 | res.inner.insert( | 200 | res.inner.insert( |
200 | text.clone(), | 201 | text.clone(), |
201 | Binding::Simple(tt::Leaf::from(literal).into()), | 202 | Binding::Simple(tt::Leaf::from(literal).into()), |
@@ -210,7 +211,7 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
210 | } | 211 | } |
211 | } | 212 | } |
212 | crate::Leaf::Punct(punct) => { | 213 | crate::Leaf::Punct(punct) => { |
213 | if input.eat_punct() != Some(punct) { | 214 | if !input.eat_punct().map(|p| p.char == punct.char).unwrap_or(false) { |
214 | return Err(ExpandError::UnexpectedToken); | 215 | return Err(ExpandError::UnexpectedToken); |
215 | } | 216 | } |
216 | } | 217 | } |
@@ -246,8 +247,23 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
246 | } | 247 | } |
247 | } | 248 | } |
248 | 249 | ||
249 | if let Some(separator) = *separator { | 250 | if let Some(separator) = separator { |
250 | if input.eat_punct().map(|p| p.char) != Some(separator) { | 251 | use crate::Separator::*; |
252 | |||
253 | if !input | ||
254 | .eat_seperator() | ||
255 | .map(|sep| match (sep, separator) { | ||
256 | (Ident(ref a), Ident(ref b)) => a.text == b.text, | ||
257 | (Literal(ref a), Literal(ref b)) => a.text == b.text, | ||
258 | (Puncts(ref a), Puncts(ref b)) if a.len() == b.len() => { | ||
259 | let a_iter = a.iter().map(|a| a.char); | ||
260 | let b_iter = b.iter().map(|b| b.char); | ||
261 | a_iter.eq(b_iter) | ||
262 | } | ||
263 | _ => false, | ||
264 | }) | ||
265 | .unwrap_or(false) | ||
266 | { | ||
251 | input.rollback(memento); | 267 | input.rollback(memento); |
252 | break; | 268 | break; |
253 | } | 269 | } |
@@ -328,7 +344,7 @@ fn expand_tt( | |||
328 | // Dirty hack to make macro-expansion terminate. | 344 | // Dirty hack to make macro-expansion terminate. |
329 | // This should be replaced by a propper macro-by-example implementation | 345 | // This should be replaced by a propper macro-by-example implementation |
330 | let mut limit = 128; | 346 | let mut limit = 128; |
331 | let mut has_sep = false; | 347 | let mut has_seps = 0; |
332 | 348 | ||
333 | while let Ok(t) = expand_subtree(&repeat.subtree, bindings, nesting) { | 349 | while let Ok(t) = expand_subtree(&repeat.subtree, bindings, nesting) { |
334 | limit -= 1; | 350 | limit -= 1; |
@@ -339,15 +355,28 @@ fn expand_tt( | |||
339 | nesting.push(idx + 1); | 355 | nesting.push(idx + 1); |
340 | token_trees.push(reduce_single_token(t).into()); | 356 | token_trees.push(reduce_single_token(t).into()); |
341 | 357 | ||
342 | if let Some(sep) = repeat.separator { | 358 | if let Some(ref sep) = repeat.separator { |
343 | let punct = | 359 | match sep { |
344 | tt::Leaf::from(tt::Punct { char: sep, spacing: tt::Spacing::Alone }); | 360 | crate::Separator::Ident(ident) => { |
345 | token_trees.push(punct.into()); | 361 | has_seps = 1; |
346 | has_sep = true; | 362 | token_trees.push(tt::Leaf::from(ident.clone()).into()); |
363 | } | ||
364 | crate::Separator::Literal(lit) => { | ||
365 | has_seps = 1; | ||
366 | token_trees.push(tt::Leaf::from(lit.clone()).into()); | ||
367 | } | ||
368 | |||
369 | crate::Separator::Puncts(puncts) => { | ||
370 | has_seps = puncts.len(); | ||
371 | for punct in puncts { | ||
372 | token_trees.push(tt::Leaf::from(*punct).into()); | ||
373 | } | ||
374 | } | ||
375 | } | ||
347 | } | 376 | } |
348 | } | 377 | } |
349 | nesting.pop().unwrap(); | 378 | nesting.pop().unwrap(); |
350 | if has_sep { | 379 | for _ in 0..has_seps { |
351 | token_trees.pop(); | 380 | token_trees.pop(); |
352 | } | 381 | } |
353 | 382 | ||