From 3dd73b038e8cf9b11d600778b88d4dce2de73a9f Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Sat, 4 Jun 2016 22:12:25 -0700 Subject: [PATCH] only emit "lint level defined here" the first time 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. It is the responsibility of the caller setting a diagnostic to decide whether to add to `one_time_diagnostics`; there are other situations where we likely do want it to be possible for a note to appear twice on the same span with the same message (e.g., "prior assignment occurs here"). This is in the matter of #24690. --- src/librustc/lint/context.rs | 8 +++++++- src/librustc/session/mod.rs | 7 ++++++- src/test/compile-fail/lint-group-style.rs | 2 -- .../compile-fail/lint-no-drop-on-repr-extern.rs | 1 - .../compile-fail/lint-unconditional-recursion.rs | 14 +------------- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 94f17ea779ac8..d77b8e4b43702 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -462,7 +462,13 @@ 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); + let span_explanation = (span, explanation.to_owned()); + let already_noted: bool = sess.one_time_diagnostics.borrow() + .contains(&span_explanation); + if !already_noted { + err.span_note(span, explanation); + sess.one_time_diagnostics.borrow_mut().insert(span_explanation); + } } err diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 100b204b50135..1e277e2d297ad 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -17,7 +17,7 @@ use middle::dependency_format; use session::search_paths::PathKind; use session::config::{DebugInfoLevel, PanicStrategy}; use ty::tls; -use util::nodemap::{NodeMap, FnvHashMap}; +use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet}; use mir::transform as mir_pass; use syntax::ast::{NodeId, NodeIdAssigner, Name}; @@ -70,6 +70,10 @@ pub struct Session { pub working_dir: PathBuf, pub lint_store: RefCell, pub lints: RefCell>>, + /// 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. + pub one_time_diagnostics: RefCell>, pub plugin_llvm_passes: RefCell>, pub mir_passes: RefCell, pub plugin_attributes: RefCell>, @@ -523,6 +527,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()), diff --git a/src/test/compile-fail/lint-group-style.rs b/src/test/compile-fail/lint-group-style.rs index 393e46ab5394c..a88e0c63ac374 100644 --- a/src/test/compile-fail/lint-group-style.rs +++ b/src/test/compile-fail/lint-group-style.rs @@ -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 diff --git a/src/test/compile-fail/lint-no-drop-on-repr-extern.rs b/src/test/compile-fail/lint-no-drop-on-repr-extern.rs index 91e5065517dcc..8c911cad34bfe 100644 --- a/src/test/compile-fail/lint-no-drop-on-repr-extern.rs +++ b/src/test/compile-fail/lint-no-drop-on-repr-extern.rs @@ -16,7 +16,6 @@ #![feature(unsafe_no_drop_flag)] #![deny(drop_with_repr_extern)] //~^ NOTE lint level defined here -//~| NOTE lint level defined here #[repr(C)] struct As { x: Box } #[repr(C)] enum Ae { Ae(Box), _None } diff --git a/src/test/compile-fail/lint-unconditional-recursion.rs b/src/test/compile-fail/lint-unconditional-recursion.rs index 94e189aa47f6f..bee5a2c45be6d 100644 --- a/src/test/compile-fail/lint-unconditional-recursion.rs +++ b/src/test/compile-fail/lint-unconditional-recursion.rs @@ -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