Skip to content

Commit fbbabb9

Browse files
authored
Rollup merge of rust-lang#128798 - futile:refactor/mbe-diagnostics, r=petrochenkov
refactor(rustc_expand::mbe): Don't require full ExtCtxt when not necessary Refactor `mbe::diagnostics::failed_to_match_macro()` to not require a full `ExtCtxt`, but only a `&ParseSess`. It hard-required the `ExtCtxt` only for a call to `cx.trace_macros_diag()`, which we move instead to the only call-site of the function. Note: This could be a potential change in observed behavior, because a call to `cx.trace_macros_diag()` now always happens after `failed_to_match_macro()` was called, where before it was only called at the end of the main return path of the function. But since `trace_macros_diag()` "flushes" out any not-yet-reported errors, it should be ok to call it for all paths, since there shouldn't be any on the non-main paths I think. However, I don't know the rest of the codebase well enough to say that with 100% confidence, but `tests/ui` still pass, which gives at least some confidence in the change. Also concretize the return type from `Box<dyn MacResult>` to `(Span, ErrorGuaranteed)`, because this function will _always_ return an error, and never any other kind of result. Was part of rust-lang#128605 and rust-lang#128747, but is a standalone refactoring. r? ``@petrochenkov``
2 parents f4fe5c8 + a70c9e1 commit fbbabb9

File tree

2 files changed

+28
-28
lines changed

2 files changed

+28
-28
lines changed

compiler/rustc_expand/src/mbe/diagnostics.rs

+24-27
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,40 @@ use std::borrow::Cow;
33
use rustc_ast::token::{self, Token, TokenKind};
44
use rustc_ast::tokenstream::TokenStream;
55
use rustc_ast_pretty::pprust;
6-
use rustc_errors::{Applicability, Diag, DiagMessage};
6+
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, DiagMessage};
77
use rustc_macros::Subdiagnostic;
88
use rustc_parse::parser::{Parser, Recovery};
9+
use rustc_session::parse::ParseSess;
910
use rustc_span::source_map::SourceMap;
1011
use rustc_span::symbol::Ident;
1112
use rustc_span::{ErrorGuaranteed, Span};
1213
use tracing::debug;
1314

1415
use super::macro_rules::{parser_from_cx, NoopTracker};
15-
use crate::base::{DummyResult, ExtCtxt, MacResult};
1616
use crate::expand::{parse_ast_fragment, AstFragmentKind};
1717
use crate::mbe::macro_parser::ParseResult::*;
1818
use crate::mbe::macro_parser::{MatcherLoc, NamedParseResult, TtParser};
1919
use crate::mbe::macro_rules::{try_match_macro, Tracker};
2020

21-
pub(super) fn failed_to_match_macro<'cx>(
22-
cx: &'cx mut ExtCtxt<'_>,
21+
pub(super) fn failed_to_match_macro(
22+
psess: &ParseSess,
2323
sp: Span,
2424
def_span: Span,
2525
name: Ident,
2626
arg: TokenStream,
2727
lhses: &[Vec<MatcherLoc>],
28-
) -> Box<dyn MacResult + 'cx> {
29-
let psess = &cx.sess.psess;
30-
28+
) -> (Span, ErrorGuaranteed) {
3129
// An error occurred, try the expansion again, tracking the expansion closely for better
3230
// diagnostics.
33-
let mut tracker = CollectTrackerAndEmitter::new(cx, sp);
31+
let mut tracker = CollectTrackerAndEmitter::new(psess.dcx(), sp);
3432

3533
let try_success_result = try_match_macro(psess, name, &arg, lhses, &mut tracker);
3634

3735
if try_success_result.is_ok() {
3836
// Nonterminal parser recovery might turn failed matches into successful ones,
3937
// but for that it must have emitted an error already
4038
assert!(
41-
tracker.cx.dcx().has_errors().is_some(),
39+
tracker.dcx.has_errors().is_some(),
4240
"Macro matching returned a success on the second try"
4341
);
4442
}
@@ -50,15 +48,15 @@ pub(super) fn failed_to_match_macro<'cx>(
5048

5149
let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure
5250
else {
53-
return DummyResult::any(sp, cx.dcx().span_delayed_bug(sp, "failed to match a macro"));
51+
return (sp, psess.dcx().span_delayed_bug(sp, "failed to match a macro"));
5452
};
5553

5654
let span = token.span.substitute_dummy(sp);
5755

58-
let mut err = cx.dcx().struct_span_err(span, parse_failure_msg(&token, None));
56+
let mut err = psess.dcx().struct_span_err(span, parse_failure_msg(&token, None));
5957
err.span_label(span, label);
60-
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
61-
err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
58+
if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
59+
err.span_label(psess.source_map().guess_head_span(def_span), "when calling this macro");
6260
}
6361

6462
annotate_doc_comment(&mut err, psess.source_map(), span);
@@ -76,7 +74,7 @@ pub(super) fn failed_to_match_macro<'cx>(
7674
err.note("captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens");
7775
err.note("see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information");
7876

79-
if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
77+
if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
8078
err.help("try using `:tt` instead in the macro definition");
8179
}
8280
}
@@ -104,18 +102,17 @@ pub(super) fn failed_to_match_macro<'cx>(
104102
}
105103
}
106104
let guar = err.emit();
107-
cx.trace_macros_diag();
108-
DummyResult::any(sp, guar)
105+
(sp, guar)
109106
}
110107

111108
/// The tracker used for the slow error path that collects useful info for diagnostics.
112-
struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
113-
cx: &'a mut ExtCtxt<'cx>,
109+
struct CollectTrackerAndEmitter<'dcx, 'matcher> {
110+
dcx: DiagCtxtHandle<'dcx>,
114111
remaining_matcher: Option<&'matcher MatcherLoc>,
115112
/// Which arm's failure should we report? (the one furthest along)
116113
best_failure: Option<BestFailure>,
117114
root_span: Span,
118-
result: Option<Box<dyn MacResult + 'cx>>,
115+
result: Option<(Span, ErrorGuaranteed)>,
119116
}
120117

121118
struct BestFailure {
@@ -131,7 +128,7 @@ impl BestFailure {
131128
}
132129
}
133130

134-
impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> {
131+
impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'matcher> {
135132
type Failure = (Token, u32, &'static str);
136133

137134
fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure {
@@ -151,7 +148,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
151148
Success(_) => {
152149
// Nonterminal parser recovery might turn failed matches into successful ones,
153150
// but for that it must have emitted an error already
154-
self.cx.dcx().span_delayed_bug(
151+
self.dcx.span_delayed_bug(
155152
self.root_span,
156153
"should not collect detailed info for successful macro match",
157154
);
@@ -177,10 +174,10 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
177174
}
178175
Error(err_sp, msg) => {
179176
let span = err_sp.substitute_dummy(self.root_span);
180-
let guar = self.cx.dcx().span_err(span, msg.clone());
181-
self.result = Some(DummyResult::any(span, guar));
177+
let guar = self.dcx.span_err(span, msg.clone());
178+
self.result = Some((span, guar));
182179
}
183-
ErrorReported(guar) => self.result = Some(DummyResult::any(self.root_span, *guar)),
180+
ErrorReported(guar) => self.result = Some((self.root_span, *guar)),
184181
}
185182
}
186183

@@ -193,9 +190,9 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
193190
}
194191
}
195192

196-
impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx, '_> {
197-
fn new(cx: &'a mut ExtCtxt<'cx>, root_span: Span) -> Self {
198-
Self { cx, remaining_matcher: None, best_failure: None, root_span, result: None }
193+
impl<'dcx> CollectTrackerAndEmitter<'dcx, '_> {
194+
fn new(dcx: DiagCtxtHandle<'dcx>, root_span: Span) -> Self {
195+
Self { dcx, remaining_matcher: None, best_failure: None, root_span, result: None }
199196
}
200197
}
201198

compiler/rustc_expand/src/mbe/macro_rules.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,10 @@ fn expand_macro<'cx>(
268268
}
269269
Err(CanRetry::Yes) => {
270270
// Retry and emit a better error.
271-
diagnostics::failed_to_match_macro(cx, sp, def_span, name, arg, lhses)
271+
let (span, guar) =
272+
diagnostics::failed_to_match_macro(cx.psess(), sp, def_span, name, arg, lhses);
273+
cx.trace_macros_diag();
274+
DummyResult::any(span, guar)
272275
}
273276
}
274277
}

0 commit comments

Comments
 (0)