Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

note individual lint name in messages set via lint group attribute #38103

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
69 changes: 43 additions & 26 deletions src/librustc/lint/context.rs
Expand Up @@ -40,8 +40,10 @@ use std::cmp;
use std::default::Default as StdDefault;
use std::mem;
use std::fmt;
use std::ops::Deref;
use syntax::attr;
use syntax::ast;
use syntax::symbol::Symbol;
use syntax_pos::{MultiSpan, Span};
use errors::{self, Diagnostic, DiagnosticBuilder};
use hir;
Expand Down Expand Up @@ -299,8 +301,9 @@ impl LintStore {
check_lint_name_cmdline(sess, self,
&lint_name[..], level);

let lint_flag_val = Symbol::intern(&lint_name);
match self.find_lint(&lint_name[..], sess, None) {
Ok(lint_id) => self.set_level(lint_id, (level, CommandLine)),
Ok(lint_id) => self.set_level(lint_id, (level, CommandLine(lint_flag_val))),
Err(FindLintError::Removed) => { }
Err(_) => {
match self.lint_groups.iter().map(|(&x, pair)| (x, pair.0.clone()))
Expand All @@ -310,7 +313,7 @@ impl LintStore {
Some(v) => {
v.iter()
.map(|lint_id: &LintId|
self.set_level(*lint_id, (level, CommandLine)))
self.set_level(*lint_id, (level, CommandLine(lint_flag_val))))
.collect::<Vec<()>>();
}
None => {
Expand Down Expand Up @@ -446,42 +449,54 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
-> DiagnosticBuilder<'a>
where S: Into<MultiSpan>
{
let (mut level, source) = lvlsrc;
let (level, source) = lvlsrc;
if level == Allow {
return sess.diagnostic().struct_dummy();
}

let name = lint.name_lower();
let mut def = None;
let msg = match source {
Default => {
format!("{}, #[{}({})] on by default", msg,
level.as_str(), name)
},
CommandLine => {
format!("{} [-{} {}]", msg,
match level {
Warn => 'W', Deny => 'D', Forbid => 'F',
Allow => bug!()
}, name.replace("_", "-"))
},
Node(src) => {
def = Some(src);
msg.to_string()
}
};

// For purposes of printing, we can treat forbid as deny.
if level == Forbid { level = Deny; }
// Except for possible note details, forbid behaves like deny.
let effective_level = if level == Forbid { Deny } else { level };

let mut err = match (level, span) {
let mut err = match (effective_level, span) {
(Warn, Some(sp)) => sess.struct_span_warn(sp, &msg[..]),
(Warn, None) => sess.struct_warn(&msg[..]),
(Deny, Some(sp)) => sess.struct_span_err(sp, &msg[..]),
(Deny, None) => sess.struct_err(&msg[..]),
_ => bug!("impossible level in raw_emit_lint"),
};

match source {
Default => {
err.note(&format!("#[{}({})] on by default", level.as_str(), name));
},
CommandLine(lint_flag_val) => {
let flag = match level {
Warn => "-W", Deny => "-D", Forbid => "-F",
Allow => bug!("earlier conditional return should handle Allow case")
};
let hyphen_case_lint_name = name.replace("_", "-");
if lint_flag_val.as_str().deref() == name {
err.note(&format!("requested on the command line with `{} {}`",
flag, hyphen_case_lint_name));
} else {
let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
err.note(&format!("`{} {}` implied by `{} {}`",
flag, hyphen_case_lint_name, flag, hyphen_case_flag_val));
}
},
Node(lint_attr_name, src) => {
def = Some(src);
if lint_attr_name.as_str().deref() != name {
let level_str = level.as_str();
err.note(&format!("#[{}({})] implied by #[{}({})]",
level_str, name, level_str, lint_attr_name));
}
}
}

// Check for future incompatibility lints and issue a stronger warning.
if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) {
let explanation = format!("this was previously accepted by the compiler \
Expand Down Expand Up @@ -649,6 +664,8 @@ pub trait LintContext<'tcx>: Sized {
}
};

let lint_attr_name = result.expect("lint attribute should be well-formed").0;

for (lint_id, level, span) in v {
let (now, now_source) = self.lints().get_level_source(lint_id);
if now == Forbid && level != Forbid {
Expand All @@ -660,19 +677,19 @@ pub trait LintContext<'tcx>: Sized {
diag_builder.span_label(span, &format!("overruled by previous forbid"));
match now_source {
LintSource::Default => &mut diag_builder,
LintSource::Node(forbid_source_span) => {
LintSource::Node(_, forbid_source_span) => {
diag_builder.span_label(forbid_source_span,
&format!("`forbid` level set here"))
},
LintSource::CommandLine => {
LintSource::CommandLine(_) => {
diag_builder.note("`forbid` lint level was set on command line")
}
}.emit()
} else if now != level {
let src = self.lints().get_level_source(lint_id).1;
self.level_stack().push((lint_id, (now, src)));
pushed += 1;
self.mut_lints().set_level(lint_id, (level, Node(span)));
self.mut_lints().set_level(lint_id, (level, Node(lint_attr_name, span)));
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/lint/mod.rs
Expand Up @@ -38,6 +38,7 @@ use std::ascii::AsciiExt;
use syntax_pos::Span;
use syntax::visit as ast_visit;
use syntax::ast;
use syntax::symbol::Symbol;

pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
Expand Down Expand Up @@ -338,10 +339,10 @@ pub enum LintSource {
Default,

/// Lint level was set by an attribute.
Node(Span),
Node(ast::Name, Span),

/// Lint level was set by a command-line flag.
CommandLine,
CommandLine(Symbol),
}

pub type LevelSource = (Level, LintSource);
Expand Down
1 change: 1 addition & 0 deletions src/test/compile-fail/imports/rfc-1560-warning-cycle.rs
Expand Up @@ -23,6 +23,7 @@ mod bar {
//~^ WARN `Foo` is ambiguous
//~| WARN hard error in a future release
//~| NOTE see issue #38260
//~| NOTE #[warn(legacy_imports)] on by default
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/test/compile-fail/issue-30730.rs
Expand Up @@ -9,5 +9,7 @@
// except according to those terms.

#![deny(warnings)] //~ NOTE: lint level defined here
use std::thread; //~ ERROR: unused import
use std::thread;
//~^ ERROR: unused import
//~| NOTE: #[deny(unused_imports)] implied by #[deny(warnings)]
fn main() {}
41 changes: 0 additions & 41 deletions src/test/compile-fail/lint-group-style.rs

This file was deleted.

11 changes: 8 additions & 3 deletions src/test/compile-fail/lint-output-format-2.rs
Expand Up @@ -11,15 +11,20 @@
// compile-flags: -F unused_features
// aux-build:lint_output_format.rs

#![feature(foo)] //~ ERROR unused or unknown feature
#![feature(foo)]
//~^ ERROR unused or unknown feature
//~| NOTE requested on the command line with `-F unused-features`

#![feature(test_feature)]

extern crate lint_output_format;
use lint_output_format::{foo, bar};
//~^ WARNING use of deprecated item: text,
//~^ WARNING use of deprecated item: text
//~| NOTE #[warn(deprecated)] on by default

fn main() {
let _x = foo(); //~ WARNING #[warn(deprecated)] on by default
let _x = foo();
//~^ WARNING use of deprecated item: text
//~| NOTE #[warn(deprecated)] on by default
let _y = bar();
}
6 changes: 3 additions & 3 deletions src/test/run-pass/path-lookahead.rs
Expand Up @@ -10,11 +10,11 @@

// Parser test for #37765

fn with_parens<T: ToString>(arg: T) -> String { //~WARN dead_code
return (<T as ToString>::to_string(&arg)); //~WARN unused_parens
fn with_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `with_parens`
return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
}

fn no_parens<T: ToString>(arg: T) -> String { //~WARN dead_code
fn no_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `no_parens`
return <T as ToString>::to_string(&arg);
}

Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/compare-method/proj-outlives-region.stderr
@@ -1,4 +1,4 @@
error[E0276]: impl has stricter requirements than trait, #[deny(extra_requirement_in_impl)] on by default
error[E0276]: impl has stricter requirements than trait
--> $DIR/proj-outlives-region.rs:22:5
|
17 | fn foo() where T: 'a;
Expand All @@ -7,6 +7,7 @@ error[E0276]: impl has stricter requirements than trait, #[deny(extra_requiremen
22 | fn foo() where U: 'a { } //~ ERROR E0276
| ^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: 'a`
|
= note: #[deny(extra_requirement_in_impl)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #37166 <https://github.com/rust-lang/rust/issues/37166>

Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/compare-method/region-unrelated.stderr
@@ -1,4 +1,4 @@
error[E0276]: impl has stricter requirements than trait, #[deny(extra_requirement_in_impl)] on by default
error[E0276]: impl has stricter requirements than trait
--> $DIR/region-unrelated.rs:22:5
|
17 | fn foo() where T: 'a;
Expand All @@ -7,6 +7,7 @@ error[E0276]: impl has stricter requirements than trait, #[deny(extra_requiremen
22 | fn foo() where V: 'a { }
| ^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `V: 'a`
|
= note: #[deny(extra_requirement_in_impl)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #37166 <https://github.com/rust-lang/rust/issues/37166>

Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/lint/command-line-lint-group-allow.rs
@@ -0,0 +1,15 @@
// Copyright 2017 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.

// compile-flags: -A bad-style

fn main() {
let _InappropriateCamelCasing = true;
}
15 changes: 15 additions & 0 deletions src/test/ui/lint/command-line-lint-group-deny.rs
@@ -0,0 +1,15 @@
// Copyright 2017 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.

// compile-flags: -D bad-style

fn main() {
let _InappropriateCamelCasing = true;
}
10 changes: 10 additions & 0 deletions src/test/ui/lint/command-line-lint-group-deny.stderr
@@ -0,0 +1,10 @@
error: variable `_InappropriateCamelCasing` should have a snake case name such as `_inappropriate_camel_casing`
--> $DIR/command-line-lint-group-deny.rs:14:9
|
14 | let _InappropriateCamelCasing = true;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D non-snake-case` implied by `-D bad-style`

error: aborting due to previous error

15 changes: 15 additions & 0 deletions src/test/ui/lint/command-line-lint-group-forbid.rs
@@ -0,0 +1,15 @@
// Copyright 2017 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.

// compile-flags: -F bad-style

fn main() {
let _InappropriateCamelCasing = true;
}
10 changes: 10 additions & 0 deletions src/test/ui/lint/command-line-lint-group-forbid.stderr
@@ -0,0 +1,10 @@
error: variable `_InappropriateCamelCasing` should have a snake case name such as `_inappropriate_camel_casing`
--> $DIR/command-line-lint-group-forbid.rs:14:9
|
14 | let _InappropriateCamelCasing = true;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-F non-snake-case` implied by `-F bad-style`

error: aborting due to previous error

15 changes: 15 additions & 0 deletions src/test/ui/lint/command-line-lint-group-warn.rs
@@ -0,0 +1,15 @@
// Copyright 2017 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.

// compile-flags: -W bad-style

fn main() {
let _InappropriateCamelCasing = true;
}
8 changes: 8 additions & 0 deletions src/test/ui/lint/command-line-lint-group-warn.stderr
@@ -0,0 +1,8 @@
warning: variable `_InappropriateCamelCasing` should have a snake case name such as `_inappropriate_camel_casing`
--> $DIR/command-line-lint-group-warn.rs:14:9
|
14 | let _InappropriateCamelCasing = true;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-W non-snake-case` implied by `-W bad-style`