use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::{self, Lock, Lrc};
use rustc_data_structures::AtomicRef;
-use syntax_pos::source_map::SourceMap;
-use syntax_pos::{Loc, MultiSpan, Span};
+use rustc_span::source_map::SourceMap;
+use rustc_span::{Loc, MultiSpan, Span};
use std::borrow::Cow;
use std::panic;
/// Returns the assembled code suggestions, whether they should be shown with an underline
/// and whether the substitution only differs in capitalization.
pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec<SubstitutionPart>, bool)> {
- use syntax_pos::{CharPos, Pos};
+ use rustc_span::{CharPos, Pos};
fn push_trailing(
buf: &mut String,
// Find the bounding span.
let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap();
- let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap();
+ let hi = substitution.parts.iter().map(|part| part.span.hi()).max().unwrap();
let bounding_span = Span::with_root_ctxt(lo, hi);
let lines = cm.span_to_lines(bounding_span).unwrap();
assert!(!lines.lines.is_empty());
}
}
-pub use syntax_pos::fatal_error::{FatalError, FatalErrorMarker};
+pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
/// Signifies that the compiler died with an explicit call to `.bug`
/// or `.span_bug` rather than a failed assertion, etc.
err_count: usize,
deduplicated_err_count: usize,
emitter: Box<dyn Emitter + sync::Send>,
- continue_after_error: bool,
delayed_span_bugs: Vec<Diagnostic>,
/// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
/// show macro backtraces even for non-local macros.
/// (rustc: see `-Z external-macro-backtrace`)
pub external_macro_backtrace: bool,
+ /// If true, identical diagnostics are reported only once.
+ pub deduplicate_diagnostics: bool,
}
impl Drop for HandlerInner {
err_count: 0,
deduplicated_err_count: 0,
emitter,
- continue_after_error: true,
delayed_span_bugs: Vec::new(),
taught_diagnostics: Default::default(),
emitted_diagnostic_codes: Default::default(),
}
}
- pub fn set_continue_after_error(&self, continue_after_error: bool) {
- self.inner.borrow_mut().continue_after_error = continue_after_error;
- }
-
// This is here to not allow mutation of flags;
// as of this writing it's only used in tests in librustc.
pub fn can_emit_warnings(&self) -> bool {
self.inner.borrow_mut().abort_if_errors()
}
- pub fn abort_if_errors_and_should_abort(&self) {
- self.inner.borrow_mut().abort_if_errors_and_should_abort()
- }
-
/// `true` if we haven't taught a diagnostic with this code already.
/// The caller must then teach the user about such a diagnostic.
///
fn emit_diag_at_span(&self, mut diag: Diagnostic, sp: impl Into<MultiSpan>) {
let mut inner = self.inner.borrow_mut();
inner.emit_diagnostic(diag.set_span(sp));
- inner.abort_if_errors_and_should_abort();
}
pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
self.emitted_diagnostic_codes.insert(code.clone());
}
- let diagnostic_hash = {
+ let already_emitted = |this: &mut Self| {
use std::hash::Hash;
let mut hasher = StableHasher::new();
diagnostic.hash(&mut hasher);
- hasher.finish()
+ let diagnostic_hash = hasher.finish();
+ !this.emitted_diagnostics.insert(diagnostic_hash)
};
- // Only emit the diagnostic if we haven't already emitted an equivalent
- // one:
- if self.emitted_diagnostics.insert(diagnostic_hash) {
+ // Only emit the diagnostic if we've been asked to deduplicate and
+ // haven't already emitted an equivalent diagnostic.
+ if !(self.flags.deduplicate_diagnostics && already_emitted(self)) {
self.emitter.emit_diagnostic(diagnostic);
if diagnostic.is_error() {
self.deduplicated_err_count += 1;
self.has_errors() || !self.delayed_span_bugs.is_empty()
}
- fn abort_if_errors_and_should_abort(&mut self) {
- self.emit_stashed_diagnostics();
-
- if self.has_errors() && !self.continue_after_error {
- FatalError.raise();
- }
- }
-
fn abort_if_errors(&mut self) {
self.emit_stashed_diagnostics();
fn emit_diag_at_span(&mut self, mut diag: Diagnostic, sp: impl Into<MultiSpan>) {
self.emit_diagnostic(diag.set_span(sp));
- self.abort_if_errors_and_should_abort();
}
fn delay_span_bug(&mut self, sp: impl Into<MultiSpan>, msg: &str) {