diff options
| author | bors <bors@rust-lang.org> | 2017-10-26 18:16:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-10-26 18:16:15 +0000 |
| commit | b218a02ad8b8b79b30a847eadf3e9c739560fadf (patch) | |
| tree | 7b6c98cf121a175eb959f22653c3403d104f8ea5 /src/librustc_errors | |
| parent | b0b80f8c2299cccd7a4f22ee3cc1a2ca823eaa31 (diff) | |
| parent | 9736474b6c3d3ce82587745723f09aca8f987c00 (diff) | |
Auto merge of #45519 - michaelwoerister:dedup-errors, r=arielb1
Don't emit the same compiler diagnostic twice. This PR makes the compiler filter out diagnostic messages that have already been emitted during the same compilation session.
Diffstat (limited to 'src/librustc_errors')
| -rw-r--r-- | src/librustc_errors/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/librustc_errors/diagnostic.rs | 4 | ||||
| -rw-r--r-- | src/librustc_errors/lib.rs | 37 | ||||
| -rw-r--r-- | src/librustc_errors/snippet.rs | 2 |
4 files changed, 35 insertions, 9 deletions
diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml index 78ff52b4b23..c72e9dd0ea3 100644 --- a/src/librustc_errors/Cargo.toml +++ b/src/librustc_errors/Cargo.toml @@ -11,3 +11,4 @@ crate-type = ["dylib"] [dependencies] serialize = { path = "../libserialize" } syntax_pos = { path = "../libsyntax_pos" } +rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index f560622c297..5e0e624082e 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -17,7 +17,7 @@ use syntax_pos::{MultiSpan, Span}; use snippet::Style; #[must_use] -#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] pub struct Diagnostic { pub level: Level, pub message: Vec<(String, Style)>, @@ -28,7 +28,7 @@ pub struct Diagnostic { } /// For example a note attached to an error. -#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] pub struct SubDiagnostic { pub level: Level, pub message: Vec<(String, Style)>, diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index adb3e4d3ed6..ba7268a4bc3 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -18,10 +18,12 @@ #![feature(range_contains)] #![cfg_attr(unix, feature(libc))] #![feature(conservative_impl_trait)] +#![feature(i128_type)] extern crate term; #[cfg(unix)] extern crate libc; +extern crate rustc_data_structures; extern crate serialize as rustc_serialize; extern crate syntax_pos; @@ -31,6 +33,9 @@ use self::Level::*; use emitter::{Emitter, EmitterWriter}; +use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::stable_hasher::StableHasher; + use std::borrow::Cow; use std::cell::{RefCell, Cell}; use std::mem; @@ -47,7 +52,7 @@ mod lock; use syntax_pos::{BytePos, Loc, FileLinesResult, FileMap, FileName, MultiSpan, Span, NO_EXPANSION}; -#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] pub enum RenderSpan { /// A FullSpan renders with both with an initial line for the /// message, prefixed by file:linenum, followed by a summary of @@ -61,7 +66,7 @@ pub enum RenderSpan { Suggestion(CodeSuggestion), } -#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] pub struct CodeSuggestion { /// Each substitute can have multiple variants due to multiple /// applicable suggestions @@ -86,7 +91,7 @@ pub struct CodeSuggestion { pub show_code_when_inline: bool, } -#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] /// See the docs on `CodeSuggestion::substitutions` pub struct Substitution { pub span: Span, @@ -271,6 +276,11 @@ pub struct Handler { continue_after_error: Cell<bool>, delayed_span_bug: RefCell<Option<Diagnostic>>, tracked_diagnostics: RefCell<Option<Vec<Diagnostic>>>, + + // This set contains a hash of every diagnostic that has been emitted by + // this handler. These hashes is used to avoid emitting the same error + // twice. + emitted_diagnostics: RefCell<FxHashSet<u128>>, } impl Handler { @@ -295,6 +305,7 @@ impl Handler { continue_after_error: Cell::new(true), delayed_span_bug: RefCell::new(None), tracked_diagnostics: RefCell::new(None), + emitted_diagnostics: RefCell::new(FxHashSet()), } } @@ -559,15 +570,29 @@ impl Handler { } fn emit_db(&self, db: &DiagnosticBuilder) { + let diagnostic = &**db; + if let Some(ref mut list) = *self.tracked_diagnostics.borrow_mut() { - list.push((**db).clone()); + list.push(diagnostic.clone()); + } + + let diagnostic_hash = { + use std::hash::Hash; + let mut hasher = StableHasher::new(); + diagnostic.hash(&mut hasher); + hasher.finish() + }; + + // Only emit the diagnostic if we haven't already emitted an equivalent + // one: + if self.emitted_diagnostics.borrow_mut().insert(diagnostic_hash) { + self.emitter.borrow_mut().emit(db); } - self.emitter.borrow_mut().emit(db); } } -#[derive(Copy, PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)] +#[derive(Copy, PartialEq, Clone, Hash, Debug, RustcEncodable, RustcDecodable)] pub enum Level { Bug, Fatal, diff --git a/src/librustc_errors/snippet.rs b/src/librustc_errors/snippet.rs index 52e3fcc1b47..2e8deeee5a5 100644 --- a/src/librustc_errors/snippet.rs +++ b/src/librustc_errors/snippet.rs @@ -203,7 +203,7 @@ pub struct StyledString { pub style: Style, } -#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] pub enum Style { HeaderMsg, LineAndColumn, |
