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"
version = "0.0.0"
dependencies = [
"rustc_data_structures 0.0.0",
"serialize 0.0.0",
"syntax_pos 0.0.0",
]

View File

@ -11,3 +11,4 @@ crate-type = ["dylib"]
[dependencies]
serialize = { path = "../libserialize" }
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;
#[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)>,

View File

@ -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,

View File

@ -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,