aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe/src/expander
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2021-02-28 05:06:17 +0000
committerEdwin Cheng <[email protected]>2021-02-28 05:06:17 +0000
commitf5bf1a9650089ec7bd0a4d3fb69706fab06da308 (patch)
treec609fe476f5634a27e0f0342861d999c0e404b9d /crates/mbe/src/expander
parentf682627da4be4777fa0c1527398ef4136cd929b1 (diff)
Fix builtin macros split exprs on comma
Diffstat (limited to 'crates/mbe/src/expander')
-rw-r--r--crates/mbe/src/expander/matcher.rs68
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 @@
3use crate::{ 3use 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
11use super::ExpandResult; 10use super::ExpandResult;
12use parser::{FragmentKind::*, TreeSink}; 11use parser::FragmentKind::*;
13use syntax::{SmolStr, SyntaxKind}; 12use syntax::SmolStr;
14use tt::buffer::{Cursor, TokenBuffer};
15 13
16impl Bindings { 14impl 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) {