70
70
//! eof: [a $( a )* a b ·]
71
71
//! ```
72
72
73
+ use rustc_errors:: ErrorGuaranteed ;
73
74
pub ( crate ) use NamedMatch :: * ;
74
75
pub ( crate ) use ParseResult :: * ;
75
- use rustc_errors:: ErrorGuaranteed ;
76
76
77
- use crate :: mbe:: { KleeneOp , TokenTree } ;
77
+ use crate :: mbe:: { macro_rules :: Tracker , KleeneOp , TokenTree } ;
78
78
79
79
use rustc_ast:: token:: { self , DocComment , Nonterminal , NonterminalKind , Token } ;
80
+ use rustc_data_structures:: fx:: FxHashMap ;
81
+ use rustc_data_structures:: sync:: Lrc ;
80
82
use rustc_lint_defs:: pluralize;
81
83
use rustc_parse:: parser:: { NtOrTt , Parser } ;
84
+ use rustc_span:: symbol:: Ident ;
82
85
use rustc_span:: symbol:: MacroRulesNormalizedIdent ;
83
86
use rustc_span:: Span ;
84
-
85
- use rustc_data_structures:: fx:: FxHashMap ;
86
- use rustc_data_structures:: sync:: Lrc ;
87
- use rustc_span:: symbol:: Ident ;
88
87
use std:: borrow:: Cow ;
89
88
use std:: collections:: hash_map:: Entry :: { Occupied , Vacant } ;
90
89
@@ -97,7 +96,8 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
97
96
///
98
97
/// This means a matcher can be represented by `&[MatcherLoc]`, and traversal mostly involves
99
98
/// simply incrementing the current matcher position index by one.
100
- pub ( super ) enum MatcherLoc {
99
+ #[ derive( Debug , Clone , PartialEq ) ]
100
+ pub ( crate ) enum MatcherLoc {
101
101
Token {
102
102
token : Token ,
103
103
} ,
@@ -401,17 +401,21 @@ impl TtParser {
401
401
///
402
402
/// `Some(result)` if everything is finished, `None` otherwise. Note that matches are kept
403
403
/// track of through the mps generated.
404
- fn parse_tt_inner (
404
+ fn parse_tt_inner < ' matcher , T : Tracker < ' matcher > > (
405
405
& mut self ,
406
- matcher : & [ MatcherLoc ] ,
406
+ matcher : & ' matcher [ MatcherLoc ] ,
407
407
token : & Token ,
408
+ track : & mut T ,
408
409
) -> Option < NamedParseResult > {
409
410
// Matcher positions that would be valid if the macro invocation was over now. Only
410
411
// modified if `token == Eof`.
411
412
let mut eof_mps = EofMatcherPositions :: None ;
412
413
413
414
while let Some ( mut mp) = self . cur_mps . pop ( ) {
414
- match & matcher[ mp. idx ] {
415
+ let matcher_loc = & matcher[ mp. idx ] ;
416
+ track. before_match_loc ( self , matcher_loc) ;
417
+
418
+ match matcher_loc {
415
419
MatcherLoc :: Token { token : t } => {
416
420
// If it's a doc comment, we just ignore it and move on to the next tt in the
417
421
// matcher. This is a bug, but #95267 showed that existing programs rely on
@@ -553,10 +557,11 @@ impl TtParser {
553
557
}
554
558
555
559
/// Match the token stream from `parser` against `matcher`.
556
- pub ( super ) fn parse_tt (
560
+ pub ( super ) fn parse_tt < ' matcher , T : Tracker < ' matcher > > (
557
561
& mut self ,
558
562
parser : & mut Cow < ' _ , Parser < ' _ > > ,
559
- matcher : & [ MatcherLoc ] ,
563
+ matcher : & ' matcher [ MatcherLoc ] ,
564
+ track : & mut T ,
560
565
) -> NamedParseResult {
561
566
// A queue of possible matcher positions. We initialize it with the matcher position in
562
567
// which the "dot" is before the first token of the first token tree in `matcher`.
@@ -572,7 +577,8 @@ impl TtParser {
572
577
573
578
// Process `cur_mps` until either we have finished the input or we need to get some
574
579
// parsing from the black-box parser done.
575
- if let Some ( res) = self . parse_tt_inner ( matcher, & parser. token ) {
580
+ let res = self . parse_tt_inner ( matcher, & parser. token , track) ;
581
+ if let Some ( res) = res {
576
582
return res;
577
583
}
578
584
0 commit comments