diff options
author | Edwin Cheng <[email protected]> | 2021-02-28 05:06:17 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2021-02-28 05:06:17 +0000 |
commit | f5bf1a9650089ec7bd0a4d3fb69706fab06da308 (patch) | |
tree | c609fe476f5634a27e0f0342861d999c0e404b9d /crates/mbe/src/expander | |
parent | f682627da4be4777fa0c1527398ef4136cd929b1 (diff) |
Fix builtin macros split exprs on comma
Diffstat (limited to 'crates/mbe/src/expander')
-rw-r--r-- | crates/mbe/src/expander/matcher.rs | 68 |
1 files changed, 2 insertions, 66 deletions
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs index 800931cd1..e3bd4c09a 100644 --- a/crates/mbe/src/expander/matcher.rs +++ b/crates/mbe/src/expander/matcher.rs | |||
@@ -3,15 +3,13 @@ | |||
3 | use crate::{ | 3 | use crate::{ |
4 | expander::{Binding, Bindings, Fragment}, | 4 | expander::{Binding, Bindings, Fragment}, |
5 | parser::{Op, RepeatKind, Separator}, | 5 | parser::{Op, RepeatKind, Separator}, |
6 | subtree_source::SubtreeTokenSource, | ||
7 | tt_iter::TtIter, | 6 | tt_iter::TtIter, |
8 | ExpandError, MetaTemplate, | 7 | ExpandError, MetaTemplate, |
9 | }; | 8 | }; |
10 | 9 | ||
11 | use super::ExpandResult; | 10 | use super::ExpandResult; |
12 | use parser::{FragmentKind::*, TreeSink}; | 11 | use parser::FragmentKind::*; |
13 | use syntax::{SmolStr, SyntaxKind}; | 12 | use syntax::SmolStr; |
14 | use tt::buffer::{Cursor, TokenBuffer}; | ||
15 | 13 | ||
16 | impl Bindings { | 14 | impl Bindings { |
17 | fn push_optional(&mut self, name: &SmolStr) { | 15 | fn push_optional(&mut self, name: &SmolStr) { |
@@ -409,68 +407,6 @@ impl<'a> TtIter<'a> { | |||
409 | .into()) | 407 | .into()) |
410 | } | 408 | } |
411 | 409 | ||
412 | fn expect_fragment( | ||
413 | &mut self, | ||
414 | fragment_kind: parser::FragmentKind, | ||
415 | ) -> ExpandResult<Option<tt::TokenTree>> { | ||
416 | struct OffsetTokenSink<'a> { | ||
417 | cursor: Cursor<'a>, | ||
418 | error: bool, | ||
419 | } | ||
420 | |||
421 | impl<'a> TreeSink for OffsetTokenSink<'a> { | ||
422 | fn token(&mut self, kind: SyntaxKind, mut n_tokens: u8) { | ||
423 | if kind == SyntaxKind::LIFETIME_IDENT { | ||
424 | n_tokens = 2; | ||
425 | } | ||
426 | for _ in 0..n_tokens { | ||
427 | self.cursor = self.cursor.bump_subtree(); | ||
428 | } | ||
429 | } | ||
430 | fn start_node(&mut self, _kind: SyntaxKind) {} | ||
431 | fn finish_node(&mut self) {} | ||
432 | fn error(&mut self, _error: parser::ParseError) { | ||
433 | self.error = true; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | let buffer = TokenBuffer::from_tokens(&self.inner.as_slice()); | ||
438 | let mut src = SubtreeTokenSource::new(&buffer); | ||
439 | let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false }; | ||
440 | |||
441 | parser::parse_fragment(&mut src, &mut sink, fragment_kind); | ||
442 | |||
443 | let mut err = None; | ||
444 | if !sink.cursor.is_root() || sink.error { | ||
445 | err = Some(err!("expected {:?}", fragment_kind)); | ||
446 | } | ||
447 | |||
448 | let mut curr = buffer.begin(); | ||
449 | let mut res = vec![]; | ||
450 | |||
451 | if sink.cursor.is_root() { | ||
452 | while curr != sink.cursor { | ||
453 | if let Some(token) = curr.token_tree() { | ||
454 | res.push(token); | ||
455 | } | ||
456 | curr = curr.bump(); | ||
457 | } | ||
458 | } | ||
459 | self.inner = self.inner.as_slice()[res.len()..].iter(); | ||
460 | if res.len() == 0 && err.is_none() { | ||
461 | err = Some(err!("no tokens consumed")); | ||
462 | } | ||
463 | let res = match res.len() { | ||
464 | 1 => Some(res[0].cloned()), | ||
465 | 0 => None, | ||
466 | _ => Some(tt::TokenTree::Subtree(tt::Subtree { | ||
467 | delimiter: None, | ||
468 | token_trees: res.into_iter().map(|it| it.cloned()).collect(), | ||
469 | })), | ||
470 | }; | ||
471 | ExpandResult { value: res, err } | ||
472 | } | ||
473 | |||
474 | fn eat_vis(&mut self) -> Option<tt::TokenTree> { | 410 | fn eat_vis(&mut self) -> Option<tt::TokenTree> { |
475 | let mut fork = self.clone(); | 411 | let mut fork = self.clone(); |
476 | match fork.expect_fragment(Visibility) { | 412 | match fork.expect_fragment(Visibility) { |