1
Fork 0

Auto merge of #84064 - hyd-dev:unknown-lints, r=petrochenkov

Do not ignore path segments in the middle in `#[allow]`/`#[warn]`/`#[deny]`/`#[forbid]` attributes

Fixes #83477.
This commit is contained in:
bors 2021-04-18 02:12:13 +00:00
commit dc99219d3a
4 changed files with 85 additions and 44 deletions

View file

@ -236,10 +236,9 @@ impl<'s> LintLevelsBuilder<'s> {
Some(lvl) => lvl, Some(lvl) => lvl,
}; };
let meta = unwrap_or!(attr.meta(), continue);
self.sess.mark_attr_used(attr); self.sess.mark_attr_used(attr);
let mut metas = unwrap_or!(meta.meta_item_list(), continue); let mut metas = unwrap_or!(attr.meta_item_list(), continue);
if metas.is_empty() { if metas.is_empty() {
// FIXME (#55112): issue unused-attributes lint for `#[level()]` // FIXME (#55112): issue unused-attributes lint for `#[level()]`
@ -255,8 +254,6 @@ impl<'s> LintLevelsBuilder<'s> {
ast::MetaItemKind::Word => {} // actual lint names handled later ast::MetaItemKind::Word => {} // actual lint names handled later
ast::MetaItemKind::NameValue(ref name_value) => { ast::MetaItemKind::NameValue(ref name_value) => {
if item.path == sym::reason { if item.path == sym::reason {
// found reason, reslice meta list to exclude it
metas = &metas[0..metas.len() - 1];
// FIXME (#55112): issue unused-attributes lint if we thereby // FIXME (#55112): issue unused-attributes lint if we thereby
// don't have any lint names (`#[level(reason = "foo")]`) // don't have any lint names (`#[level(reason = "foo")]`)
if let ast::LitKind::Str(rationale, _) = name_value.kind { if let ast::LitKind::Str(rationale, _) = name_value.kind {
@ -275,6 +272,8 @@ impl<'s> LintLevelsBuilder<'s> {
.span_label(name_value.span, "reason must be a string literal") .span_label(name_value.span, "reason must be a string literal")
.emit(); .emit();
} }
// found reason, reslice meta list to exclude it
metas.pop().unwrap();
} else { } else {
bad_attr(item.span) bad_attr(item.span)
.span_label(item.span, "bad attribute argument") .span_label(item.span, "bad attribute argument")
@ -288,10 +287,10 @@ impl<'s> LintLevelsBuilder<'s> {
} }
for li in metas { for li in metas {
let meta_item = match li.meta_item() {
Some(meta_item) if meta_item.is_word() => meta_item,
_ => {
let sp = li.span(); let sp = li.span();
let mut meta_item = match li {
ast::NestedMetaItem::MetaItem(meta_item) if meta_item.is_word() => meta_item,
_ => {
let mut err = bad_attr(sp); let mut err = bad_attr(sp);
let mut add_label = true; let mut add_label = true;
if let Some(item) = li.meta_item() { if let Some(item) = li.meta_item() {
@ -330,15 +329,19 @@ impl<'s> LintLevelsBuilder<'s> {
continue; continue;
} }
Some(tool_ident.name) Some(meta_item.path.segments.remove(0).ident.name)
} else { } else {
None None
}; };
let name = meta_item.path.segments.last().expect("empty lint name").ident.name; let name = pprust::path_to_string(&meta_item.path);
let lint_result = store.check_lint_name(&name.as_str(), tool_name); let lint_result = store.check_lint_name(&name, tool_name);
match &lint_result { match &lint_result {
CheckLintNameResult::Ok(ids) => { CheckLintNameResult::Ok(ids) => {
let src = LintLevelSource::Node(name, li.span(), reason); let src = LintLevelSource::Node(
meta_item.path.segments.last().expect("empty lint name").ident.name,
sp,
reason,
);
for &id in *ids { for &id in *ids {
self.check_gated_lint(id, attr.span); self.check_gated_lint(id, attr.span);
self.insert_spec(&mut specs, id, (level, src)); self.insert_spec(&mut specs, id, (level, src));
@ -351,7 +354,7 @@ impl<'s> LintLevelsBuilder<'s> {
let complete_name = &format!("{}::{}", tool_name.unwrap(), name); let complete_name = &format!("{}::{}", tool_name.unwrap(), name);
let src = LintLevelSource::Node( let src = LintLevelSource::Node(
Symbol::intern(complete_name), Symbol::intern(complete_name),
li.span(), sp,
reason, reason,
); );
for id in ids { for id in ids {
@ -367,7 +370,7 @@ impl<'s> LintLevelsBuilder<'s> {
lint, lint,
lvl, lvl,
src, src,
Some(li.span().into()), Some(sp.into()),
|lint| { |lint| {
let msg = format!( let msg = format!(
"lint name `{}` is deprecated \ "lint name `{}` is deprecated \
@ -376,7 +379,7 @@ impl<'s> LintLevelsBuilder<'s> {
); );
lint.build(&msg) lint.build(&msg)
.span_suggestion( .span_suggestion(
li.span(), sp,
"change it to", "change it to",
new_lint_name.to_string(), new_lint_name.to_string(),
Applicability::MachineApplicable, Applicability::MachineApplicable,
@ -387,7 +390,7 @@ impl<'s> LintLevelsBuilder<'s> {
let src = LintLevelSource::Node( let src = LintLevelSource::Node(
Symbol::intern(&new_lint_name), Symbol::intern(&new_lint_name),
li.span(), sp,
reason, reason,
); );
for id in ids { for id in ids {
@ -414,12 +417,12 @@ impl<'s> LintLevelsBuilder<'s> {
lint, lint,
renamed_lint_level, renamed_lint_level,
src, src,
Some(li.span().into()), Some(sp.into()),
|lint| { |lint| {
let mut err = lint.build(&msg); let mut err = lint.build(&msg);
if let Some(new_name) = &renamed { if let Some(new_name) = &renamed {
err.span_suggestion( err.span_suggestion(
li.span(), sp,
"use the new name", "use the new name",
new_name.to_string(), new_name.to_string(),
Applicability::MachineApplicable, Applicability::MachineApplicable,
@ -433,13 +436,7 @@ impl<'s> LintLevelsBuilder<'s> {
let lint = builtin::UNKNOWN_LINTS; let lint = builtin::UNKNOWN_LINTS;
let (level, src) = let (level, src) =
self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess); self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess);
struct_lint_level( struct_lint_level(self.sess, lint, level, src, Some(sp.into()), |lint| {
self.sess,
lint,
level,
src,
Some(li.span().into()),
|lint| {
let name = if let Some(tool_name) = tool_name { let name = if let Some(tool_name) = tool_name {
format!("{}::{}", tool_name, name) format!("{}::{}", tool_name, name)
} else { } else {
@ -448,15 +445,14 @@ impl<'s> LintLevelsBuilder<'s> {
let mut db = lint.build(&format!("unknown lint: `{}`", name)); let mut db = lint.build(&format!("unknown lint: `{}`", name));
if let Some(suggestion) = suggestion { if let Some(suggestion) = suggestion {
db.span_suggestion( db.span_suggestion(
li.span(), sp,
"did you mean", "did you mean",
suggestion.to_string(), suggestion.to_string(),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} }
db.emit(); db.emit();
}, });
);
} }
} }
// If this lint was renamed, apply the new lint instead of ignoring the attribute. // If this lint was renamed, apply the new lint instead of ignoring the attribute.
@ -466,8 +462,7 @@ impl<'s> LintLevelsBuilder<'s> {
// Ignore any errors or warnings that happen because the new name is inaccurate // Ignore any errors or warnings that happen because the new name is inaccurate
// NOTE: `new_name` already includes the tool name, so we don't have to add it again. // NOTE: `new_name` already includes the tool name, so we don't have to add it again.
if let CheckLintNameResult::Ok(ids) = store.check_lint_name(&new_name, None) { if let CheckLintNameResult::Ok(ids) = store.check_lint_name(&new_name, None) {
let src = let src = LintLevelSource::Node(Symbol::intern(&new_name), sp, reason);
LintLevelSource::Node(Symbol::intern(&new_name), li.span(), reason);
for &id in ids { for &id in ids {
self.check_gated_lint(id, attr.span); self.check_gated_lint(id, attr.span);
self.insert_spec(&mut specs, id, (level, src)); self.insert_spec(&mut specs, id, (level, src));

View file

@ -0,0 +1,16 @@
// check-pass
#![warn(rustc::internal)]
#[allow(rustc::foo::bar::default_hash_types)]
//~^ WARN unknown lint: `rustc::foo::bar::default_hash_types`
//~| HELP did you mean
//~| SUGGESTION rustc::default_hash_types
#[allow(rustc::foo::default_hash_types)]
//~^ WARN unknown lint: `rustc::foo::default_hash_types`
//~| HELP did you mean
//~| SUGGESTION rustc::default_hash_types
fn main() {
let _ = std::collections::HashMap::<String, String>::new();
//~^ WARN Prefer FxHashMap over HashMap, it has better performance
//~| HELP use
}

View file

@ -0,0 +1,30 @@
warning: unknown lint: `rustc::foo::bar::default_hash_types`
--> $DIR/issue-83477.rs:4:9
|
LL | #[allow(rustc::foo::bar::default_hash_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
|
= note: `#[warn(unknown_lints)]` on by default
warning: unknown lint: `rustc::foo::default_hash_types`
--> $DIR/issue-83477.rs:8:9
|
LL | #[allow(rustc::foo::default_hash_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
warning: Prefer FxHashMap over HashMap, it has better performance
--> $DIR/issue-83477.rs:13:31
|
LL | let _ = std::collections::HashMap::<String, String>::new();
| ^^^^^^^ help: use: `FxHashMap`
|
note: the lint level is defined here
--> $DIR/issue-83477.rs:2:9
|
LL | #![warn(rustc::internal)]
| ^^^^^^^^^^^^^^^
= note: `#[warn(rustc::default_hash_types)]` implied by `#[warn(rustc::internal)]`
= note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
warning: 3 warnings emitted

View file

@ -1,5 +1,5 @@
#![warn(clippy::all, clippy::pedantic)] #![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::clippy::let_underscore_drop)] #![allow(clippy::let_underscore_drop)]
#![allow(clippy::missing_docs_in_private_items)] #![allow(clippy::missing_docs_in_private_items)]
fn main() { fn main() {