mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
introing one-time diagnostics: only emit "lint level defined here" once
We introduce a new `one_time_diagnostics` field on `rustc::session::Session` to hold a hashset of diagnostic messages we've set once but don't want to see again (as uniquified by span and message text), "lint level defined here" being the motivating example dealt with here. This is in the matter of #24690.
This commit is contained in:
parent
8e05e7ee3c
commit
1bfa1d51fd
@ -452,8 +452,7 @@ pub fn raw_struct_lint<'a>(sess: &'a Session,
|
||||
}
|
||||
|
||||
if let Some(span) = def {
|
||||
let explanation = "lint level defined here";
|
||||
err.span_note(span, &explanation);
|
||||
sess.diag_span_note_once(&mut err, span, "lint level defined here");
|
||||
}
|
||||
|
||||
err
|
||||
|
@ -17,7 +17,7 @@ use middle::dependency_format;
|
||||
use session::search_paths::PathKind;
|
||||
use session::config::DebugInfoLevel;
|
||||
use ty::tls;
|
||||
use util::nodemap::{NodeMap, FnvHashMap};
|
||||
use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
|
||||
use util::common::duration_to_secs_str;
|
||||
use mir::transform as mir_pass;
|
||||
|
||||
@ -75,6 +75,10 @@ pub struct Session {
|
||||
pub working_dir: PathBuf,
|
||||
pub lint_store: RefCell<lint::LintStore>,
|
||||
pub lints: RefCell<NodeMap<Vec<(lint::LintId, Span, String)>>>,
|
||||
/// Set of (span, message) tuples tracking lint (sub)diagnostics that have
|
||||
/// been set once, but should not be set again, in order to avoid
|
||||
/// redundantly verbose output (Issue #24690).
|
||||
pub one_time_diagnostics: RefCell<FnvHashSet<(Span, String)>>,
|
||||
pub plugin_llvm_passes: RefCell<Vec<String>>,
|
||||
pub mir_passes: RefCell<mir_pass::Passes>,
|
||||
pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
|
||||
@ -288,6 +292,26 @@ impl Session {
|
||||
pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
|
||||
&self.parse_sess.span_diagnostic
|
||||
}
|
||||
|
||||
/// Analogous to calling `.span_note` on the given DiagnosticBuilder, but
|
||||
/// deduplicates on span and message for this `Session`.
|
||||
//
|
||||
// FIXME: if the need arises for one-time diagnostics other than
|
||||
// `span_note`, we almost certainly want to generalize this "check the
|
||||
// one-time diagnostics map, then set message if it's not already there"
|
||||
// code to accomodate all of them
|
||||
pub fn diag_span_note_once<'a, 'b>(&'a self,
|
||||
diag_builder: &'b mut DiagnosticBuilder<'a>,
|
||||
span: Span, message: &str) {
|
||||
let span_message = (span, message.to_owned());
|
||||
let already_noted: bool = self.one_time_diagnostics.borrow()
|
||||
.contains(&span_message);
|
||||
if !already_noted {
|
||||
diag_builder.span_note(span, &message);
|
||||
self.one_time_diagnostics.borrow_mut().insert(span_message);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
|
||||
self.parse_sess.codemap()
|
||||
}
|
||||
@ -561,6 +585,7 @@ pub fn build_session_(sopts: config::Options,
|
||||
working_dir: env::current_dir().unwrap(),
|
||||
lint_store: RefCell::new(lint::LintStore::new()),
|
||||
lints: RefCell::new(NodeMap()),
|
||||
one_time_diagnostics: RefCell::new(FnvHashSet()),
|
||||
plugin_llvm_passes: RefCell::new(Vec::new()),
|
||||
mir_passes: RefCell::new(mir_pass::Passes::new()),
|
||||
plugin_attributes: RefCell::new(Vec::new()),
|
||||
|
@ -20,7 +20,6 @@ mod test {
|
||||
|
||||
#[forbid(bad_style)]
|
||||
//~^ NOTE lint level defined here
|
||||
//~^^ NOTE lint level defined here
|
||||
mod bad {
|
||||
fn CamelCase() {} //~ ERROR function `CamelCase` should have a snake case name
|
||||
|
||||
@ -30,7 +29,6 @@ mod test {
|
||||
mod warn {
|
||||
#![warn(bad_style)]
|
||||
//~^ NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
|
||||
fn CamelCase() {} //~ WARN function `CamelCase` should have a snake case name
|
||||
|
||||
|
@ -10,19 +10,7 @@
|
||||
|
||||
#![deny(unconditional_recursion)]
|
||||
//~^ NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
//~| NOTE lint level defined here
|
||||
|
||||
#![allow(dead_code)]
|
||||
fn foo() { //~ ERROR function cannot return without recurring
|
||||
foo(); //~ NOTE recursive call site
|
||||
|
Loading…
Reference in New Issue
Block a user