From ef6a07221d66bff1ef8edac4f9ffc39013abf256 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Wed, 26 Oct 2016 23:07:38 -0700 Subject: [PATCH] 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. --- src/librustc/lint/context.rs | 2 +- src/librustc/session/mod.rs | 17 +++++++-------- src/test/ui/span/issue-24690.rs | 22 ++++++++++++++++++++ src/test/ui/span/issue-24690.stderr | 32 +++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/span/issue-24690.rs create mode 100644 src/test/ui/span/issue-24690.stderr diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index eebf4d32ab2..cf4115e37cd 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -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 diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 154fe9af79a..ce3f2be54b2 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -75,10 +75,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 + /// 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>, + pub one_time_diagnostics: RefCell>, pub plugin_llvm_passes: RefCell>, pub mir_passes: RefCell, pub plugin_attributes: RefCell>, @@ -294,8 +294,8 @@ pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler { } /// 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 @@ pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler { // 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 @@ pub fn diag_span_note_once<'a, 'b>(&'a self, 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); } diff --git a/src/test/ui/span/issue-24690.rs b/src/test/ui/span/issue-24690.rs new file mode 100644 index 00000000000..def0d9aced3 --- /dev/null +++ b/src/test/ui/span/issue-24690.rs @@ -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 or the MIT license +// , 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); +} diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr new file mode 100644 index 00000000000..0d2a2ef7516 --- /dev/null +++ b/src/test/ui/span/issue-24690.stderr @@ -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 + -- 2.44.0