Only emit expanded diagnostic information once
This commit is contained in:
parent
e76d3f62cc
commit
864f6d180b
@ -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>()
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user