Add Tracker
to track matching operations
This should allow us to collect detailed information without slowing down the inital hot path.
This commit is contained in:
parent
6c47848c25
commit
2f8a068cb7
3 changed files with 49 additions and 18 deletions
|
@ -70,21 +70,20 @@
|
|||
//! eof: [a $( a )* a b ·]
|
||||
//! ```
|
||||
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
pub(crate) use NamedMatch::*;
|
||||
pub(crate) use ParseResult::*;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
|
||||
use crate::mbe::{KleeneOp, TokenTree};
|
||||
use crate::mbe::{macro_rules::Tracker, KleeneOp, TokenTree};
|
||||
|
||||
use rustc_ast::token::{self, DocComment, Nonterminal, NonterminalKind, Token};
|
||||
use rustc_lint_defs::pluralize;
|
||||
use rustc_parse::parser::{NtOrTt, Parser};
|
||||
use rustc_span::symbol::MacroRulesNormalizedIdent;
|
||||
use rustc_span::Span;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_lint_defs::pluralize;
|
||||
use rustc_parse::parser::{NtOrTt, Parser};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::symbol::MacroRulesNormalizedIdent;
|
||||
use rustc_span::Span;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
|
||||
|
@ -97,7 +96,8 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
|
|||
///
|
||||
/// This means a matcher can be represented by `&[MatcherLoc]`, and traversal mostly involves
|
||||
/// simply incrementing the current matcher position index by one.
|
||||
pub(super) enum MatcherLoc {
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub(crate) enum MatcherLoc {
|
||||
Token {
|
||||
token: Token,
|
||||
},
|
||||
|
@ -401,17 +401,21 @@ impl TtParser {
|
|||
///
|
||||
/// `Some(result)` if everything is finished, `None` otherwise. Note that matches are kept
|
||||
/// track of through the mps generated.
|
||||
fn parse_tt_inner(
|
||||
fn parse_tt_inner<'matcher, T: Tracker<'matcher>>(
|
||||
&mut self,
|
||||
matcher: &[MatcherLoc],
|
||||
matcher: &'matcher [MatcherLoc],
|
||||
token: &Token,
|
||||
track: &mut T,
|
||||
) -> Option<NamedParseResult> {
|
||||
// Matcher positions that would be valid if the macro invocation was over now. Only
|
||||
// modified if `token == Eof`.
|
||||
let mut eof_mps = EofMatcherPositions::None;
|
||||
|
||||
while let Some(mut mp) = self.cur_mps.pop() {
|
||||
match &matcher[mp.idx] {
|
||||
let matcher_loc = &matcher[mp.idx];
|
||||
track.before_match_loc(self, matcher_loc);
|
||||
|
||||
match matcher_loc {
|
||||
MatcherLoc::Token { token: t } => {
|
||||
// If it's a doc comment, we just ignore it and move on to the next tt in the
|
||||
// matcher. This is a bug, but #95267 showed that existing programs rely on
|
||||
|
@ -553,10 +557,11 @@ impl TtParser {
|
|||
}
|
||||
|
||||
/// Match the token stream from `parser` against `matcher`.
|
||||
pub(super) fn parse_tt(
|
||||
pub(super) fn parse_tt<'matcher, T: Tracker<'matcher>>(
|
||||
&mut self,
|
||||
parser: &mut Cow<'_, Parser<'_>>,
|
||||
matcher: &[MatcherLoc],
|
||||
matcher: &'matcher [MatcherLoc],
|
||||
track: &mut T,
|
||||
) -> NamedParseResult {
|
||||
// A queue of possible matcher positions. We initialize it with the matcher position in
|
||||
// which the "dot" is before the first token of the first token tree in `matcher`.
|
||||
|
@ -572,7 +577,8 @@ impl TtParser {
|
|||
|
||||
// Process `cur_mps` until either we have finished the input or we need to get some
|
||||
// parsing from the black-box parser done.
|
||||
if let Some(res) = self.parse_tt_inner(matcher, &parser.token) {
|
||||
let res = self.parse_tt_inner(matcher, &parser.token, track);
|
||||
if let Some(res) = res {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue