1 //! An NFA-based parser, which is porting from rustc mbe parsing code
3 //! See <https://github.com/rust-lang/rust/blob/70b18bc2cbac4712020019f5bf57c00905373205/compiler/rustc_expand/src/mbe/macro_parser.rs>
4 //! Here is a quick intro to how the parser works, copied from rustc:
6 //! A 'position' is a dot in the middle of a matcher, usually represented as a
7 //! dot. For example `· a $( a )* a b` is a position, as is `a $( · a )* a b`.
9 //! The parser walks through the input a character at a time, maintaining a list
10 //! of threads consistent with the current position in the input string: `cur_items`.
12 //! As it processes them, it fills up `eof_items` with threads that would be valid if
13 //! the macro invocation is now over, `bb_items` with threads that are waiting on
14 //! a Rust non-terminal like `$e:expr`, and `next_items` with threads that are waiting
15 //! on a particular token. Most of the logic concerns moving the · through the
16 //! repetitions indicated by Kleene stars. The rules for moving the · without
17 //! consuming any input are called epsilon transitions. It only advances or calls
18 //! out to the real Rust parser when no `cur_items` threads remain.
23 //! Start parsing a a a a b against [· a $( a )* a b].
25 //! Remaining input: a a a a b
26 //! next: [· a $( a )* a b]
28 //! - - - Advance over an a. - - -
30 //! Remaining input: a a a b
31 //! cur: [a · $( a )* a b]
32 //! Descend/Skip (first item).
33 //! next: [a $( · a )* a b] [a $( a )* · a b].
35 //! - - - Advance over an a. - - -
37 //! Remaining input: a a b
38 //! cur: [a $( a · )* a b] [a $( a )* a · b]
39 //! Follow epsilon transition: Finish/Repeat (first item)
40 //! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]
42 //! - - - Advance over an a. - - - (this looks exactly like the last step)
44 //! Remaining input: a b
45 //! cur: [a $( a · )* a b] [a $( a )* a · b]
46 //! Follow epsilon transition: Finish/Repeat (first item)
47 //! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]
49 //! - - - Advance over an a. - - - (this looks exactly like the last step)
51 //! Remaining input: b
52 //! cur: [a $( a · )* a b] [a $( a )* a · b]
53 //! Follow epsilon transition: Finish/Repeat (first item)
54 //! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]
56 //! - - - Advance over a b. - - -
58 //! Remaining input: ''
59 //! eof: [a $( a )* a b ·]
64 use smallvec
::{smallvec, SmallVec}
;
68 expander
::{Binding, Bindings, ExpandResult, Fragment}
,
69 parser
::{MetaVarKind, Op, RepeatKind, Separator}
,
72 ExpandError
, MetaTemplate
, ValueResult
,
76 fn push_optional(&mut self, name
: &SmolStr
) {
77 // FIXME: Do we have a better way to represent an empty token ?
78 // Insert an empty subtree for empty token
80 tt
::Subtree { delimiter: tt::Delimiter::unspecified(), token_trees: vec![] }
.into();
81 self.inner
.insert(name
.clone(), Binding
::Fragment(Fragment
::Tokens(tt
)));
84 fn push_empty(&mut self, name
: &SmolStr
) {
85 self.inner
.insert(name
.clone(), Binding
::Empty
);
88 fn bindings(&self) -> impl Iterator
<Item
= &Binding
> {
93 #[derive(Clone, Debug, Default, PartialEq, Eq)]
94 pub(super) struct Match
{
95 pub(super) bindings
: Bindings
,
96 /// We currently just keep the first error and count the rest to compare matches.
97 pub(super) err
: Option
<ExpandError
>,
98 pub(super) err_count
: usize,
99 /// How many top-level token trees were left to match.
100 pub(super) unmatched_tts
: usize,
101 /// The number of bound variables
102 pub(super) bound_count
: usize,
106 fn add_err(&mut self, err
: ExpandError
) {
107 let prev_err
= self.err
.take();
108 self.err
= prev_err
.or(Some(err
));
113 /// Matching errors are added to the `Match`.
114 pub(super) fn match_(pattern
: &MetaTemplate
, input
: &tt
::Subtree
) -> Match
{
115 let mut res
= match_loop(pattern
, input
);
116 res
.bound_count
= count(res
.bindings
.bindings());
119 fn count
<'a
>(bindings
: impl Iterator
<Item
= &'a Binding
>) -> usize {
122 Binding
::Fragment(_
) => 1,
124 Binding
::Missing(_
) => 1,
125 Binding
::Nested(it
) => count(it
.iter()),
131 #[derive(Debug, Clone)]
135 Fragment(SmolStr
, Fragment
),
136 Missing(SmolStr
, MetaVarKind
),
137 Nested(usize, usize),
140 #[derive(Debug, Clone)]
141 struct BindingsIdx(usize, usize);
143 #[derive(Debug, Clone)]
146 Parent { idx: usize, len: usize }
,
150 struct BindingsBuilder
{
151 nodes
: Vec
<Vec
<LinkNode
<Rc
<BindingKind
>>>>,
152 nested
: Vec
<Vec
<LinkNode
<usize>>>,
155 impl BindingsBuilder
{
156 fn alloc(&mut self) -> BindingsIdx
{
157 let idx
= self.nodes
.len();
158 self.nodes
.push(Vec
::new());
159 let nidx
= self.nested
.len();
160 self.nested
.push(Vec
::new());
161 BindingsIdx(idx
, nidx
)
164 fn copy(&mut self, bindings
: &BindingsIdx
) -> BindingsIdx
{
165 let idx
= copy_parent(bindings
.0, &mut self.nodes
);
166 let nidx
= copy_parent(bindings
.1, &mut self.nested
);
167 return BindingsIdx(idx
, nidx
);
169 fn copy_parent
<T
>(idx
: usize, target
: &mut Vec
<Vec
<LinkNode
<T
>>>) -> usize
173 let new_idx
= target
.len();
174 let len
= target
[idx
].len();
176 target
.push(target
[idx
].clone())
178 target
.push(vec
![LinkNode
::Parent { idx, len }
]);
184 fn push_empty(&mut self, idx
: &mut BindingsIdx
, var
: &SmolStr
) {
185 self.nodes
[idx
.0].push(LinkNode
::Node(Rc
::new(BindingKind
::Empty(var
.clone()))));
188 fn push_optional(&mut self, idx
: &mut BindingsIdx
, var
: &SmolStr
) {
189 self.nodes
[idx
.0].push(LinkNode
::Node(Rc
::new(BindingKind
::Optional(var
.clone()))));
192 fn push_fragment(&mut self, idx
: &mut BindingsIdx
, var
: &SmolStr
, fragment
: Fragment
) {
194 .push(LinkNode
::Node(Rc
::new(BindingKind
::Fragment(var
.clone(), fragment
))));
197 fn push_missing(&mut self, idx
: &mut BindingsIdx
, var
: &SmolStr
, kind
: MetaVarKind
) {
198 self.nodes
[idx
.0].push(LinkNode
::Node(Rc
::new(BindingKind
::Missing(var
.clone(), kind
))));
201 fn push_nested(&mut self, parent
: &mut BindingsIdx
, child
: &BindingsIdx
) {
202 let BindingsIdx(idx
, nidx
) = self.copy(child
);
203 self.nodes
[parent
.0].push(LinkNode
::Node(Rc
::new(BindingKind
::Nested(idx
, nidx
))));
206 fn push_default(&mut self, idx
: &mut BindingsIdx
) {
207 self.nested
[idx
.1].push(LinkNode
::Node(idx
.0));
208 let new_idx
= self.nodes
.len();
209 self.nodes
.push(Vec
::new());
213 fn build(self, idx
: &BindingsIdx
) -> Bindings
{
214 self.build_inner(&self.nodes
[idx
.0])
217 fn build_inner(&self, link_nodes
: &[LinkNode
<Rc
<BindingKind
>>]) -> Bindings
{
218 let mut bindings
= Bindings
::default();
219 let mut nodes
= Vec
::new();
220 self.collect_nodes(link_nodes
, &mut nodes
);
224 BindingKind
::Empty(name
) => {
225 bindings
.push_empty(name
);
227 BindingKind
::Optional(name
) => {
228 bindings
.push_optional(name
);
230 BindingKind
::Fragment(name
, fragment
) => {
231 bindings
.inner
.insert(name
.clone(), Binding
::Fragment(fragment
.clone()));
233 BindingKind
::Missing(name
, kind
) => {
234 bindings
.inner
.insert(name
.clone(), Binding
::Missing(*kind
));
236 BindingKind
::Nested(idx
, nested_idx
) => {
237 let mut nested_nodes
= Vec
::new();
238 self.collect_nested(*idx
, *nested_idx
, &mut nested_nodes
);
240 for (idx
, iter
) in nested_nodes
.into_iter().enumerate() {
241 for (key
, value
) in &iter
.inner
{
242 let bindings
= bindings
245 .or_insert_with(|| Binding
::Nested(Vec
::new()));
247 if let Binding
::Nested(it
) = bindings
{
248 // insert empty nested bindings before this one
249 while it
.len() < idx
{
250 it
.push(Binding
::Nested(Vec
::new()));
252 it
.push(value
.clone());
263 fn collect_nested_ref
<'a
>(
267 nested_refs
: &mut Vec
<&'a
[LinkNode
<Rc
<BindingKind
>>]>,
269 self.nested
[id
].iter().take(len
).for_each(|it
| match it
{
270 LinkNode
::Node(id
) => nested_refs
.push(&self.nodes
[*id
]),
271 LinkNode
::Parent { idx, len }
=> self.collect_nested_ref(*idx
, *len
, nested_refs
),
275 fn collect_nested(&self, idx
: usize, nested_idx
: usize, nested
: &mut Vec
<Bindings
>) {
276 let last
= &self.nodes
[idx
];
277 let mut nested_refs
: Vec
<&[_
]> = Vec
::new();
278 self.nested
[nested_idx
].iter().for_each(|it
| match *it
{
279 LinkNode
::Node(idx
) => nested_refs
.push(&self.nodes
[idx
]),
280 LinkNode
::Parent { idx, len }
=> self.collect_nested_ref(idx
, len
, &mut nested_refs
),
282 nested_refs
.push(last
);
283 nested
.extend(nested_refs
.into_iter().map(|iter
| self.build_inner(iter
)));
286 fn collect_nodes_ref
<'a
>(&'a
self, id
: usize, len
: usize, nodes
: &mut Vec
<&'a BindingKind
>) {
287 self.nodes
[id
].iter().take(len
).for_each(|it
| match it
{
288 LinkNode
::Node(it
) => nodes
.push(it
),
289 LinkNode
::Parent { idx, len }
=> self.collect_nodes_ref(*idx
, *len
, nodes
),
293 fn collect_nodes
<'a
>(
295 link_nodes
: &'a
[LinkNode
<Rc
<BindingKind
>>],
296 nodes
: &mut Vec
<&'a BindingKind
>,
298 link_nodes
.iter().for_each(|it
| match it
{
299 LinkNode
::Node(it
) => nodes
.push(it
),
300 LinkNode
::Parent { idx, len }
=> self.collect_nodes_ref(*idx
, *len
, nodes
),
305 #[derive(Debug, Clone)]
306 struct MatchState
<'t
> {
307 /// The position of the "dot" in this matcher
308 dot
: OpDelimitedIter
<'t
>,
310 /// Token subtree stack
311 /// When matching against matchers with nested delimited submatchers (e.g., `pat ( pat ( .. )
312 /// pat ) pat`), we need to keep track of the matchers we are descending into. This stack does
313 /// that where the bottom of the stack is the outermost matcher.
314 stack
: SmallVec
<[OpDelimitedIter
<'t
>; 4]>,
316 /// The "parent" matcher position if we are in a repetition. That is, the matcher position just
317 /// before we enter the repetition.
318 up
: Option
<Box
<MatchState
<'t
>>>,
320 /// The separator if we are in a repetition.
321 sep
: Option
<Separator
>,
323 /// The KleeneOp of this sequence if we are in a repetition.
324 sep_kind
: Option
<RepeatKind
>,
326 /// Whether we already matched separator token.
329 /// Matched meta variables bindings
330 bindings
: BindingsIdx
,
332 /// Cached result of meta variable parsing
333 meta_result
: Option
<(TtIter
<'t
>, ExpandResult
<Option
<Fragment
>>)>,
335 /// Is error occuried in this state, will `poised` to "parent"
339 /// Process the matcher positions of `cur_items` until it is empty. In the process, this will
340 /// produce more items in `next_items`, `eof_items`, and `bb_items`.
342 /// For more info about the how this happens, see the module-level doc comments and the inline
343 /// comments of this function.
347 /// - `src`: the current token of the parser.
348 /// - `stack`: the "parent" frames of the token tree
349 /// - `res`: the match result to store errors
350 /// - `cur_items`: the set of current items to be processed. This should be empty by the end of a
351 /// successful execution of this function.
352 /// - `next_items`: the set of newly generated items. These are used to replenish `cur_items` in
353 /// the function `parse`.
354 /// - `eof_items`: the set of items that would be valid if this was the EOF.
355 /// - `bb_items`: the set of items that are waiting for the black-box parser.
356 /// - `error_items`: the set of items in errors, used for error-resilient parsing
357 fn match_loop_inner
<'t
>(
359 stack
: &[TtIter
<'t
>],
361 bindings_builder
: &mut BindingsBuilder
,
362 cur_items
: &mut SmallVec
<[MatchState
<'t
>; 1]>,
363 bb_items
: &mut SmallVec
<[MatchState
<'t
>; 1]>,
364 next_items
: &mut Vec
<MatchState
<'t
>>,
365 eof_items
: &mut SmallVec
<[MatchState
<'t
>; 1]>,
366 error_items
: &mut SmallVec
<[MatchState
<'t
>; 1]>,
368 macro_rules
! try_push
{
369 ($items
: expr
, $it
:expr
) => {
371 error_items
.push($it
);
378 while let Some(mut item
) = cur_items
.pop() {
379 while item
.dot
.is_eof() {
380 match item
.stack
.pop() {
388 let op
= match item
.dot
.peek() {
390 // We are at or past the end of the matcher of `item`.
391 if let Some(up
) = &item
.up
{
392 if !item
.sep_matched
{
393 // Get the `up` matcher
394 let mut new_pos
= (**up
).clone();
395 new_pos
.bindings
= bindings_builder
.copy(&new_pos
.bindings
);
396 // Add matches from this repetition to the `matches` of `up`
397 bindings_builder
.push_nested(&mut new_pos
.bindings
, &item
.bindings
);
399 // Move the "dot" past the repetition in `up`
401 new_pos
.is_error
= new_pos
.is_error
|| item
.is_error
;
402 cur_items
.push(new_pos
);
405 // Check if we need a separator.
406 if item
.sep
.is_some() && !item
.sep_matched
{
407 let sep
= item
.sep
.as_ref().unwrap();
408 let mut fork
= src
.clone();
409 if fork
.expect_separator(sep
) {
410 // HACK: here we use `meta_result` to pass `TtIter` back to caller because
411 // it might have been advanced multiple times. `ValueResult` is
413 item
.meta_result
= Some((fork
, ValueResult
::ok(None
)));
415 // item.sep_parsed = Some(sep_len);
416 item
.sep_matched
= true;
417 try_push
!(next_items
, item
);
420 // We don't need a separator. Move the "dot" back to the beginning of the matcher
421 // and try to match again UNLESS we are only allowed to have _one_ repetition.
422 else if item
.sep_kind
!= Some(RepeatKind
::ZeroOrOne
) {
423 item
.dot
= item
.dot
.reset();
424 item
.sep_matched
= false;
425 bindings_builder
.push_default(&mut item
.bindings
);
426 cur_items
.push(item
);
429 // If we are not in a repetition, then being at the end of a matcher means that we have
430 // reached the potential end of the input.
431 try_push
!(eof_items
, item
);
438 // We are in the middle of a matcher.
440 OpDelimited
::Op(Op
::Repeat { tokens, kind, separator }
) => {
441 if matches
!(kind
, RepeatKind
::ZeroOrMore
| RepeatKind
::ZeroOrOne
) {
442 let mut new_item
= item
.clone();
443 new_item
.bindings
= bindings_builder
.copy(&new_item
.bindings
);
447 bindings_builder
.push_empty(&mut new_item
.bindings
, &s
);
451 cur_items
.push(new_item
);
453 cur_items
.push(MatchState
{
454 dot
: tokens
.iter_delimited(None
),
455 stack
: Default
::default(),
456 up
: Some(Box
::new(item
)),
457 sep
: separator
.clone(),
458 sep_kind
: Some(*kind
),
460 bindings
: bindings_builder
.alloc(),
465 OpDelimited
::Op(Op
::Subtree { tokens, delimiter }
) => {
466 if let Ok(subtree
) = src
.clone().expect_subtree() {
467 if subtree
.delimiter
.kind
== delimiter
.kind
{
468 item
.stack
.push(item
.dot
);
469 item
.dot
= tokens
.iter_delimited(Some(delimiter
));
470 cur_items
.push(item
);
474 OpDelimited
::Op(Op
::Var { kind, name, .. }
) => {
475 if let &Some(kind
) = kind
{
476 let mut fork
= src
.clone();
477 let match_res
= match_meta_var(kind
, &mut fork
);
478 match match_res
.err
{
480 // Some meta variables are optional (e.g. vis)
481 if match_res
.value
.is_some() {
482 item
.meta_result
= Some((fork
, match_res
));
483 try_push
!(bb_items
, item
);
485 bindings_builder
.push_optional(&mut item
.bindings
, name
);
487 cur_items
.push(item
);
492 match match_res
.value
{
493 Some(fragment
) => bindings_builder
.push_fragment(
499 bindings_builder
.push_missing(&mut item
.bindings
, name
, kind
)
502 item
.is_error
= true;
503 error_items
.push(item
);
508 OpDelimited
::Op(Op
::Literal(lhs
)) => {
509 if let Ok(rhs
) = src
.clone().expect_leaf() {
510 if matches
!(rhs
, tt
::Leaf
::Literal(it
) if it
.text
== lhs
.text
) {
513 res
.add_err(ExpandError
::UnexpectedToken
);
514 item
.is_error
= true;
517 res
.add_err(ExpandError
::binding_error(format
!("expected literal: `{lhs}`")));
518 item
.is_error
= true;
520 try_push
!(next_items
, item
);
522 OpDelimited
::Op(Op
::Ident(lhs
)) => {
523 if let Ok(rhs
) = src
.clone().expect_leaf() {
524 if matches
!(rhs
, tt
::Leaf
::Ident(it
) if it
.text
== lhs
.text
) {
527 res
.add_err(ExpandError
::UnexpectedToken
);
528 item
.is_error
= true;
531 res
.add_err(ExpandError
::binding_error(format
!("expected ident: `{lhs}`")));
532 item
.is_error
= true;
534 try_push
!(next_items
, item
);
536 OpDelimited
::Op(Op
::Punct(lhs
)) => {
537 let mut fork
= src
.clone();
538 let error
= if let Ok(rhs
) = fork
.expect_glued_punct() {
539 let first_is_single_quote
= rhs
[0].char == '
\''
;
540 let lhs
= lhs
.iter().map(|it
| it
.char);
541 let rhs
= rhs
.iter().map(|it
| it
.char);
542 if lhs
.clone().eq(rhs
) {
543 // HACK: here we use `meta_result` to pass `TtIter` back to caller because
544 // it might have been advanced multiple times. `ValueResult` is
546 item
.meta_result
= Some((fork
, ValueResult
::ok(None
)));
548 next_items
.push(item
);
552 if first_is_single_quote
{
553 // If the first punct token is a single quote, that's a part of a lifetime
554 // ident, not a punct.
555 ExpandError
::UnexpectedToken
557 let lhs
: SmolStr
= lhs
.collect();
558 ExpandError
::binding_error(format
!("expected punct: `{lhs}`"))
561 ExpandError
::UnexpectedToken
565 item
.is_error
= true;
566 error_items
.push(item
);
568 OpDelimited
::Op(Op
::Ignore { .. }
| Op
::Index { .. }
) => {}
569 OpDelimited
::Open
=> {
570 if matches
!(src
.peek_n(0), Some(tt
::TokenTree
::Subtree(..))) {
572 try_push
!(next_items
, item
);
575 OpDelimited
::Close
=> {
576 let is_delim_closed
= src
.peek_n(0).is_none() && !stack
.is_empty();
579 try_push
!(next_items
, item
);
586 fn match_loop(pattern
: &MetaTemplate
, src
: &tt
::Subtree
) -> Match
{
587 let mut src
= TtIter
::new(src
);
588 let mut stack
: SmallVec
<[TtIter
<'_
>; 1]> = SmallVec
::new();
589 let mut res
= Match
::default();
590 let mut error_recover_item
= None
;
592 let mut bindings_builder
= BindingsBuilder
::default();
594 let mut cur_items
= smallvec
![MatchState
{
595 dot
: pattern
.iter_delimited(None
),
596 stack
: Default
::default(),
601 bindings
: bindings_builder
.alloc(),
606 let mut next_items
= vec
![];
609 let mut bb_items
= SmallVec
::new();
610 let mut eof_items
= SmallVec
::new();
611 let mut error_items
= SmallVec
::new();
613 stdx
::always
!(next_items
.is_empty());
619 &mut bindings_builder
,
626 stdx
::always
!(cur_items
.is_empty());
628 if !error_items
.is_empty() {
629 error_recover_item
= error_items
.pop().map(|it
| it
.bindings
);
630 } else if let [state
, ..] = &*eof_items
{
631 error_recover_item
= Some(state
.bindings
.clone());
634 // We need to do some post processing after the `match_loop_inner`.
635 // If we reached the EOF, check that there is EXACTLY ONE possible matcher. Otherwise,
636 // either the parse is ambiguous (which should never happen) or there is a syntax error.
637 if src
.peek_n(0).is_none() && stack
.is_empty() {
638 if let [state
] = &*eof_items
{
639 // remove all errors, because it is the correct answer !
640 res
= Match
::default();
641 res
.bindings
= bindings_builder
.build(&state
.bindings
);
644 if let Some(item
) = error_recover_item
{
645 res
.bindings
= bindings_builder
.build(&item
);
647 res
.add_err(ExpandError
::UnexpectedToken
);
652 // If there are no possible next positions AND we aren't waiting for the black-box parser,
653 // then there is a syntax error.
655 // Another possibility is that we need to call out to parse some rust nonterminal
656 // (black-box) parser. However, if there is not EXACTLY ONE of these, something is wrong.
657 let has_leftover_tokens
= (bb_items
.is_empty() && next_items
.is_empty())
658 || !(bb_items
.is_empty() || next_items
.is_empty())
659 || bb_items
.len() > 1;
660 if has_leftover_tokens
{
661 res
.unmatched_tts
+= src
.len();
662 while let Some(it
) = stack
.pop() {
664 res
.unmatched_tts
+= src
.len();
666 res
.add_err(ExpandError
::LeftoverTokens
);
668 if let Some(error_recover_item
) = error_recover_item
{
669 res
.bindings
= bindings_builder
.build(&error_recover_item
);
673 // Dump all possible `next_items` into `cur_items` for the next iteration.
674 else if !next_items
.is_empty() {
675 if let Some((iter
, _
)) = next_items
[0].meta_result
.take() {
676 // We've matched a possibly "glued" punct. The matched punct (hence
677 // `meta_result` also) must be the same for all items.
678 // FIXME: If there are multiple items, it's definitely redundant (and it's hacky!
679 // `meta_result` isn't supposed to be used this way).
681 // We already bumped, so no need to call `.next()` like in the other branch.
683 for item
in next_items
.iter_mut() {
684 item
.meta_result
= None
;
688 Some(tt
::TokenTree
::Subtree(subtree
)) => {
689 stack
.push(src
.clone());
690 src
= TtIter
::new(subtree
);
693 if let Some(iter
) = stack
.pop() {
700 // Now process the next token
701 cur_items
.extend(next_items
.drain(..));
703 // Finally, we have the case where we need to call the black-box parser to get some
706 stdx
::always
!(bb_items
.len() == 1);
707 let mut item
= bb_items
.pop().unwrap();
709 if let Some(OpDelimited
::Op(Op
::Var { name, .. }
)) = item
.dot
.peek() {
710 let (iter
, match_res
) = item
.meta_result
.take().unwrap();
711 match match_res
.value
{
713 bindings_builder
.push_fragment(&mut item
.bindings
, name
, fragment
);
715 None
if match_res
.err
.is_none() => {
716 bindings_builder
.push_optional(&mut item
.bindings
, name
);
720 if let Some(err
) = match_res
.err
{
728 cur_items
.push(item
);
730 stdx
::always
!(!cur_items
.is_empty());
734 fn match_meta_var(kind
: MetaVarKind
, input
: &mut TtIter
<'_
>) -> ExpandResult
<Option
<Fragment
>> {
735 let fragment
= match kind
{
736 MetaVarKind
::Path
=> parser
::PrefixEntryPoint
::Path
,
737 MetaVarKind
::Ty
=> parser
::PrefixEntryPoint
::Ty
,
738 // FIXME: These two should actually behave differently depending on the edition.
740 // https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html
741 MetaVarKind
::Pat
| MetaVarKind
::PatParam
=> parser
::PrefixEntryPoint
::Pat
,
742 MetaVarKind
::Stmt
=> parser
::PrefixEntryPoint
::Stmt
,
743 MetaVarKind
::Block
=> parser
::PrefixEntryPoint
::Block
,
744 MetaVarKind
::Meta
=> parser
::PrefixEntryPoint
::MetaItem
,
745 MetaVarKind
::Item
=> parser
::PrefixEntryPoint
::Item
,
746 MetaVarKind
::Vis
=> parser
::PrefixEntryPoint
::Vis
,
747 MetaVarKind
::Expr
=> {
748 // `expr` should not match underscores, let expressions, or inline const. The latter
749 // two are for [backwards compatibility][0].
750 // HACK: Macro expansion should not be done using "rollback and try another alternative".
751 // rustc [explicitly checks the next token][1].
752 // [0]: https://github.com/rust-lang/rust/issues/86730
753 // [1]: https://github.com/rust-lang/rust/blob/f0c4da499/compiler/rustc_expand/src/mbe/macro_parser.rs#L576
754 match input
.peek_n(0) {
755 Some(tt
::TokenTree
::Leaf(tt
::Leaf
::Ident(it
)))
756 if it
.text
== "_" || it
.text
== "let" || it
.text
== "const" =>
758 return ExpandResult
::only_err(ExpandError
::NoMatchingRule
)
763 .expect_fragment(parser
::PrefixEntryPoint
::Expr
)
764 .map(|tt
| tt
.map(Fragment
::Expr
));
767 let tt_result
= match kind
{
768 MetaVarKind
::Ident
=> input
770 .map(|ident
| tt
::Leaf
::from(ident
.clone()).into())
771 .map_err(|()| ExpandError
::binding_error("expected ident")),
772 MetaVarKind
::Tt
=> input
774 .map_err(|()| ExpandError
::binding_error("expected token tree")),
775 MetaVarKind
::Lifetime
=> input
777 .map_err(|()| ExpandError
::binding_error("expected lifetime")),
778 MetaVarKind
::Literal
=> {
779 let neg
= input
.eat_char('
-'
);
783 let lit
= literal
.clone();
786 Some(neg
) => tt
::TokenTree
::Subtree(tt
::Subtree
{
787 delimiter
: tt
::Delimiter
::unspecified(),
788 token_trees
: vec
![neg
, lit
.into()],
792 .map_err(|()| ExpandError
::binding_error("expected literal"))
794 _
=> Err(ExpandError
::UnexpectedToken
),
796 return tt_result
.map(|it
| Some(Fragment
::Tokens(it
))).into();
799 input
.expect_fragment(fragment
).map(|it
| it
.map(Fragment
::Tokens
))
802 fn collect_vars(collector_fun
: &mut impl FnMut(SmolStr
), pattern
: &MetaTemplate
) {
803 for op
in pattern
.iter() {
805 Op
::Var { name, .. }
=> collector_fun(name
.clone()),
806 Op
::Subtree { tokens, .. }
=> collect_vars(collector_fun
, tokens
),
807 Op
::Repeat { tokens, .. }
=> collect_vars(collector_fun
, tokens
),
808 Op
::Ignore { .. }
| Op
::Index { .. }
| Op
::Literal(_
) | Op
::Ident(_
) | Op
::Punct(_
) => {
814 fn iter_delimited
<'a
>(&'a
self, delimited
: Option
<&'a tt
::Delimiter
>) -> OpDelimitedIter
<'a
> {
818 delimited
: delimited
.unwrap_or(&tt
::Delimiter
::UNSPECIFIED
),
823 #[derive(Debug, Clone, Copy)]
824 enum OpDelimited
<'a
> {
830 #[derive(Debug, Clone, Copy)]
831 struct OpDelimitedIter
<'a
> {
833 delimited
: &'a tt
::Delimiter
,
837 impl<'a
> OpDelimitedIter
<'a
> {
838 fn is_eof(&self) -> bool
{
839 let len
= self.inner
.len()
840 + if self.delimited
.kind
!= tt
::DelimiterKind
::Invisible { 2 }
else { 0 }
;
844 fn peek(&self) -> Option
<OpDelimited
<'a
>> {
845 match self.delimited
.kind
{
846 tt
::DelimiterKind
::Invisible
=> self.inner
.get(self.idx
).map(OpDelimited
::Op
),
847 _
=> match self.idx
{
848 0 => Some(OpDelimited
::Open
),
849 i
if i
== self.inner
.len() + 1 => Some(OpDelimited
::Close
),
850 i
=> self.inner
.get(i
- 1).map(OpDelimited
::Op
),
855 fn reset(&self) -> Self {
856 Self { inner: self.inner, idx: 0, delimited: self.delimited }
860 impl<'a
> Iterator
for OpDelimitedIter
<'a
> {
861 type Item
= OpDelimited
<'a
>;
863 fn next(&mut self) -> Option
<Self::Item
> {
864 let res
= self.peek();
869 fn size_hint(&self) -> (usize, Option
<usize>) {
870 let len
= self.inner
.len()
871 + if self.delimited
.kind
!= tt
::DelimiterKind
::Invisible { 2 }
else { 0 }
;
872 let remain
= len
.saturating_sub(self.idx
);
873 (remain
, Some(remain
))
877 impl<'a
> TtIter
<'a
> {
878 fn expect_separator(&mut self, separator
: &Separator
) -> bool
{
879 let mut fork
= self.clone();
880 let ok
= match separator
{
881 Separator
::Ident(lhs
) => match fork
.expect_ident_or_underscore() {
882 Ok(rhs
) => rhs
.text
== lhs
.text
,
885 Separator
::Literal(lhs
) => match fork
.expect_literal() {
886 Ok(rhs
) => match rhs
{
887 tt
::Leaf
::Literal(rhs
) => rhs
.text
== lhs
.text
,
888 tt
::Leaf
::Ident(rhs
) => rhs
.text
== lhs
.text
,
889 tt
::Leaf
::Punct(_
) => false,
893 Separator
::Puncts(lhs
) => match fork
.expect_glued_punct() {
895 let lhs
= lhs
.iter().map(|it
| it
.char);
896 let rhs
= rhs
.iter().map(|it
| it
.char);
908 fn expect_tt(&mut self) -> Result
<tt
::TokenTree
, ()> {
909 if let Some(tt
::TokenTree
::Leaf(tt
::Leaf
::Punct(punct
))) = self.peek_n(0) {
910 if punct
.char == '
\''
{
911 self.expect_lifetime()
913 let puncts
= self.expect_glued_punct()?
;
914 let token_trees
= puncts
.into_iter().map(|p
| tt
::Leaf
::Punct(p
).into()).collect();
915 Ok(tt
::TokenTree
::Subtree(tt
::Subtree
{
916 delimiter
: tt
::Delimiter
::unspecified(),
921 self.next().ok_or(()).cloned()
925 fn expect_lifetime(&mut self) -> Result
<tt
::TokenTree
, ()> {
926 let punct
= self.expect_single_punct()?
;
927 if punct
.char != '
\''
{
930 let ident
= self.expect_ident_or_underscore()?
;
933 delimiter
: tt
::Delimiter
::unspecified(),
935 tt
::Leaf
::Punct(*punct
).into(),
936 tt
::Leaf
::Ident(ident
.clone()).into(),
942 fn eat_char(&mut self, c
: char) -> Option
<tt
::TokenTree
> {
943 let mut fork
= self.clone();
944 match fork
.expect_char(c
) {
946 let tt
= self.next().cloned();