1
Fork 0

librustc_errors: Don't emit the same error message twice.

This commit is contained in:
Michael Woerister 2017-10-25 15:01:06 +02:00
parent 67f3dc3fee
commit 6fccd71f75
5 changed files with 36 additions and 9 deletions

1
src/Cargo.lock generated
View file

@ -1705,6 +1705,7 @@ dependencies = [
name = "rustc_errors" name = "rustc_errors"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"rustc_data_structures 0.0.0",
"serialize 0.0.0", "serialize 0.0.0",
"syntax_pos 0.0.0", "syntax_pos 0.0.0",
] ]

View file

@ -11,3 +11,4 @@ crate-type = ["dylib"]
[dependencies] [dependencies]
serialize = { path = "../libserialize" } serialize = { path = "../libserialize" }
syntax_pos = { path = "../libsyntax_pos" } syntax_pos = { path = "../libsyntax_pos" }
rustc_data_structures = { path = "../librustc_data_structures" }

View file

@ -17,7 +17,7 @@ use syntax_pos::{MultiSpan, Span};
use snippet::Style; use snippet::Style;
#[must_use] #[must_use]
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] #[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
pub struct Diagnostic { pub struct Diagnostic {
pub level: Level, pub level: Level,
pub message: Vec<(String, Style)>, pub message: Vec<(String, Style)>,
@ -28,7 +28,7 @@ pub struct Diagnostic {
} }
/// For example a note attached to an error. /// 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 struct SubDiagnostic {
pub level: Level, pub level: Level,
pub message: Vec<(String, Style)>, pub message: Vec<(String, Style)>,

View file

@ -18,10 +18,12 @@
#![feature(range_contains)] #![feature(range_contains)]
#![cfg_attr(unix, feature(libc))] #![cfg_attr(unix, feature(libc))]
#![feature(conservative_impl_trait)] #![feature(conservative_impl_trait)]
#![feature(i128_type)]
extern crate term; extern crate term;
#[cfg(unix)] #[cfg(unix)]
extern crate libc; extern crate libc;
extern crate rustc_data_structures;
extern crate serialize as rustc_serialize; extern crate serialize as rustc_serialize;
extern crate syntax_pos; extern crate syntax_pos;
@ -31,6 +33,9 @@ use self::Level::*;
use emitter::{Emitter, EmitterWriter}; use emitter::{Emitter, EmitterWriter};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stable_hasher::StableHasher;
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::{RefCell, Cell}; use std::cell::{RefCell, Cell};
use std::mem; use std::mem;
@ -47,7 +52,7 @@ mod lock;
use syntax_pos::{BytePos, Loc, FileLinesResult, FileMap, FileName, MultiSpan, Span, NO_EXPANSION}; 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 { pub enum RenderSpan {
/// A FullSpan renders with both with an initial line for the /// A FullSpan renders with both with an initial line for the
/// message, prefixed by file:linenum, followed by a summary of /// message, prefixed by file:linenum, followed by a summary of
@ -61,7 +66,7 @@ pub enum RenderSpan {
Suggestion(CodeSuggestion), Suggestion(CodeSuggestion),
} }
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] #[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
pub struct CodeSuggestion { pub struct CodeSuggestion {
/// Each substitute can have multiple variants due to multiple /// Each substitute can have multiple variants due to multiple
/// applicable suggestions /// applicable suggestions
@ -86,7 +91,7 @@ pub struct CodeSuggestion {
pub show_code_when_inline: bool, 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` /// See the docs on `CodeSuggestion::substitutions`
pub struct Substitution { pub struct Substitution {
pub span: Span, pub span: Span,
@ -271,6 +276,11 @@ pub struct Handler {
continue_after_error: Cell<bool>, continue_after_error: Cell<bool>,
delayed_span_bug: RefCell<Option<Diagnostic>>, delayed_span_bug: RefCell<Option<Diagnostic>>,
tracked_diagnostics: RefCell<Option<Vec<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 { impl Handler {
@ -295,6 +305,7 @@ impl Handler {
continue_after_error: Cell::new(true), continue_after_error: Cell::new(true),
delayed_span_bug: RefCell::new(None), delayed_span_bug: RefCell::new(None),
tracked_diagnostics: 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) { fn emit_db(&self, db: &DiagnosticBuilder) {
let diagnostic = &**db;
if let Some(ref mut list) = *self.tracked_diagnostics.borrow_mut() { 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 { pub enum Level {
Bug, Bug,
Fatal, Fatal,

View file

@ -203,7 +203,7 @@ pub struct StyledString {
pub style: Style, pub style: Style,
} }
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)] #[derive(Copy, Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
pub enum Style { pub enum Style {
HeaderMsg, HeaderMsg,
LineAndColumn, LineAndColumn,