diff options
| author | Michael Woerister <michaelwoerister@posteo> | 2017-10-25 15:01:06 +0200 |
|---|---|---|
| committer | Michael Woerister <michaelwoerister@posteo> | 2017-10-25 15:01:06 +0200 |
| commit | 6fccd71f7552a26d6c002d4712a6d16ff49da31f (patch) | |
| tree | 29a3df738d112ca072e619c9ff5f2ae8d73c6012 | |
| parent | 67f3dc3fee6a5bb5e651025368fb308d415a85b5 (diff) | |
| download | rust-6fccd71f7552a26d6c002d4712a6d16ff49da31f.tar.gz rust-6fccd71f7552a26d6c002d4712a6d16ff49da31f.zip | |
librustc_errors: Don't emit the same error message twice.
| -rw-r--r-- | src/Cargo.lock | 1 | ||||
| -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 |
5 files changed, 36 insertions, 9 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock index a8bcea6d781..76bdc8ef4c6 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1705,6 +1705,7 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ + "rustc_data_structures 0.0.0", "serialize 0.0.0", "syntax_pos 0.0.0", ] 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 02c0307e98c..64afdb1d2e0 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 d9b0f4ac8a6..39bb0184289 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, |
