From 864f6d180baf76365619a7fe76b6c8b87e5ead8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 21 Jan 2018 21:19:37 -0800 Subject: [PATCH] Only emit expanded diagnostic information once --- src/librustc_errors/diagnostic.rs | 6 +++++- src/librustc_errors/lib.rs | 10 ++++++++++ src/librustc_typeck/check/cast.rs | 22 +++++++++++++--------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 8da4321fa5b..2e654fe9929 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -27,7 +27,7 @@ pub struct Diagnostic { pub suggestions: Vec, } -#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum DiagnosticId { Error(String), Lint(String), @@ -281,6 +281,10 @@ pub fn code(&mut self, s: DiagnosticId) -> &mut Self { self } + pub fn get_code(&self) -> Option { + self.code.clone() + } + pub fn message(&self) -> String { self.message.iter().map(|i| i.0.to_owned()).collect::() } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 1fb673815ee..cabafa052a3 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -244,6 +244,7 @@ pub struct Handler { continue_after_error: Cell, delayed_span_bug: RefCell>, tracked_diagnostics: RefCell>>, + tracked_diagnostic_codes: RefCell>, // 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 @@ -303,6 +304,7 @@ pub fn with_emitter_and_flags(e: Box, flags: HandlerFlags) -> Handler { continue_after_error: Cell::new(true), delayed_span_bug: RefCell::new(None), tracked_diagnostics: RefCell::new(None), + tracked_diagnostic_codes: RefCell::new(FxHashSet()), emitted_diagnostics: RefCell::new(FxHashSet()), } } @@ -575,6 +577,10 @@ pub fn track_diagnostics(&self, f: F) -> (R, Vec) (ret, diagnostics) } + pub fn code_emitted(&self, code: &DiagnosticId) -> bool { + self.tracked_diagnostic_codes.borrow().contains(code) + } + fn emit_db(&self, db: &DiagnosticBuilder) { let diagnostic = &**db; @@ -582,6 +588,10 @@ fn emit_db(&self, db: &DiagnosticBuilder) { list.push(diagnostic.clone()); } + if let Some(ref code) = diagnostic.code { + self.tracked_diagnostic_codes.borrow_mut().insert(code.clone()); + } + let diagnostic_hash = { use std::hash::Hash; let mut hasher = StableHasher::new(); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index d31a99dd171..3cd93a1c845 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -290,18 +290,22 @@ fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) { self.expr_ty, fcx.ty_to_string(self.cast_ty) ); - if fcx.tcx.sess.opts.debugging_opts.explain { + if fcx.tcx.sess.opts.debugging_opts.explain + && !fcx.tcx.sess.parse_sess.span_diagnostic + .code_emitted(&err.get_code().unwrap()) { err.note( - "Thin pointers are \"simple\" pointers: they are purely a reference to a \ - memory address.\n\n\ - Fat pointers are pointers referencing \"Dynamically Sized Types\" (also \ - called DST). DST don't have a statically known size, therefore they can \ - only exist behind some kind of pointers that contain additional \ - information. Slices and trait objects are DSTs. In the case of slices, \ - the additional information the fat pointer holds is their size."); + "Thin pointers are \"simple\" pointers: they are purely a reference to a +memory address. + +Fat pointers are pointers referencing \"Dynamically Sized Types\" (also +called DST). DST don't have a statically known size, therefore they can +only exist behind some kind of pointers that contain additional +information. Slices and trait objects are DSTs. In the case of slices, +the additional information the fat pointer holds is their size."); err.note("to fix this error, don't try to cast directly between thin and fat \ pointers"); - err.help("for more information about casts, take a look at [The Book]\ + err.help("for more information about casts, take a look at + [The Book]\ (https://doc.rust-lang.org/book/first-edition/\ casting-between-types.html)"); }