Skip to content

Commit 1bfa1d5

Browse files
committedOct 15, 2016
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.
1 parent 8e05e7e commit 1bfa1d5

File tree

4 files changed

+28
-18
lines changed

4 files changed

+28
-18
lines changed
 

‎src/librustc/lint/context.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,7 @@ pub fn raw_struct_lint<'a>(sess: &'a Session,
452452
}
453453

454454
if let Some(span) = def {
455-
let explanation = "lint level defined here";
456-
err.span_note(span, &explanation);
455+
sess.diag_span_note_once(&mut err, span, "lint level defined here");
457456
}
458457

459458
err

‎src/librustc/session/mod.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use middle::dependency_format;
1717
use session::search_paths::PathKind;
1818
use session::config::DebugInfoLevel;
1919
use ty::tls;
20-
use util::nodemap::{NodeMap, FnvHashMap};
20+
use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
2121
use util::common::duration_to_secs_str;
2222
use mir::transform as mir_pass;
2323

@@ -75,6 +75,10 @@ pub struct Session {
7575
pub working_dir: PathBuf,
7676
pub lint_store: RefCell<lint::LintStore>,
7777
pub lints: RefCell<NodeMap<Vec<(lint::LintId, Span, String)>>>,
78+
/// Set of (span, message) tuples tracking lint (sub)diagnostics that have
79+
/// been set once, but should not be set again, in order to avoid
80+
/// redundantly verbose output (Issue #24690).
81+
pub one_time_diagnostics: RefCell<FnvHashSet<(Span, String)>>,
7882
pub plugin_llvm_passes: RefCell<Vec<String>>,
7983
pub mir_passes: RefCell<mir_pass::Passes>,
8084
pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
@@ -288,6 +292,26 @@ impl Session {
288292
pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
289293
&self.parse_sess.span_diagnostic
290294
}
295+
296+
/// Analogous to calling `.span_note` on the given DiagnosticBuilder, but
297+
/// deduplicates on span and message for this `Session`.
298+
//
299+
// FIXME: if the need arises for one-time diagnostics other than
300+
// `span_note`, we almost certainly want to generalize this "check the
301+
// one-time diagnostics map, then set message if it's not already there"
302+
// code to accomodate all of them
303+
pub fn diag_span_note_once<'a, 'b>(&'a self,
304+
diag_builder: &'b mut DiagnosticBuilder<'a>,
305+
span: Span, message: &str) {
306+
let span_message = (span, message.to_owned());
307+
let already_noted: bool = self.one_time_diagnostics.borrow()
308+
.contains(&span_message);
309+
if !already_noted {
310+
diag_builder.span_note(span, &message);
311+
self.one_time_diagnostics.borrow_mut().insert(span_message);
312+
}
313+
}
314+
291315
pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
292316
self.parse_sess.codemap()
293317
}
@@ -561,6 +585,7 @@ pub fn build_session_(sopts: config::Options,
561585
working_dir: env::current_dir().unwrap(),
562586
lint_store: RefCell::new(lint::LintStore::new()),
563587
lints: RefCell::new(NodeMap()),
588+
one_time_diagnostics: RefCell::new(FnvHashSet()),
564589
plugin_llvm_passes: RefCell::new(Vec::new()),
565590
mir_passes: RefCell::new(mir_pass::Passes::new()),
566591
plugin_attributes: RefCell::new(Vec::new()),

‎src/test/compile-fail/lint-group-style.rs

-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ mod test {
2020

2121
#[forbid(bad_style)]
2222
//~^ NOTE lint level defined here
23-
//~^^ NOTE lint level defined here
2423
mod bad {
2524
fn CamelCase() {} //~ ERROR function `CamelCase` should have a snake case name
2625

@@ -30,7 +29,6 @@ mod test {
3029
mod warn {
3130
#![warn(bad_style)]
3231
//~^ NOTE lint level defined here
33-
//~| NOTE lint level defined here
3432

3533
fn CamelCase() {} //~ WARN function `CamelCase` should have a snake case name
3634

‎src/test/compile-fail/lint-unconditional-recursion.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,7 @@
1010

1111
#![deny(unconditional_recursion)]
1212
//~^ NOTE lint level defined here
13-
//~| NOTE lint level defined here
14-
//~| NOTE lint level defined here
15-
//~| NOTE lint level defined here
16-
//~| NOTE lint level defined here
17-
//~| NOTE lint level defined here
18-
//~| NOTE lint level defined here
19-
//~| NOTE lint level defined here
20-
//~| NOTE lint level defined here
21-
//~| NOTE lint level defined here
22-
//~| NOTE lint level defined here
23-
//~| NOTE lint level defined here
24-
//~| NOTE lint level defined here
25-
//~| NOTE lint level defined here
13+
2614
#![allow(dead_code)]
2715
fn foo() { //~ ERROR function cannot return without recurring
2816
foo(); //~ NOTE recursive call site

0 commit comments

Comments
 (0)