1use std::{rc::Rc, sync::Arc};
63
64use intern::{Symbol, sym};
65use smallvec::{SmallVec, smallvec};
66use span::Span;
67use tt::{
68 DelimSpan,
69 iter::{TtElement, TtIter},
70};
71
72use crate::{
73 ExpandError, ExpandErrorKind, MetaTemplate, ValueResult,
74 expander::{Binding, Bindings, ExpandResult, Fragment},
75 expect_fragment,
76 parser::{ExprKind, MetaVarKind, Op, RepeatKind, Separator},
77};
78
79impl<'a> Bindings<'a> {
80 fn push_optional(&mut self, name: Symbol) {
81 self.inner.insert(name, Binding::Fragment(Fragment::Empty));
82 }
83
84 fn push_empty(&mut self, name: Symbol) {
85 self.inner.insert(name, Binding::Empty);
86 }
87
88 fn bindings(&self) -> impl Iterator<Item = &Binding<'a>> {
89 self.inner.values()
90 }
91}
92
93#[derive(Clone, Default, Debug)]
94pub(super) struct Match<'a> {
95 pub(super) bindings: Bindings<'a>,
96 pub(super) err: Option<ExpandError>,
98 pub(super) err_count: usize,
99 pub(super) unmatched_tts: usize,
101 pub(super) bound_count: usize,
103}
104
105impl Match<'_> {
106 fn add_err(&mut self, err: ExpandError) {
107 let prev_err = self.err.take();
108 self.err = prev_err.or(Some(err));
109 self.err_count += 1;
110 }
111}
112
113pub(super) fn match_<'t>(
115 db: &dyn salsa::Database,
116 pattern: &'t MetaTemplate,
117 input: &'t tt::TopSubtree<Span>,
118) -> Match<'t> {
119 let mut res = match_loop(db, pattern, input);
120 res.bound_count = count(res.bindings.bindings());
121 return res;
122
123 fn count<'a>(bindings: impl Iterator<Item = &'a Binding<'a>>) -> usize {
124 bindings
125 .map(|it| match it {
126 Binding::Fragment(_) => 1,
127 Binding::Empty => 1,
128 Binding::Missing(_) => 1,
129 Binding::Nested(it) => count(it.iter()),
130 })
131 .sum()
132 }
133}
134
135#[derive(Debug, Clone)]
136enum BindingKind<'a> {
137 Empty(Symbol),
138 Optional(Symbol),
139 Fragment(Symbol, Fragment<'a>),
140 Missing(Symbol, MetaVarKind),
141 Nested(usize, usize),
142}
143
144#[derive(Debug, Clone)]
145struct BindingsIdx(usize, usize);
146
147#[derive(Debug, Clone)]
148enum LinkNode<T> {
149 Node(T),
150 Parent { idx: usize, len: usize },
151}
152
153#[derive(Default)]
154struct BindingsBuilder<'a> {
155 nodes: Vec<Vec<LinkNode<Rc<BindingKind<'a>>>>>,
156 nested: Vec<Vec<LinkNode<usize>>>,
157}
158
159impl<'a> BindingsBuilder<'a> {
160 fn alloc(&mut self) -> BindingsIdx {
161 let idx = self.nodes.len();
162 self.nodes.push(Vec::new());
163 let nidx = self.nested.len();
164 self.nested.push(Vec::new());
165 BindingsIdx(idx, nidx)
166 }
167
168 fn copy(&mut self, bindings: &BindingsIdx) -> BindingsIdx {
169 let idx = copy_parent(bindings.0, &mut self.nodes);
170 let nidx = copy_parent(bindings.1, &mut self.nested);
171 return BindingsIdx(idx, nidx);
172
173 fn copy_parent<T>(idx: usize, target: &mut Vec<Vec<LinkNode<T>>>) -> usize
174 where
175 T: Clone,
176 {
177 let new_idx = target.len();
178 let len = target[idx].len();
179 if len < 4 {
180 target.push(target[idx].clone())
181 } else {
182 target.push(vec![LinkNode::Parent { idx, len }]);
183 }
184 new_idx
185 }
186 }
187
188 fn push_empty(&mut self, idx: &mut BindingsIdx, var: &Symbol) {
189 self.nodes[idx.0].push(LinkNode::Node(Rc::new(BindingKind::Empty(var.clone()))));
190 }
191
192 fn push_optional(&mut self, idx: &mut BindingsIdx, var: &Symbol) {
193 self.nodes[idx.0].push(LinkNode::Node(Rc::new(BindingKind::Optional(var.clone()))));
194 }
195
196 fn push_fragment(&mut self, idx: &mut BindingsIdx, var: &Symbol, fragment: Fragment<'a>) {
197 self.nodes[idx.0]
198 .push(LinkNode::Node(Rc::new(BindingKind::Fragment(var.clone(), fragment))));
199 }
200
201 fn push_missing(&mut self, idx: &mut BindingsIdx, var: &Symbol, kind: MetaVarKind) {
202 self.nodes[idx.0].push(LinkNode::Node(Rc::new(BindingKind::Missing(var.clone(), kind))));
203 }
204
205 fn push_nested(&mut self, parent: &mut BindingsIdx, child: &BindingsIdx) {
206 let BindingsIdx(idx, nidx) = self.copy(child);
207 self.nodes[parent.0].push(LinkNode::Node(Rc::new(BindingKind::Nested(idx, nidx))));
208 }
209
210 fn push_default(&mut self, idx: &mut BindingsIdx) {
211 self.nested[idx.1].push(LinkNode::Node(idx.0));
212 let new_idx = self.nodes.len();
213 self.nodes.push(Vec::new());
214 idx.0 = new_idx;
215 }
216
217 fn build(self, idx: &BindingsIdx) -> Bindings<'a> {
218 self.build_inner(&self.nodes[idx.0])
219 }
220
221 fn build_inner(&self, link_nodes: &[LinkNode<Rc<BindingKind<'a>>>]) -> Bindings<'a> {
222 let mut bindings = Bindings::default();
223 let mut nodes = Vec::new();
224 self.collect_nodes(link_nodes, &mut nodes);
225
226 for cmd in nodes {
227 match cmd {
228 BindingKind::Empty(name) => {
229 bindings.push_empty(name.clone());
230 }
231 BindingKind::Optional(name) => {
232 bindings.push_optional(name.clone());
233 }
234 BindingKind::Fragment(name, fragment) => {
235 bindings.inner.insert(name.clone(), Binding::Fragment(fragment.clone()));
236 }
237 BindingKind::Missing(name, kind) => {
238 bindings.inner.insert(name.clone(), Binding::Missing(*kind));
239 }
240 BindingKind::Nested(idx, nested_idx) => {
241 let mut nested_nodes = Vec::new();
242 self.collect_nested(*idx, *nested_idx, &mut nested_nodes);
243
244 for (idx, iter) in nested_nodes.into_iter().enumerate() {
245 for (key, value) in &iter.inner {
246 let bindings = bindings
247 .inner
248 .entry(key.clone())
249 .or_insert_with(|| Binding::Nested(Vec::new()));
250
251 if let Binding::Nested(it) = bindings {
252 while it.len() < idx {
254 it.push(Binding::Nested(Vec::new()));
255 }
256 it.push(value.clone());
257 }
258 }
259 }
260 }
261 }
262 }
263
264 bindings
265 }
266
267 fn collect_nested_ref<'b>(
268 &'b self,
269 id: usize,
270 len: usize,
271 nested_refs: &mut Vec<&'b [LinkNode<Rc<BindingKind<'a>>>]>,
272 ) {
273 self.nested[id].iter().take(len).for_each(|it| match it {
274 LinkNode::Node(id) => nested_refs.push(&self.nodes[*id]),
275 LinkNode::Parent { idx, len } => self.collect_nested_ref(*idx, *len, nested_refs),
276 });
277 }
278
279 fn collect_nested(&self, idx: usize, nested_idx: usize, nested: &mut Vec<Bindings<'a>>) {
280 let last = &self.nodes[idx];
281 let mut nested_refs: Vec<&[_]> = Vec::new();
282 self.nested[nested_idx].iter().for_each(|it| match *it {
283 LinkNode::Node(idx) => nested_refs.push(&self.nodes[idx]),
284 LinkNode::Parent { idx, len } => self.collect_nested_ref(idx, len, &mut nested_refs),
285 });
286 nested_refs.push(last);
287 nested.extend(nested_refs.into_iter().map(|iter| self.build_inner(iter)));
288 }
289
290 fn collect_nodes_ref<'b>(
291 &'b self,
292 id: usize,
293 len: usize,
294 nodes: &mut Vec<&'b BindingKind<'a>>,
295 ) {
296 self.nodes[id].iter().take(len).for_each(|it| match it {
297 LinkNode::Node(it) => nodes.push(it),
298 LinkNode::Parent { idx, len } => self.collect_nodes_ref(*idx, *len, nodes),
299 });
300 }
301
302 fn collect_nodes<'b>(
303 &'b self,
304 link_nodes: &'b [LinkNode<Rc<BindingKind<'a>>>],
305 nodes: &mut Vec<&'b BindingKind<'a>>,
306 ) {
307 link_nodes.iter().for_each(|it| match it {
308 LinkNode::Node(it) => nodes.push(it),
309 LinkNode::Parent { idx, len } => self.collect_nodes_ref(*idx, *len, nodes),
310 });
311 }
312}
313
314#[derive(Debug, Clone)]
315struct MatchState<'t> {
316 dot: OpDelimitedIter<'t>,
318
319 stack: SmallVec<[OpDelimitedIter<'t>; 4]>,
324
325 up: Option<Box<MatchState<'t>>>,
328
329 sep: Option<Arc<Separator>>,
331
332 sep_kind: Option<RepeatKind>,
334
335 sep_matched: bool,
337
338 bindings: BindingsIdx,
340
341 meta_result: Option<(TtIter<'t, Span>, ExpandResult<Option<Fragment<'t>>>)>,
343
344 is_error: bool,
346}
347
348#[inline]
367fn match_loop_inner<'t>(
368 db: &dyn salsa::Database,
369 src: TtIter<'t, Span>,
370 stack: &[TtIter<'t, Span>],
371 res: &mut Match<'t>,
372 bindings_builder: &mut BindingsBuilder<'t>,
373 cur_items: &mut SmallVec<[MatchState<'t>; 1]>,
374 bb_items: &mut SmallVec<[MatchState<'t>; 1]>,
375 next_items: &mut Vec<MatchState<'t>>,
376 eof_items: &mut SmallVec<[MatchState<'t>; 1]>,
377 error_items: &mut SmallVec<[MatchState<'t>; 1]>,
378 delim_span: tt::DelimSpan<Span>,
379) {
380 macro_rules! try_push {
381 ($items: expr, $it:expr) => {
382 if $it.is_error {
383 error_items.push($it);
384 } else {
385 $items.push($it);
386 }
387 };
388 }
389
390 while let Some(mut item) = cur_items.pop() {
391 while item.dot.is_eof() {
392 match item.stack.pop() {
393 Some(frame) => {
394 item.dot = frame;
395 item.dot.next();
396 }
397 None => break,
398 }
399 }
400 let op = match item.dot.peek() {
401 None => {
402 if let Some(up) = &item.up {
404 if !item.sep_matched {
405 let mut new_pos = (**up).clone();
407 new_pos.bindings = bindings_builder.copy(&new_pos.bindings);
408 bindings_builder.push_nested(&mut new_pos.bindings, &item.bindings);
410
411 new_pos.dot.next();
413 new_pos.is_error = new_pos.is_error || item.is_error;
414 cur_items.push(new_pos);
415 }
416
417 if item.sep.is_some() && !item.sep_matched {
419 let sep = item.sep.as_ref().unwrap();
420 let mut fork = src.clone();
421 if expect_separator(&mut fork, sep) {
422 item.meta_result = Some((fork, ValueResult::ok(None)));
426 item.dot.next();
427 item.sep_matched = true;
429 try_push!(next_items, item);
430 }
431 }
432 else if item.sep_kind != Some(RepeatKind::ZeroOrOne) {
435 item.dot = item.dot.reset();
436 item.sep_matched = false;
437 bindings_builder.push_default(&mut item.bindings);
438 cur_items.push(item);
439 }
440 } else {
441 try_push!(eof_items, item);
444 }
445 continue;
446 }
447 Some(it) => it,
448 };
449
450 match op {
452 OpDelimited::Op(Op::Repeat { tokens, kind, separator }) => {
453 if matches!(kind, RepeatKind::ZeroOrMore | RepeatKind::ZeroOrOne) {
454 let mut new_item = item.clone();
455 new_item.bindings = bindings_builder.copy(&new_item.bindings);
456 new_item.dot.next();
457 collect_vars(
458 &mut |s| {
459 bindings_builder.push_empty(&mut new_item.bindings, &s);
460 },
461 tokens,
462 );
463 cur_items.push(new_item);
464 }
465 cur_items.push(MatchState {
466 dot: tokens.iter_delimited(delim_span),
467 stack: Default::default(),
468 up: Some(Box::new(item)),
469 sep: separator.clone(),
470 sep_kind: Some(*kind),
471 sep_matched: false,
472 bindings: bindings_builder.alloc(),
473 meta_result: None,
474 is_error: false,
475 })
476 }
477 OpDelimited::Op(Op::Subtree { tokens, delimiter }) => {
478 if let Ok((subtree, _)) = src.clone().expect_subtree()
479 && subtree.delimiter.kind == delimiter.kind
480 {
481 item.stack.push(item.dot);
482 item.dot = tokens.iter_delimited_with(*delimiter);
483 cur_items.push(item);
484 }
485 }
486 OpDelimited::Op(Op::Var { kind, name, .. }) => {
487 if let &Some(kind) = kind {
488 let mut fork = src.clone();
489 let match_res = match_meta_var(db, kind, &mut fork, delim_span);
490 match match_res.err {
491 None => {
492 if !match_res.value.is_empty() {
494 item.meta_result = Some((fork, match_res.map(Some)));
495 try_push!(bb_items, item);
496 } else {
497 bindings_builder.push_optional(&mut item.bindings, name);
498 item.dot.next();
499 cur_items.push(item);
500 }
501 }
502 Some(err) => {
503 res.add_err(err);
504 if !match_res.value.is_empty() {
505 bindings_builder.push_fragment(
506 &mut item.bindings,
507 name,
508 match_res.value,
509 )
510 } else {
511 bindings_builder.push_missing(&mut item.bindings, name, kind)
512 }
513 item.is_error = true;
514 error_items.push(item);
515 }
516 }
517 }
518 }
519 OpDelimited::Op(Op::Literal(lhs)) => {
520 if let Ok(rhs) = src.clone().expect_leaf() {
521 if matches!(rhs, tt::Leaf::Literal(it) if it.symbol == lhs.symbol) {
522 item.dot.next();
523 } else {
524 res.add_err(ExpandError::new(
525 *rhs.span(),
526 ExpandErrorKind::UnexpectedToken,
527 ));
528 item.is_error = true;
529 }
530 } else {
531 res.add_err(ExpandError::binding_error(
532 src.clone().next().map_or(delim_span.close, |it| it.first_span()),
533 format!("expected literal: `{lhs}`"),
534 ));
535 item.is_error = true;
536 }
537 try_push!(next_items, item);
538 }
539 OpDelimited::Op(Op::Ident(lhs)) => {
540 if let Ok(rhs) = src.clone().expect_leaf() {
541 if matches!(rhs, tt::Leaf::Ident(it) if it.sym == lhs.sym) {
542 item.dot.next();
543 } else {
544 res.add_err(ExpandError::new(
545 *rhs.span(),
546 ExpandErrorKind::UnexpectedToken,
547 ));
548 item.is_error = true;
549 }
550 } else {
551 res.add_err(ExpandError::binding_error(
552 src.clone().next().map_or(delim_span.close, |it| it.first_span()),
553 format!("expected ident: `{lhs}`"),
554 ));
555 item.is_error = true;
556 }
557 try_push!(next_items, item);
558 }
559 OpDelimited::Op(Op::Punct(lhs)) => {
560 let mut fork = src.clone();
561 let error = if let Ok(rhs) = fork.expect_glued_punct() {
562 let first_is_single_quote = rhs[0].char == '\'';
563 let lhs = lhs.iter().map(|it| it.char);
564 let rhs_ = rhs.iter().map(|it| it.char);
565 if lhs.clone().eq(rhs_) {
566 item.meta_result = Some((fork, ValueResult::ok(None)));
570 item.dot.next();
571 next_items.push(item);
572 continue;
573 }
574
575 if first_is_single_quote {
576 ExpandError::new(
579 rhs.get(1).map_or(rhs[0].span, |it| it.span),
580 ExpandErrorKind::UnexpectedToken,
581 )
582 } else {
583 let lhs = lhs.collect::<String>();
584 ExpandError::binding_error(rhs[0].span, format!("expected punct: `{lhs}`"))
585 }
586 } else {
587 ExpandError::new(
588 src.clone().next().map_or(delim_span.close, |it| it.first_span()),
589 ExpandErrorKind::UnexpectedToken,
590 )
591 };
592
593 res.add_err(error);
594 item.is_error = true;
595 error_items.push(item);
596 }
597 OpDelimited::Op(
598 Op::Ignore { .. }
599 | Op::Index { .. }
600 | Op::Count { .. }
601 | Op::Len { .. }
602 | Op::Concat { .. },
603 ) => {
604 stdx::never!("metavariable expression in lhs found");
605 }
606 OpDelimited::Open => {
607 if matches!(src.peek(), Some(TtElement::Subtree(..))) {
608 item.dot.next();
609 try_push!(next_items, item);
610 }
611 }
612 OpDelimited::Close => {
613 let is_delim_closed = src.is_empty() && !stack.is_empty();
614 if is_delim_closed {
615 item.dot.next();
616 try_push!(next_items, item);
617 }
618 }
619 }
620 }
621}
622
623fn match_loop<'t>(
624 db: &dyn salsa::Database,
625 pattern: &'t MetaTemplate,
626 src: &'t tt::TopSubtree<Span>,
627) -> Match<'t> {
628 let span = src.top_subtree().delimiter.delim_span();
629 let mut src = src.iter();
630 let mut stack: SmallVec<[TtIter<'_, Span>; 1]> = SmallVec::new();
631 let mut res = Match::default();
632 let mut error_recover_item = None;
633
634 let mut bindings_builder = BindingsBuilder::default();
635
636 let mut cur_items = smallvec![MatchState {
637 dot: pattern.iter_delimited(span),
638 stack: Default::default(),
639 up: None,
640 sep: None,
641 sep_kind: None,
642 sep_matched: false,
643 bindings: bindings_builder.alloc(),
644 is_error: false,
645 meta_result: None,
646 }];
647
648 let mut next_items = vec![];
649
650 loop {
651 let mut bb_items = SmallVec::new();
652 let mut eof_items = SmallVec::new();
653 let mut error_items = SmallVec::new();
654
655 stdx::always!(next_items.is_empty());
656
657 match_loop_inner(
658 db,
659 src.clone(),
660 &stack,
661 &mut res,
662 &mut bindings_builder,
663 &mut cur_items,
664 &mut bb_items,
665 &mut next_items,
666 &mut eof_items,
667 &mut error_items,
668 span,
669 );
670 stdx::always!(cur_items.is_empty());
671
672 if !error_items.is_empty() {
673 error_recover_item = error_items.pop().map(|it| it.bindings);
674 } else if let [state, ..] = &*eof_items {
675 error_recover_item = Some(state.bindings.clone());
676 }
677
678 if src.is_empty() && stack.is_empty() {
682 if let [state] = &*eof_items {
683 res = Match::default();
685 res.bindings = bindings_builder.build(&state.bindings);
686 } else {
687 if let Some(item) = error_recover_item {
689 res.bindings = bindings_builder.build(&item);
690 }
691 res.add_err(ExpandError::new(span.open, ExpandErrorKind::UnexpectedToken));
692 }
693 return res;
694 }
695
696 let has_leftover_tokens = (bb_items.is_empty() && next_items.is_empty())
702 || !(bb_items.is_empty() || next_items.is_empty())
703 || bb_items.len() > 1;
704 if has_leftover_tokens {
705 res.unmatched_tts += src.remaining().flat_tokens().len();
706 res.add_err(ExpandError::new(span.open, ExpandErrorKind::LeftoverTokens));
707
708 if let Some(error_recover_item) = error_recover_item {
709 res.bindings = bindings_builder.build(&error_recover_item);
710 }
711 return res;
712 }
713 else if !next_items.is_empty() {
715 if let Some((iter, _)) = next_items[0].meta_result.take() {
716 src = iter;
723 for item in next_items.iter_mut() {
724 item.meta_result = None;
725 }
726 } else {
727 match src.next() {
728 Some(TtElement::Subtree(_, subtree_iter)) => {
729 stack.push(src.clone());
730 src = subtree_iter;
731 }
732 None => {
733 if let Some(iter) = stack.pop() {
734 src = iter;
735 }
736 }
737 _ => (),
738 }
739 }
740 cur_items.extend(next_items.drain(..));
742 }
743 else {
746 stdx::always!(bb_items.len() == 1);
747 let mut item = bb_items.pop().unwrap();
748
749 if let Some(OpDelimited::Op(Op::Var { name, .. })) = item.dot.peek() {
750 let (iter, match_res) = item.meta_result.take().unwrap();
751 match match_res.value {
752 Some(fragment) => {
753 bindings_builder.push_fragment(&mut item.bindings, name, fragment);
754 }
755 None if match_res.err.is_none() => {
756 bindings_builder.push_optional(&mut item.bindings, name);
757 }
758 None => {}
759 }
760 if let Some(err) = match_res.err {
761 res.add_err(err);
762 }
763 src = iter.clone();
764 item.dot.next();
765 } else {
766 unreachable!()
767 }
768 cur_items.push(item);
769 }
770 stdx::always!(!cur_items.is_empty());
771 }
772}
773
774fn match_meta_var<'t>(
775 db: &dyn salsa::Database,
776 kind: MetaVarKind,
777 input: &mut TtIter<'t, Span>,
778 delim_span: DelimSpan<Span>,
779) -> ExpandResult<Fragment<'t>> {
780 let fragment = match kind {
781 MetaVarKind::Path => {
782 return expect_fragment(db, input, parser::PrefixEntryPoint::Path, delim_span)
783 .map(Fragment::Path);
784 }
785 MetaVarKind::Expr(expr) => {
786 match input.peek() {
795 Some(TtElement::Leaf(tt::Leaf::Ident(it))) => {
796 let is_err = if it.is_raw.no() && matches!(expr, ExprKind::Expr2021) {
797 it.sym == sym::underscore || it.sym == sym::let_ || it.sym == sym::const_
798 } else {
799 it.sym == sym::let_
800 };
801 if is_err {
802 return ExpandResult::only_err(ExpandError::new(
803 it.span,
804 ExpandErrorKind::NoMatchingRule,
805 ));
806 }
807 }
808 _ => {}
809 };
810 return expect_fragment(db, input, parser::PrefixEntryPoint::Expr, delim_span)
811 .map(Fragment::Expr);
812 }
813 MetaVarKind::Ident | MetaVarKind::Tt | MetaVarKind::Lifetime | MetaVarKind::Literal => {
814 let span = input.next_span();
815 let savepoint = input.savepoint();
816 let err = match kind {
817 MetaVarKind::Ident => input.expect_ident().map(drop).map_err(|()| {
818 ExpandError::binding_error(span.unwrap_or(delim_span.close), "expected ident")
819 }),
820 MetaVarKind::Tt => expect_tt(input).map_err(|()| {
821 ExpandError::binding_error(
822 span.unwrap_or(delim_span.close),
823 "expected token tree",
824 )
825 }),
826 MetaVarKind::Lifetime => expect_lifetime(input).map(drop).map_err(|()| {
827 ExpandError::binding_error(
828 span.unwrap_or(delim_span.close),
829 "expected lifetime",
830 )
831 }),
832 MetaVarKind::Literal => {
833 eat_char(input, '-');
834 input.expect_literal().map(drop).map_err(|()| {
835 ExpandError::binding_error(
836 span.unwrap_or(delim_span.close),
837 "expected literal",
838 )
839 })
840 }
841 _ => unreachable!(),
842 }
843 .err();
844 let tt_result = input.from_savepoint(savepoint);
845 return ValueResult { value: Fragment::Tokens(tt_result), err };
846 }
847 MetaVarKind::Ty => parser::PrefixEntryPoint::Ty,
848 MetaVarKind::Pat => parser::PrefixEntryPoint::PatTop,
849 MetaVarKind::PatParam => parser::PrefixEntryPoint::Pat,
850 MetaVarKind::Stmt => parser::PrefixEntryPoint::Stmt,
851 MetaVarKind::Block => parser::PrefixEntryPoint::Block,
852 MetaVarKind::Meta => parser::PrefixEntryPoint::MetaItem,
853 MetaVarKind::Item => parser::PrefixEntryPoint::Item,
854 MetaVarKind::Vis => parser::PrefixEntryPoint::Vis,
855 };
856 expect_fragment(db, input, fragment, delim_span).map(Fragment::Tokens)
857}
858
859fn collect_vars(collector_fun: &mut impl FnMut(Symbol), pattern: &MetaTemplate) {
860 for op in pattern.iter() {
861 match op {
862 Op::Var { name, .. } => collector_fun(name.clone()),
863 Op::Subtree { tokens, .. } => collect_vars(collector_fun, tokens),
864 Op::Repeat { tokens, .. } => collect_vars(collector_fun, tokens),
865 Op::Literal(_) | Op::Ident(_) | Op::Punct(_) => {}
866 Op::Ignore { .. }
867 | Op::Index { .. }
868 | Op::Count { .. }
869 | Op::Len { .. }
870 | Op::Concat { .. } => {
871 stdx::never!("metavariable expression in lhs found");
872 }
873 }
874 }
875}
876impl MetaTemplate {
877 fn iter_delimited_with(&self, delimiter: tt::Delimiter<Span>) -> OpDelimitedIter<'_> {
878 OpDelimitedIter { inner: &self.0, idx: 0, delimited: delimiter }
879 }
880 fn iter_delimited(&self, span: tt::DelimSpan<Span>) -> OpDelimitedIter<'_> {
881 OpDelimitedIter {
882 inner: &self.0,
883 idx: 0,
884 delimited: tt::Delimiter::invisible_delim_spanned(span),
885 }
886 }
887}
888
889#[derive(Debug, Clone, Copy)]
890enum OpDelimited<'a> {
891 Op(&'a Op),
892 Open,
893 Close,
894}
895
896#[derive(Debug, Clone, Copy)]
897struct OpDelimitedIter<'a> {
898 inner: &'a [Op],
899 delimited: tt::Delimiter<Span>,
900 idx: usize,
901}
902
903impl<'a> OpDelimitedIter<'a> {
904 fn is_eof(&self) -> bool {
905 let len = self.inner.len()
906 + if self.delimited.kind != tt::DelimiterKind::Invisible { 2 } else { 0 };
907 self.idx >= len
908 }
909
910 fn peek(&self) -> Option<OpDelimited<'a>> {
911 match self.delimited.kind {
912 tt::DelimiterKind::Invisible => self.inner.get(self.idx).map(OpDelimited::Op),
913 _ => match self.idx {
914 0 => Some(OpDelimited::Open),
915 i if i == self.inner.len() + 1 => Some(OpDelimited::Close),
916 i => self.inner.get(i - 1).map(OpDelimited::Op),
917 },
918 }
919 }
920
921 fn reset(&self) -> Self {
922 Self { inner: self.inner, idx: 0, delimited: self.delimited }
923 }
924}
925
926impl<'a> Iterator for OpDelimitedIter<'a> {
927 type Item = OpDelimited<'a>;
928
929 fn next(&mut self) -> Option<Self::Item> {
930 let res = self.peek();
931 self.idx += 1;
932 res
933 }
934
935 fn size_hint(&self) -> (usize, Option<usize>) {
936 let len = self.inner.len()
937 + if self.delimited.kind != tt::DelimiterKind::Invisible { 2 } else { 0 };
938 let remain = len.saturating_sub(self.idx);
939 (remain, Some(remain))
940 }
941}
942
943fn expect_separator<S: Copy>(iter: &mut TtIter<'_, S>, separator: &Separator) -> bool {
944 let mut fork = iter.clone();
945 let ok = match separator {
946 Separator::Ident(lhs) => match fork.expect_ident_or_underscore() {
947 Ok(rhs) => rhs.sym == lhs.sym,
948 Err(_) => false,
949 },
950 Separator::Literal(lhs) => match fork.expect_literal() {
951 Ok(rhs) => match rhs {
952 tt::Leaf::Literal(rhs) => rhs.symbol == lhs.symbol,
953 tt::Leaf::Ident(rhs) => rhs.sym == lhs.symbol,
954 tt::Leaf::Punct(_) => false,
955 },
956 Err(_) => false,
957 },
958 Separator::Puncts(lhs) => match fork.expect_glued_punct() {
959 Ok(rhs) => {
960 let lhs = lhs.iter().map(|it| it.char);
961 let rhs = rhs.iter().map(|it| it.char);
962 lhs.eq(rhs)
963 }
964 Err(_) => false,
965 },
966 Separator::Lifetime(_punct, ident) => match expect_lifetime(&mut fork) {
967 Ok(lifetime) => lifetime.sym == ident.sym,
968 Err(_) => false,
969 },
970 };
971 if ok {
972 *iter = fork;
973 }
974 ok
975}
976
977fn expect_tt<S: Copy>(iter: &mut TtIter<'_, S>) -> Result<(), ()> {
978 if let Some(TtElement::Leaf(tt::Leaf::Punct(punct))) = iter.peek() {
979 if punct.char == '\'' {
980 expect_lifetime(iter)?;
981 } else {
982 iter.expect_glued_punct()?;
983 }
984 } else {
985 iter.next().ok_or(())?;
986 }
987 Ok(())
988}
989
990fn expect_lifetime<'a, S: Copy>(iter: &mut TtIter<'a, S>) -> Result<&'a tt::Ident<S>, ()> {
991 let punct = iter.expect_single_punct()?;
992 if punct.char != '\'' {
993 return Err(());
994 }
995 iter.expect_ident_or_underscore()
996}
997
998fn eat_char<S: Copy>(iter: &mut TtIter<'_, S>, c: char) {
999 if matches!(iter.peek(), Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char, .. }))) if *char == c)
1000 {
1001 iter.next().expect("already peeked");
1002 }
1003}