From 4719cb30367496c90827f05b52f9fb3306aeae11 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 30 Apr 2021 19:38:06 +0200 Subject: [PATCH] Ignore span references from diagnostics. The diagnostics are replayed at the correct place anyway. --- compiler/rustc_errors/src/lib.rs | 96 ++++++++++--------- compiler/rustc_interface/src/callbacks.rs | 13 ++- .../rustc_query_system/src/dep_graph/graph.rs | 6 +- 3 files changed, 65 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 292ea64ee7b..4b9073d470b 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -473,10 +473,12 @@ pub enum StashKey { CallAssocMethod, } -fn default_track_diagnostic(_: &Diagnostic) {} +fn default_track_diagnostic(d: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) { + (*f)(d) +} -pub static TRACK_DIAGNOSTICS: AtomicRef = - AtomicRef::new(&(default_track_diagnostic as fn(&_))); +pub static TRACK_DIAGNOSTICS: AtomicRef = + AtomicRef::new(&(default_track_diagnostic as _)); #[derive(Copy, Clone, Default)] pub struct HandlerFlags { @@ -1290,67 +1292,69 @@ impl HandlerInner { && !diagnostic.is_force_warn() { if diagnostic.has_future_breakage() { - (*TRACK_DIAGNOSTICS)(diagnostic); + (*TRACK_DIAGNOSTICS)(diagnostic, &mut |_| {}); } return None; } - (*TRACK_DIAGNOSTICS)(diagnostic); - if matches!(diagnostic.level, Level::Expect(_) | Level::Allow) { + (*TRACK_DIAGNOSTICS)(diagnostic, &mut |_| {}); return None; } - if let Some(ref code) = diagnostic.code { - self.emitted_diagnostic_codes.insert(code.clone()); - } + let mut guaranteed = None; + (*TRACK_DIAGNOSTICS)(diagnostic, &mut |diagnostic| { + if let Some(ref code) = diagnostic.code { + self.emitted_diagnostic_codes.insert(code.clone()); + } - let already_emitted = |this: &mut Self| { - let mut hasher = StableHasher::new(); - diagnostic.hash(&mut hasher); - let diagnostic_hash = hasher.finish(); - !this.emitted_diagnostics.insert(diagnostic_hash) - }; - - // Only emit the diagnostic if we've been asked to deduplicate or - // haven't already emitted an equivalent diagnostic. - if !(self.flags.deduplicate_diagnostics && already_emitted(self)) { - debug!(?diagnostic); - debug!(?self.emitted_diagnostics); - let already_emitted_sub = |sub: &mut SubDiagnostic| { - debug!(?sub); - if sub.level != Level::OnceNote { - return false; - } + let already_emitted = |this: &mut Self| { let mut hasher = StableHasher::new(); - sub.hash(&mut hasher); + diagnostic.hash(&mut hasher); let diagnostic_hash = hasher.finish(); - debug!(?diagnostic_hash); - !self.emitted_diagnostics.insert(diagnostic_hash) + !this.emitted_diagnostics.insert(diagnostic_hash) }; - diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {}); + // Only emit the diagnostic if we've been asked to deduplicate or + // haven't already emitted an equivalent diagnostic. + if !(self.flags.deduplicate_diagnostics && already_emitted(self)) { + debug!(?diagnostic); + debug!(?self.emitted_diagnostics); + let already_emitted_sub = |sub: &mut SubDiagnostic| { + debug!(?sub); + if sub.level != Level::OnceNote { + return false; + } + let mut hasher = StableHasher::new(); + sub.hash(&mut hasher); + let diagnostic_hash = hasher.finish(); + debug!(?diagnostic_hash); + !self.emitted_diagnostics.insert(diagnostic_hash) + }; - self.emitter.emit_diagnostic(diagnostic); + diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {}); + + self.emitter.emit_diagnostic(diagnostic); + if diagnostic.is_error() { + self.deduplicated_err_count += 1; + } else if let Warning(_) = diagnostic.level { + self.deduplicated_warn_count += 1; + } + } if diagnostic.is_error() { - self.deduplicated_err_count += 1; - } else if let Warning(_) = diagnostic.level { - self.deduplicated_warn_count += 1; - } - } - if diagnostic.is_error() { - if matches!(diagnostic.level, Level::Error { lint: true }) { - self.bump_lint_err_count(); + if matches!(diagnostic.level, Level::Error { lint: true }) { + self.bump_lint_err_count(); + } else { + self.bump_err_count(); + } + + guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } else { - self.bump_err_count(); + self.bump_warn_count(); } + }); - Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) - } else { - self.bump_warn_count(); - - None - } + guaranteed } fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) { diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index 76442de69d3..ee0552d77ce 100644 --- a/compiler/rustc_interface/src/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs @@ -10,6 +10,7 @@ //! origin crate when the `TyCtxt` is not present in TLS. use rustc_errors::{Diagnostic, TRACK_DIAGNOSTICS}; +use rustc_middle::dep_graph::TaskDepsRef; use rustc_middle::ty::tls; use std::fmt; @@ -26,14 +27,22 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) { /// This is a callback from `rustc_ast` as it cannot access the implicit state /// in `rustc_middle` otherwise. It is used when diagnostic messages are /// emitted and stores them in the current query, if there is one. -fn track_diagnostic(diagnostic: &Diagnostic) { +fn track_diagnostic(diagnostic: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) { tls::with_context_opt(|icx| { if let Some(icx) = icx { if let Some(diagnostics) = icx.diagnostics { let mut diagnostics = diagnostics.lock(); diagnostics.extend(Some(diagnostic.clone())); + std::mem::drop(diagnostics); } + + // Diagnostics are tracked, we can ignore the dependency. + let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() }; + return tls::enter_context(&icx, move |_| (*f)(diagnostic)); } + + // In any other case, invoke diagnostics anyway. + (*f)(diagnostic); }) } @@ -55,5 +64,5 @@ fn def_id_debug(def_id: rustc_hir::def_id::DefId, f: &mut fmt::Formatter<'_>) -> pub fn setup_callbacks() { rustc_span::SPAN_TRACK.swap(&(track_span_parent as fn(_))); rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _)); - TRACK_DIAGNOSTICS.swap(&(track_diagnostic as fn(&_))); + TRACK_DIAGNOSTICS.swap(&(track_diagnostic as _)); } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 52957ee0222..0b1ff5d709f 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -634,7 +634,7 @@ impl DepGraph { if dep_node_debug.borrow().contains_key(&dep_node) { return; } - let debug_str = debug_str_gen(); + let debug_str = self.with_ignore(debug_str_gen); dep_node_debug.borrow_mut().insert(dep_node, debug_str); } @@ -829,7 +829,9 @@ impl DepGraph { ); if !side_effects.is_empty() { - self.emit_side_effects(qcx, data, dep_node_index, side_effects); + self.with_query_deserialization(|| { + self.emit_side_effects(qcx, data, dep_node_index, side_effects) + }); } // ... and finally storing a "Green" entry in the color map.