deduplicate one-time diagnostics on lint ID as well as span and message
Some lint-level attributes (like `bad-style`, or, more dramatically, `warnings`) can affect more than one lint; it seems fairer to point out the attribute once for each distinct lint affected. Also, a UI test is added. This remains in the matter of #24690.
This commit is contained in:
parent
8d1da8452c
commit
ef6a07221d
4 changed files with 64 additions and 9 deletions
|
|
@ -452,7 +452,7 @@ pub fn raw_struct_lint<'a>(sess: &'a Session,
|
|||
}
|
||||
|
||||
if let Some(span) = def {
|
||||
sess.diag_span_note_once(&mut err, span, "lint level defined here");
|
||||
sess.diag_span_note_once(&mut err, lint, span, "lint level defined here");
|
||||
}
|
||||
|
||||
err
|
||||
|
|
|
|||
|
|
@ -75,10 +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
|
||||
/// Set of (LintId, 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 one_time_diagnostics: RefCell<FnvHashSet<(lint::LintId, Span, String)>>,
|
||||
pub plugin_llvm_passes: RefCell<Vec<String>>,
|
||||
pub mir_passes: RefCell<mir_pass::Passes>,
|
||||
pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
|
||||
|
|
@ -294,8 +294,8 @@ impl Session {
|
|||
}
|
||||
|
||||
/// Analogous to calling `.span_note` on the given DiagnosticBuilder, but
|
||||
/// deduplicates on span and message for this `Session` if we're not
|
||||
/// outputting in JSON mode.
|
||||
/// deduplicates on lint ID, span, and message for this `Session` if we're
|
||||
/// not outputting in JSON mode.
|
||||
//
|
||||
// FIXME: if the need arises for one-time diagnostics other than
|
||||
// `span_note`, we almost certainly want to generalize this
|
||||
|
|
@ -303,7 +303,7 @@ impl Session {
|
|||
// 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) {
|
||||
lint: &'static lint::Lint, span: Span, message: &str) {
|
||||
match self.opts.error_format {
|
||||
// when outputting JSON for tool consumption, the tool might want
|
||||
// the duplicates
|
||||
|
|
@ -311,8 +311,9 @@ impl Session {
|
|||
diag_builder.span_note(span, &message);
|
||||
},
|
||||
_ => {
|
||||
let span_message = (span, message.to_owned());
|
||||
let fresh = self.one_time_diagnostics.borrow_mut().insert(span_message);
|
||||
let lint_id = lint::LintId::of(lint);
|
||||
let id_span_message = (lint_id, span, message.to_owned());
|
||||
let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message);
|
||||
if fresh {
|
||||
diag_builder.span_note(span, &message);
|
||||
}
|
||||
|
|
|
|||
22
src/test/ui/span/issue-24690.rs
Normal file
22
src/test/ui/span/issue-24690.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! A test to ensure that helpful `note` messages aren't emitted more often
|
||||
//! than necessary.
|
||||
|
||||
// Although there are three errors, we should only get two "lint level defined
|
||||
// here" notes pointing at the `warnings` span, one for each error type.
|
||||
#![deny(warnings)]
|
||||
|
||||
fn main() {
|
||||
let theTwo = 2;
|
||||
let theOtherTwo = 2;
|
||||
println!("{}", theTwo);
|
||||
}
|
||||
32
src/test/ui/span/issue-24690.stderr
Normal file
32
src/test/ui/span/issue-24690.stderr
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
error: unused variable: `theOtherTwo`
|
||||
--> $DIR/issue-24690.rs:20:9
|
||||
|
|
||||
20 | let theOtherTwo = 2;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/issue-24690.rs:16:9
|
||||
|
|
||||
16 | #![deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
|
||||
error: variable `theTwo` should have a snake case name such as `the_two`
|
||||
--> $DIR/issue-24690.rs:19:9
|
||||
|
|
||||
19 | let theTwo = 2;
|
||||
| ^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/issue-24690.rs:16:9
|
||||
|
|
||||
16 | #![deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
|
||||
error: variable `theOtherTwo` should have a snake case name such as `the_other_two`
|
||||
--> $DIR/issue-24690.rs:20:9
|
||||
|
|
||||
20 | let theOtherTwo = 2;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue