Skip to content

Commit

Permalink
introing one-time diagnostics: only emit "lint level defined here" once
Browse files Browse the repository at this point in the history
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 rust-lang#24690.
  • Loading branch information
zackmdavis committed Oct 15, 2016
1 parent 8e05e7e commit 1bfa1d5
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 18 deletions.
3 changes: 1 addition & 2 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 26 additions & 1 deletion src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)>>,
Expand Down Expand Up @@ -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()
}
Expand Down Expand Up @@ -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()),
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/lint-group-style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down
14 changes: 1 addition & 13 deletions src/test/compile-fail/lint-unconditional-recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 1bfa1d5

Please sign in to comment.