Skip to content

Commit bfe0098

Browse files
author
Ariel Ben-Yehuda
authored
Rollup merge of rust-lang#42919 - zackmdavis:once_again_we_heard_you_the_first_time, r=eddyb
make lint on-by-default/implied-by messages appear only once From review discussion on rust-lang#38103 (rust-lang#38103 (comment)). ![we_heard](https://user-images.githubusercontent.com/1076988/27564103-6284b78e-5a8a-11e7-9d35-f7f297ca9573.png) r? @nikomatsakis
2 parents ea762f2 + 32b8579 commit bfe0098

File tree

5 files changed

+63
-41
lines changed

5 files changed

+63
-41
lines changed

src/librustc/lint/context.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,6 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
510510
}
511511

512512
let name = lint.name_lower();
513-
let mut def = None;
514513

515514
// Except for possible note details, forbid behaves like deny.
516515
let effective_level = if level == Forbid { Deny } else { level };
@@ -525,7 +524,8 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
525524

526525
match source {
527526
Default => {
528-
err.note(&format!("#[{}({})] on by default", level.as_str(), name));
527+
sess.diag_note_once(&mut err, lint,
528+
&format!("#[{}({})] on by default", level.as_str(), name));
529529
},
530530
CommandLine(lint_flag_val) => {
531531
let flag = match level {
@@ -534,20 +534,24 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
534534
};
535535
let hyphen_case_lint_name = name.replace("_", "-");
536536
if lint_flag_val.as_str() == name {
537-
err.note(&format!("requested on the command line with `{} {}`",
538-
flag, hyphen_case_lint_name));
537+
sess.diag_note_once(&mut err, lint,
538+
&format!("requested on the command line with `{} {}`",
539+
flag, hyphen_case_lint_name));
539540
} else {
540541
let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
541-
err.note(&format!("`{} {}` implied by `{} {}`",
542-
flag, hyphen_case_lint_name, flag, hyphen_case_flag_val));
542+
sess.diag_note_once(&mut err, lint,
543+
&format!("`{} {}` implied by `{} {}`",
544+
flag, hyphen_case_lint_name, flag,
545+
hyphen_case_flag_val));
543546
}
544547
},
545548
Node(lint_attr_name, src) => {
546-
def = Some(src);
549+
sess.diag_span_note_once(&mut err, lint, src, "lint level defined here");
547550
if lint_attr_name.as_str() != name {
548551
let level_str = level.as_str();
549-
err.note(&format!("#[{}({})] implied by #[{}({})]",
550-
level_str, name, level_str, lint_attr_name));
552+
sess.diag_note_once(&mut err, lint,
553+
&format!("#[{}({})] implied by #[{}({})]",
554+
level_str, name, level_str, lint_attr_name));
551555
}
552556
}
553557
}
@@ -563,10 +567,6 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
563567
err.note(&citation);
564568
}
565569

566-
if let Some(span) = def {
567-
sess.diag_span_note_once(&mut err, lint, span, "lint level defined here");
568-
}
569-
570570
err
571571
}
572572

src/librustc/session/mod.rs

+43-17
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ pub struct Session {
7979
pub working_dir: (String, bool),
8080
pub lint_store: RefCell<lint::LintStore>,
8181
pub lints: RefCell<lint::LintTable>,
82-
/// Set of (LintId, span, message) tuples tracking lint (sub)diagnostics
83-
/// that have been set once, but should not be set again, in order to avoid
84-
/// redundantly verbose output (Issue #24690).
85-
pub one_time_diagnostics: RefCell<FxHashSet<(lint::LintId, Span, String)>>,
82+
/// Set of (LintId, Option<Span>, message) tuples tracking lint
83+
/// (sub)diagnostics that have been set once, but should not be set again,
84+
/// in order to avoid redundantly verbose output (Issue #24690).
85+
pub one_time_diagnostics: RefCell<FxHashSet<(lint::LintId, Option<Span>, String)>>,
8686
pub plugin_llvm_passes: RefCell<Vec<String>>,
8787
pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
8888
pub crate_types: RefCell<Vec<config::CrateType>>,
@@ -157,6 +157,13 @@ pub struct PerfStats {
157157
pub decode_def_path_tables_time: Cell<Duration>,
158158
}
159159

160+
/// Enum to support dispatch of one-time diagnostics (in Session.diag_once)
161+
enum DiagnosticBuilderMethod {
162+
Note,
163+
SpanNote,
164+
// add more variants as needed to support one-time diagnostics
165+
}
166+
160167
impl Session {
161168
pub fn local_crate_disambiguator(&self) -> Symbol {
162169
*self.crate_disambiguator.borrow()
@@ -329,34 +336,53 @@ impl Session {
329336
&self.parse_sess.span_diagnostic
330337
}
331338

332-
/// Analogous to calling `.span_note` on the given DiagnosticBuilder, but
333-
/// deduplicates on lint ID, span, and message for this `Session` if we're
334-
/// not outputting in JSON mode.
335-
//
336-
// FIXME: if the need arises for one-time diagnostics other than
337-
// `span_note`, we almost certainly want to generalize this
338-
// "check/insert-into the one-time diagnostics map, then set message if
339-
// it's not already there" code to accomodate all of them
340-
pub fn diag_span_note_once<'a, 'b>(&'a self,
341-
diag_builder: &'b mut DiagnosticBuilder<'a>,
342-
lint: &'static lint::Lint, span: Span, message: &str) {
339+
/// Analogous to calling methods on the given `DiagnosticBuilder`, but
340+
/// deduplicates on lint ID, span (if any), and message for this `Session`
341+
/// if we're not outputting in JSON mode.
342+
fn diag_once<'a, 'b>(&'a self,
343+
diag_builder: &'b mut DiagnosticBuilder<'a>,
344+
method: DiagnosticBuilderMethod,
345+
lint: &'static lint::Lint, message: &str, span: Option<Span>) {
346+
let mut do_method = || {
347+
match method {
348+
DiagnosticBuilderMethod::Note => {
349+
diag_builder.note(message);
350+
},
351+
DiagnosticBuilderMethod::SpanNote => {
352+
diag_builder.span_note(span.expect("span_note expects a span"), message);
353+
}
354+
}
355+
};
356+
343357
match self.opts.error_format {
344358
// when outputting JSON for tool consumption, the tool might want
345359
// the duplicates
346360
config::ErrorOutputType::Json => {
347-
diag_builder.span_note(span, &message);
361+
do_method()
348362
},
349363
_ => {
350364
let lint_id = lint::LintId::of(lint);
351365
let id_span_message = (lint_id, span, message.to_owned());
352366
let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message);
353367
if fresh {
354-
diag_builder.span_note(span, &message);
368+
do_method()
355369
}
356370
}
357371
}
358372
}
359373

374+
pub fn diag_span_note_once<'a, 'b>(&'a self,
375+
diag_builder: &'b mut DiagnosticBuilder<'a>,
376+
lint: &'static lint::Lint, span: Span, message: &str) {
377+
self.diag_once(diag_builder, DiagnosticBuilderMethod::SpanNote, lint, message, Some(span));
378+
}
379+
380+
pub fn diag_note_once<'a, 'b>(&'a self,
381+
diag_builder: &'b mut DiagnosticBuilder<'a>,
382+
lint: &'static lint::Lint, message: &str) {
383+
self.diag_once(diag_builder, DiagnosticBuilderMethod::Note, lint, message, None);
384+
}
385+
360386
pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
361387
self.parse_sess.codemap()
362388
}

src/test/ui/lint/lint-group-style.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,64 +4,64 @@ error: function `CamelCase` should have a snake case name such as `camel_case`
44
14 | fn CamelCase() {}
55
| ^^^^^^^^^^^^^^^^^
66
|
7-
= note: #[deny(non_snake_case)] implied by #[deny(bad_style)]
87
note: lint level defined here
98
--> $DIR/lint-group-style.rs:11:9
109
|
1110
11 | #![deny(bad_style)]
1211
| ^^^^^^^^^
12+
= note: #[deny(non_snake_case)] implied by #[deny(bad_style)]
1313

1414
error: function `CamelCase` should have a snake case name such as `camel_case`
1515
--> $DIR/lint-group-style.rs:22:9
1616
|
1717
22 | fn CamelCase() {}
1818
| ^^^^^^^^^^^^^^^^^
1919
|
20-
= note: #[forbid(non_snake_case)] implied by #[forbid(bad_style)]
2120
note: lint level defined here
2221
--> $DIR/lint-group-style.rs:20:14
2322
|
2423
20 | #[forbid(bad_style)]
2524
| ^^^^^^^^^
25+
= note: #[forbid(non_snake_case)] implied by #[forbid(bad_style)]
2626

2727
error: static variable `bad` should have an upper case name such as `BAD`
2828
--> $DIR/lint-group-style.rs:24:9
2929
|
3030
24 | static bad: isize = 1;
3131
| ^^^^^^^^^^^^^^^^^^^^^^
3232
|
33-
= note: #[forbid(non_upper_case_globals)] implied by #[forbid(bad_style)]
3433
note: lint level defined here
3534
--> $DIR/lint-group-style.rs:20:14
3635
|
3736
20 | #[forbid(bad_style)]
3837
| ^^^^^^^^^
38+
= note: #[forbid(non_upper_case_globals)] implied by #[forbid(bad_style)]
3939

4040
warning: function `CamelCase` should have a snake case name such as `camel_case`
4141
--> $DIR/lint-group-style.rs:30:9
4242
|
4343
30 | fn CamelCase() {}
4444
| ^^^^^^^^^^^^^^^^^
4545
|
46-
= note: #[warn(non_snake_case)] implied by #[warn(bad_style)]
4746
note: lint level defined here
4847
--> $DIR/lint-group-style.rs:28:17
4948
|
5049
28 | #![warn(bad_style)]
5150
| ^^^^^^^^^
51+
= note: #[warn(non_snake_case)] implied by #[warn(bad_style)]
5252

5353
warning: type `snake_case` should have a camel case name such as `SnakeCase`
5454
--> $DIR/lint-group-style.rs:32:9
5555
|
5656
32 | struct snake_case;
5757
| ^^^^^^^^^^^^^^^^^^
5858
|
59-
= note: #[warn(non_camel_case_types)] implied by #[warn(bad_style)]
6059
note: lint level defined here
6160
--> $DIR/lint-group-style.rs:28:17
6261
|
6362
28 | #![warn(bad_style)]
6463
| ^^^^^^^^^
64+
= note: #[warn(non_camel_case_types)] implied by #[warn(bad_style)]
6565

6666
error: aborting due to previous error(s)
6767

src/test/ui/path-lookahead.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,4 @@ warning: function is never used: `no_parens`
2323
20 | | return <T as ToString>::to_string(&arg);
2424
21 | | }
2525
| |_^
26-
|
27-
= note: #[warn(dead_code)] on by default
2826

src/test/ui/span/issue-24690.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,31 @@ error: variable `theTwo` should have a snake case name such as `the_two`
44
19 | let theTwo = 2;
55
| ^^^^^^
66
|
7-
= note: #[deny(non_snake_case)] implied by #[deny(warnings)]
87
note: lint level defined here
98
--> $DIR/issue-24690.rs:16:9
109
|
1110
16 | #![deny(warnings)]
1211
| ^^^^^^^^
12+
= note: #[deny(non_snake_case)] implied by #[deny(warnings)]
1313

1414
error: variable `theOtherTwo` should have a snake case name such as `the_other_two`
1515
--> $DIR/issue-24690.rs:20:9
1616
|
1717
20 | let theOtherTwo = 2;
1818
| ^^^^^^^^^^^
19-
|
20-
= note: #[deny(non_snake_case)] implied by #[deny(warnings)]
2119

2220
error: unused variable: `theOtherTwo`
2321
--> $DIR/issue-24690.rs:20:9
2422
|
2523
20 | let theOtherTwo = 2;
2624
| ^^^^^^^^^^^
2725
|
28-
= note: #[deny(unused_variables)] implied by #[deny(warnings)]
2926
note: lint level defined here
3027
--> $DIR/issue-24690.rs:16:9
3128
|
3229
16 | #![deny(warnings)]
3330
| ^^^^^^^^
31+
= note: #[deny(unused_variables)] implied by #[deny(warnings)]
3432

3533
error: aborting due to previous error(s)
3634

0 commit comments

Comments
 (0)