Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/mbe/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ impl NamedMatch {
}

/// Performs a token equality check, ignoring syntax context (that is, an unhygienic comparison)
fn token_name_eq(t1: &Token, t2: &Token) -> bool {
pub(super) fn token_name_eq(t1: &Token, t2: &Token) -> bool {
if let (Some((ident1, is_raw1)), Some((ident2, is_raw2))) = (t1.ident(), t2.ident()) {
ident1.name == ident2.name && is_raw1 == is_raw2
} else if let (Some((ident1, is_raw1)), Some((ident2, is_raw2))) =
Expand Down
16 changes: 15 additions & 1 deletion compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use tracing::{debug, instrument, trace, trace_span};

use super::SequenceRepetition;
use super::diagnostics::{FailedMacro, failed_to_match_macro};
use super::macro_parser::{NamedMatches, NamedParseResult};
use super::macro_parser::{NamedMatches, NamedParseResult, token_name_eq};
use crate::base::{
AttrProcMacro, BangProcMacro, DummyResult, ExpandResult, ExtCtxt, MacResult,
MacroExpanderResult, SyntaxExtension, SyntaxExtensionKind, TTMacroExpander,
Expand Down Expand Up @@ -362,6 +362,9 @@ fn trace_macros_note(cx_expansions: &mut FxIndexMap<Span, Vec<String>>, sp: Span
}

pub(super) trait Tracker<'matcher> {
/// Diagnostic trackers need every failure callback, even for an immediate mismatch.
const TRACK_FAILURES: bool = true;

/// Provide context on the arm that's about to be matched.
fn prepare(&mut self, which_matcher: WhichMatcher, matcher: &'matcher [MatcherLoc]);

Expand Down Expand Up @@ -405,6 +408,8 @@ pub(super) trait Tracker<'matcher> {
pub(super) struct NoopTracker;

impl<'matcher> Tracker<'matcher> for NoopTracker {
const TRACK_FAILURES: bool = false;

fn prepare(&mut self, _which_matcher: WhichMatcher, _matcher: &'matcher [MatcherLoc]) {}

fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {}
Expand Down Expand Up @@ -634,6 +639,15 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>(
let mut tt_parser = TtParser::new();
for (i, rule) in rules.iter().enumerate() {
let MacroRule::Func { lhs, .. } = rule else { continue };
if !T::TRACK_FAILURES
&& let Some(MatcherLoc::Token { token }) = lhs.first()
&& !matches!(token.kind, DocComment(..))
&& !token_name_eq(token, &parser.token)
{
// A literal mismatch cannot parse, gate features, or be ambiguous.
// Diagnostic replay still runs the original matcher and callbacks.
continue;
}
let _tracing_span = trace_span!("Matching arm", %i);

// Take a snapshot of the state of pre-expansion gating at this point.
Expand Down