1
Fork 0

Give TRACK_DIAGNOSTIC a return value.

This means `DiagCtxtInner::emit_diagnostic` can return its result
directly, rather than having to modify a local variable.
This commit is contained in:
Nicholas Nethercote 2024-02-09 16:16:22 +11:00
parent 1a1876c979
commit bf62d5913a
2 changed files with 18 additions and 16 deletions

View file

@ -526,12 +526,15 @@ pub enum StashKey {
UndeterminedMacroResolution, UndeterminedMacroResolution,
} }
fn default_track_diagnostic(diag: DiagInner, f: &mut dyn FnMut(DiagInner)) { fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
(*f)(diag) (*f)(diag)
} }
pub static TRACK_DIAGNOSTIC: AtomicRef<fn(DiagInner, &mut dyn FnMut(DiagInner))> = /// Diagnostics emitted by `DiagCtxtInner::emit_diagnostic` are passed through this function. Used
AtomicRef::new(&(default_track_diagnostic as _)); /// for tracking by incremental, to replay diagnostics as necessary.
pub static TRACK_DIAGNOSTIC: AtomicRef<
fn(DiagInner, &mut dyn FnMut(DiagInner) -> Option<ErrorGuaranteed>) -> Option<ErrorGuaranteed>,
> = AtomicRef::new(&(default_track_diagnostic as _));
#[derive(Copy, Clone, Default)] #[derive(Copy, Clone, Default)]
pub struct DiagCtxtFlags { pub struct DiagCtxtFlags {
@ -1406,19 +1409,18 @@ impl DiagCtxtInner {
} }
Warning if !self.flags.can_emit_warnings => { Warning if !self.flags.can_emit_warnings => {
if diagnostic.has_future_breakage() { if diagnostic.has_future_breakage() {
(*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
} }
return None; return None;
} }
Allow | Expect(_) => { Allow | Expect(_) => {
(*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); TRACK_DIAGNOSTIC(diagnostic, &mut |_| None);
return None; return None;
} }
_ => {} _ => {}
} }
let mut guaranteed = None; TRACK_DIAGNOSTIC(diagnostic, &mut |mut diagnostic| {
(*TRACK_DIAGNOSTIC)(diagnostic, &mut |mut diagnostic| {
if let Some(code) = diagnostic.code { if let Some(code) = diagnostic.code {
self.emitted_diagnostic_codes.insert(code); self.emitted_diagnostic_codes.insert(code);
} }
@ -1481,17 +1483,17 @@ impl DiagCtxtInner {
// `ErrorGuaranteed` for errors and lint errors originates. // `ErrorGuaranteed` for errors and lint errors originates.
#[allow(deprecated)] #[allow(deprecated)]
let guar = ErrorGuaranteed::unchecked_error_guaranteed(); let guar = ErrorGuaranteed::unchecked_error_guaranteed();
guaranteed = Some(guar);
if is_lint { if is_lint {
self.lint_err_guars.push(guar); self.lint_err_guars.push(guar);
} else { } else {
self.err_guars.push(guar); self.err_guars.push(guar);
} }
self.panic_if_treat_err_as_bug(); self.panic_if_treat_err_as_bug();
Some(guar)
} else {
None
} }
}); })
guaranteed
} }
fn treat_err_as_bug(&self) -> bool { fn treat_err_as_bug(&self) -> bool {

View file

@ -29,7 +29,7 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
/// This is a callback from `rustc_errors` as it cannot access the implicit state /// This is a callback from `rustc_errors` as it cannot access the implicit state
/// in `rustc_middle` otherwise. It is used when diagnostic messages are /// in `rustc_middle` otherwise. It is used when diagnostic messages are
/// emitted and stores them in the current query, if there is one. /// emitted and stores them in the current query, if there is one.
fn track_diagnostic(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner)) { fn track_diagnostic<R>(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
tls::with_context_opt(|icx| { tls::with_context_opt(|icx| {
if let Some(icx) = icx { if let Some(icx) = icx {
if let Some(diagnostics) = icx.diagnostics { if let Some(diagnostics) = icx.diagnostics {
@ -38,11 +38,11 @@ fn track_diagnostic(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner)) {
// Diagnostics are tracked, we can ignore the dependency. // Diagnostics are tracked, we can ignore the dependency.
let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() }; let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() };
return tls::enter_context(&icx, move || (*f)(diagnostic)); tls::enter_context(&icx, move || (*f)(diagnostic))
} else {
// In any other case, invoke diagnostics anyway.
(*f)(diagnostic)
} }
// In any other case, invoke diagnostics anyway.
(*f)(diagnostic);
}) })
} }