Only emit expanded diagnostic information once

This commit is contained in:
Esteban Küber 2018-01-21 21:19:37 -08:00
parent e76d3f62cc
commit 864f6d180b
3 changed files with 28 additions and 10 deletions

View File

@ -27,7 +27,7 @@ pub struct Diagnostic {
pub suggestions: Vec<CodeSuggestion>, pub suggestions: Vec<CodeSuggestion>,
} }
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum DiagnosticId { pub enum DiagnosticId {
Error(String), Error(String),
Lint(String), Lint(String),
@ -281,6 +281,10 @@ impl Diagnostic {
self self
} }
pub fn get_code(&self) -> Option<DiagnosticId> {
self.code.clone()
}
pub fn message(&self) -> String { pub fn message(&self) -> String {
self.message.iter().map(|i| i.0.to_owned()).collect::<String>() self.message.iter().map(|i| i.0.to_owned()).collect::<String>()
} }

View File

@ -244,6 +244,7 @@ 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>>>,
tracked_diagnostic_codes: RefCell<FxHashSet<DiagnosticId>>,
// This set contains a hash of every diagnostic that has been emitted by // 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 // this handler. These hashes is used to avoid emitting the same error
@ -303,6 +304,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),
tracked_diagnostic_codes: RefCell::new(FxHashSet()),
emitted_diagnostics: RefCell::new(FxHashSet()), emitted_diagnostics: RefCell::new(FxHashSet()),
} }
} }
@ -575,6 +577,10 @@ impl Handler {
(ret, diagnostics) (ret, diagnostics)
} }
pub fn code_emitted(&self, code: &DiagnosticId) -> bool {
self.tracked_diagnostic_codes.borrow().contains(code)
}
fn emit_db(&self, db: &DiagnosticBuilder) { fn emit_db(&self, db: &DiagnosticBuilder) {
let diagnostic = &**db; let diagnostic = &**db;
@ -582,6 +588,10 @@ impl Handler {
list.push(diagnostic.clone()); list.push(diagnostic.clone());
} }
if let Some(ref code) = diagnostic.code {
self.tracked_diagnostic_codes.borrow_mut().insert(code.clone());
}
let diagnostic_hash = { let diagnostic_hash = {
use std::hash::Hash; use std::hash::Hash;
let mut hasher = StableHasher::new(); let mut hasher = StableHasher::new();

View File

@ -290,18 +290,22 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
self.expr_ty, self.expr_ty,
fcx.ty_to_string(self.cast_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( err.note(
"Thin pointers are \"simple\" pointers: they are purely a reference to a \ "Thin pointers are \"simple\" pointers: they are purely a reference to a
memory address.\n\n\ memory address.
Fat pointers are pointers referencing \"Dynamically Sized Types\" (also \
called DST). DST don't have a statically known size, therefore they can \ Fat pointers are pointers referencing \"Dynamically Sized Types\" (also
only exist behind some kind of pointers that contain additional \ called DST). DST don't have a statically known size, therefore they can
information. Slices and trait objects are DSTs. In the case of slices, \ only exist behind some kind of pointers that contain additional
the additional information the fat pointer holds is their size."); 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 \ err.note("to fix this error, don't try to cast directly between thin and fat \
pointers"); 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/\ (https://doc.rust-lang.org/book/first-edition/\
casting-between-types.html)"); casting-between-types.html)");
} }