Skip to content

Commit 6fccd71

Browse files
librustc_errors: Don't emit the same error message twice.
1 parent 67f3dc3 commit 6fccd71

File tree

5 files changed

+36
-9
lines changed

5 files changed

+36
-9
lines changed

src/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc_errors/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ crate-type = ["dylib"]
1111
[dependencies]
1212
serialize = { path = "../libserialize" }
1313
syntax_pos = { path = "../libsyntax_pos" }
14+
rustc_data_structures = { path = "../librustc_data_structures" }

src/librustc_errors/diagnostic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use syntax_pos::{MultiSpan, Span};
1717
use snippet::Style;
1818

1919
#[must_use]
20-
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
20+
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
2121
pub struct Diagnostic {
2222
pub level: Level,
2323
pub message: Vec<(String, Style)>,
@@ -28,7 +28,7 @@ pub struct Diagnostic {
2828
}
2929

3030
/// For example a note attached to an error.
31-
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
31+
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
3232
pub struct SubDiagnostic {
3333
pub level: Level,
3434
pub message: Vec<(String, Style)>,

src/librustc_errors/lib.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
#![feature(range_contains)]
1919
#![cfg_attr(unix, feature(libc))]
2020
#![feature(conservative_impl_trait)]
21+
#![feature(i128_type)]
2122

2223
extern crate term;
2324
#[cfg(unix)]
2425
extern crate libc;
26+
extern crate rustc_data_structures;
2527
extern crate serialize as rustc_serialize;
2628
extern crate syntax_pos;
2729

@@ -31,6 +33,9 @@ use self::Level::*;
3133

3234
use emitter::{Emitter, EmitterWriter};
3335

36+
use rustc_data_structures::fx::FxHashSet;
37+
use rustc_data_structures::stable_hasher::StableHasher;
38+
3439
use std::borrow::Cow;
3540
use std::cell::{RefCell, Cell};
3641
use std::mem;
@@ -47,7 +52,7 @@ mod lock;
4752

4853
use syntax_pos::{BytePos, Loc, FileLinesResult, FileMap, FileName, MultiSpan, Span, NO_EXPANSION};
4954

50-
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
55+
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
5156
pub enum RenderSpan {
5257
/// A FullSpan renders with both with an initial line for the
5358
/// message, prefixed by file:linenum, followed by a summary of
@@ -61,7 +66,7 @@ pub enum RenderSpan {
6166
Suggestion(CodeSuggestion),
6267
}
6368

64-
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
69+
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
6570
pub struct CodeSuggestion {
6671
/// Each substitute can have multiple variants due to multiple
6772
/// applicable suggestions
@@ -86,7 +91,7 @@ pub struct CodeSuggestion {
8691
pub show_code_when_inline: bool,
8792
}
8893

89-
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
94+
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
9095
/// See the docs on `CodeSuggestion::substitutions`
9196
pub struct Substitution {
9297
pub span: Span,
@@ -271,6 +276,11 @@ pub struct Handler {
271276
continue_after_error: Cell<bool>,
272277
delayed_span_bug: RefCell<Option<Diagnostic>>,
273278
tracked_diagnostics: RefCell<Option<Vec<Diagnostic>>>,
279+
280+
// This set contains a hash of every diagnostic that has been emitted by
281+
// this handler. These hashes is used to avoid emitting the same error
282+
// twice.
283+
emitted_diagnostics: RefCell<FxHashSet<u128>>,
274284
}
275285

276286
impl Handler {
@@ -295,6 +305,7 @@ impl Handler {
295305
continue_after_error: Cell::new(true),
296306
delayed_span_bug: RefCell::new(None),
297307
tracked_diagnostics: RefCell::new(None),
308+
emitted_diagnostics: RefCell::new(FxHashSet()),
298309
}
299310
}
300311

@@ -559,15 +570,29 @@ impl Handler {
559570
}
560571

561572
fn emit_db(&self, db: &DiagnosticBuilder) {
573+
let diagnostic = &**db;
574+
562575
if let Some(ref mut list) = *self.tracked_diagnostics.borrow_mut() {
563-
list.push((**db).clone());
576+
list.push(diagnostic.clone());
577+
}
578+
579+
let diagnostic_hash = {
580+
use std::hash::Hash;
581+
let mut hasher = StableHasher::new();
582+
diagnostic.hash(&mut hasher);
583+
hasher.finish()
584+
};
585+
586+
// Only emit the diagnostic if we haven't already emitted an equivalent
587+
// one:
588+
if self.emitted_diagnostics.borrow_mut().insert(diagnostic_hash) {
589+
self.emitter.borrow_mut().emit(db);
564590
}
565-
self.emitter.borrow_mut().emit(db);
566591
}
567592
}
568593

569594

570-
#[derive(Copy, PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
595+
#[derive(Copy, PartialEq, Clone, Hash, Debug, RustcEncodable, RustcDecodable)]
571596
pub enum Level {
572597
Bug,
573598
Fatal,

src/librustc_errors/snippet.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ pub struct StyledString {
203203
pub style: Style,
204204
}
205205

206-
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
206+
#[derive(Copy, Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
207207
pub enum Style {
208208
HeaderMsg,
209209
LineAndColumn,

0 commit comments

Comments
 (0)