Skip to content

Commit 7b6c6d6

Browse files
committed
mbe: Unify failed_to_match_macro variants
`failed_to_match_macro` and `failed_to_match_macro_attr` had a fair bit in common. Unify the two, and handle the differences with conditionals.
1 parent 6792cf5 commit 7b6c6d6

File tree

2 files changed

+17
-73
lines changed

2 files changed

+17
-73
lines changed

compiler/rustc_expand/src/mbe/diagnostics.rs

Lines changed: 12 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ pub(super) fn failed_to_match_macro(
2121
sp: Span,
2222
def_span: Span,
2323
name: Ident,
24-
arg: TokenStream,
24+
attr_args: Option<&TokenStream>,
25+
body: &TokenStream,
2526
rules: &[MacroRule],
2627
) -> (Span, ErrorGuaranteed) {
2728
debug!("failed to match macro");
@@ -35,7 +36,11 @@ pub(super) fn failed_to_match_macro(
3536
// diagnostics.
3637
let mut tracker = CollectTrackerAndEmitter::new(psess.dcx(), sp);
3738

38-
let try_success_result = try_match_macro(psess, name, &arg, rules, &mut tracker);
39+
let try_success_result = if let Some(attr_args) = attr_args {
40+
try_match_macro_attr(psess, name, attr_args, body, rules, &mut tracker)
41+
} else {
42+
try_match_macro(psess, name, body, rules, &mut tracker)
43+
};
3944

4045
if try_success_result.is_ok() {
4146
// Nonterminal parser recovery might turn failed matches into successful ones,
@@ -53,7 +58,7 @@ pub(super) fn failed_to_match_macro(
5358

5459
let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure
5560
else {
56-
if !rules.iter().any(|rule| matches!(rule, MacroRule::Func { .. })) {
61+
if attr_args.is_none() && !rules.iter().any(|rule| matches!(rule, MacroRule::Func { .. })) {
5762
let mut err = psess.dcx().struct_span_err(sp, "invoked macro has no invocation rules");
5863
if !def_head_span.is_dummy() {
5964
err.span_label(def_head_span, "this macro has no rules to invoke");
@@ -92,10 +97,12 @@ pub(super) fn failed_to_match_macro(
9297
}
9398

9499
// Check whether there's a missing comma in this macro call, like `println!("{}" a);`
95-
if let Some((arg, comma_span)) = arg.add_comma() {
100+
if attr_args.is_none()
101+
&& let Some((body, comma_span)) = body.add_comma()
102+
{
96103
for rule in rules {
97104
let MacroRule::Func { lhs, .. } = rule else { continue };
98-
let parser = parser_from_cx(psess, arg.clone(), Recovery::Allowed);
105+
let parser = parser_from_cx(psess, body.clone(), Recovery::Allowed);
99106
let mut tt_parser = TtParser::new(name);
100107

101108
if let Success(_) =
@@ -118,70 +125,6 @@ pub(super) fn failed_to_match_macro(
118125
(sp, guar)
119126
}
120127

121-
pub(super) fn failed_to_match_macro_attr(
122-
psess: &ParseSess,
123-
sp: Span,
124-
def_span: Span,
125-
name: Ident,
126-
args: TokenStream,
127-
body: TokenStream,
128-
rules: &[MacroRule],
129-
) -> ErrorGuaranteed {
130-
// An error occurred, try the expansion again, tracking the expansion closely for better
131-
// diagnostics.
132-
let mut tracker = CollectTrackerAndEmitter::new(psess.dcx(), sp);
133-
134-
let result = try_match_macro_attr(psess, name, &args, &body, rules, &mut tracker);
135-
if result.is_ok() {
136-
// Nonterminal parser recovery might turn failed matches into successful ones,
137-
// but for that it must have emitted an error already
138-
assert!(
139-
tracker.dcx.has_errors().is_some(),
140-
"Macro matching returned a success on the second try"
141-
);
142-
}
143-
144-
if let Some((_, guar)) = tracker.result {
145-
// An irrecoverable error occurred and has been emitted.
146-
return guar;
147-
}
148-
149-
let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure
150-
else {
151-
return psess.dcx().span_delayed_bug(sp, "failed to match a macro attr");
152-
};
153-
154-
let span = token.span.substitute_dummy(sp);
155-
156-
let mut err = psess.dcx().struct_span_err(span, parse_failure_msg(&token, None));
157-
err.span_label(span, label);
158-
if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
159-
err.span_label(psess.source_map().guess_head_span(def_span), "when calling this macro");
160-
}
161-
162-
annotate_doc_comment(&mut err, psess.source_map(), span);
163-
164-
if let Some(span) = remaining_matcher.span() {
165-
err.span_note(span, format!("while trying to match {remaining_matcher}"));
166-
} else {
167-
err.note(format!("while trying to match {remaining_matcher}"));
168-
}
169-
170-
if let MatcherLoc::Token { token: expected_token } = &remaining_matcher
171-
&& (matches!(expected_token.kind, token::OpenInvisible(_))
172-
|| matches!(token.kind, token::OpenInvisible(_)))
173-
{
174-
err.note("captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens");
175-
err.note("see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information");
176-
177-
if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
178-
err.help("try using `:tt` instead in the macro definition");
179-
}
180-
}
181-
182-
err.emit()
183-
}
184-
185128
/// The tracker used for the slow error path that collects useful info for diagnostics.
186129
struct CollectTrackerAndEmitter<'dcx, 'matcher> {
187130
dcx: DiagCtxtHandle<'dcx>,

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_span::hygiene::Transparency;
2828
use rustc_span::{Ident, Span, kw, sym};
2929
use tracing::{debug, instrument, trace, trace_span};
3030

31-
use super::diagnostics::{failed_to_match_macro, failed_to_match_macro_attr};
31+
use super::diagnostics::failed_to_match_macro;
3232
use super::macro_parser::{NamedMatches, NamedParseResult};
3333
use super::{SequenceRepetition, diagnostics};
3434
use crate::base::{
@@ -308,7 +308,8 @@ fn expand_macro<'cx>(
308308
}
309309
Err(CanRetry::Yes) => {
310310
// Retry and emit a better error.
311-
let (span, guar) = failed_to_match_macro(cx.psess(), sp, def_span, name, arg, rules);
311+
let (span, guar) =
312+
failed_to_match_macro(cx.psess(), sp, def_span, name, None, &arg, rules);
312313
cx.macro_error_and_trace_macros_diag();
313314
DummyResult::any(span, guar)
314315
}
@@ -370,8 +371,8 @@ fn expand_macro_attr(
370371
Err(CanRetry::No(guar)) => Err(guar),
371372
Err(CanRetry::Yes) => {
372373
// Retry and emit a better error.
373-
let guar =
374-
failed_to_match_macro_attr(cx.psess(), sp, def_span, name, args, body, rules);
374+
let (_, guar) =
375+
failed_to_match_macro(cx.psess(), sp, def_span, name, Some(&args), &body, rules);
375376
cx.trace_macros_diag();
376377
Err(guar)
377378
}

0 commit comments

Comments
 (0)