1
Fork 0

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
information. Slices and trait objects are DSTs. In the case of slices,
the additional information the fat pointer holds is their size."); 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)");
} }