about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-01-21 21:19:37 -0800
committerEsteban Küber <esteban@kuber.com.ar>2018-01-22 15:46:51 -0800
commit864f6d180baf76365619a7fe76b6c8b87e5ead8f (patch)
tree2f6a9c23802f4edf74a969da38b8341a932fe354 /src
parente76d3f62cc34a77496305639f22a7da168ebc301 (diff)
downloadrust-864f6d180baf76365619a7fe76b6c8b87e5ead8f.tar.gz
rust-864f6d180baf76365619a7fe76b6c8b87e5ead8f.zip
Only emit expanded diagnostic information once
Diffstat (limited to 'src')
-rw-r--r--src/librustc_errors/diagnostic.rs6
-rw-r--r--src/librustc_errors/lib.rs10
-rw-r--r--src/librustc_typeck/check/cast.rs22
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<CodeSuggestion>,
 }
 
-#[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 @@ impl Diagnostic {
         self
     }
 
+    pub fn get_code(&self) -> Option<DiagnosticId> {
+        self.code.clone()
+    }
+
     pub fn message(&self) -> String {
         self.message.iter().map(|i| i.0.to_owned()).collect::<String>()
     }
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<bool>,
     delayed_span_bug: RefCell<Option<Diagnostic>>,
     tracked_diagnostics: RefCell<Option<Vec<Diagnostic>>>,
+    tracked_diagnostic_codes: RefCell<FxHashSet<DiagnosticId>>,
 
     // 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 @@ impl 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 @@ impl Handler {
         (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 @@ impl Handler {
             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 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
                     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)");
                 }