Merge pull request #2936 from flip1995/useless_lint_attr

Fix useless_attribute lint for extern crate items with macro_use
This commit is contained in:
Philipp Krones 2018-07-19 14:57:28 +02:00 committed by GitHub
commit 0f49e8968d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 13 deletions

View file

@ -39,22 +39,31 @@ declare_clippy_lint! {
} }
/// **What it does:** Checks for `extern crate` and `use` items annotated with /// **What it does:** Checks for `extern crate` and `use` items annotated with
/// lint attributes /// lint attributes.
///
/// This lint whitelists `#[allow(unused_imports)]` and `#[allow(deprecated)]` on
/// `use` items and `#[allow(unused_imports)]` on `extern crate` items with a
/// `#[macro_use]` attribute.
/// ///
/// **Why is this bad?** Lint attributes have no effect on crate imports. Most /// **Why is this bad?** Lint attributes have no effect on crate imports. Most
/// likely a `!` was /// likely a `!` was forgotten.
/// forgotten
/// ///
/// **Known problems:** Technically one might allow `unused_import` on a `use` /// **Known problems:** None.
/// item,
/// but it's easier to remove the unused item.
/// ///
/// **Example:** /// **Example:**
/// ```rust /// ```rust
/// // Bad
/// #[deny(dead_code)] /// #[deny(dead_code)]
/// extern crate foo; /// extern crate foo;
/// #[allow(unused_import)] /// #[forbid(dead_code)]
/// use foo::bar; /// use foo::bar;
///
/// // Ok
/// #[allow(unused_imports)]
/// use foo::baz;
/// #[allow(unused_imports)]
/// #[macro_use]
/// extern crate baz;
/// ``` /// ```
declare_clippy_lint! { declare_clippy_lint! {
pub USELESS_ATTRIBUTE, pub USELESS_ATTRIBUTE,
@ -154,17 +163,26 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
check_attrs(cx, item.span, item.name, &item.attrs) check_attrs(cx, item.span, item.name, &item.attrs)
} }
match item.node { match item.node {
ItemKind::ExternCrate(_) | ItemKind::Use(_, _) => { ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
let skip_unused_imports = item.attrs.iter().any(|attr| attr.name() == "macro_use");
for attr in &item.attrs { for attr in &item.attrs {
if let Some(ref lint_list) = attr.meta_item_list() { if let Some(ref lint_list) = attr.meta_item_list() {
match &*attr.name().as_str() { match &*attr.name().as_str() {
"allow" | "warn" | "deny" | "forbid" => { "allow" | "warn" | "deny" | "forbid" => {
// whitelist `unused_imports` and `deprecated` // whitelist `unused_imports` and `deprecated` for `use` items
// and `unused_imports` for `extern crate` items with `macro_use`
for lint in lint_list { for lint in lint_list {
if is_word(lint, "unused_imports") || is_word(lint, "deprecated") { match item.node {
if let ItemKind::Use(_, _) = item.node { ItemKind::Use(..) => if is_word(lint, "unused_imports")
return; || is_word(lint, "deprecated") {
} return
},
ItemKind::ExternCrate(..) => if is_word(lint, "unused_imports")
&& skip_unused_imports {
return
},
_ => {},
} }
} }
let line_span = last_line_of_span(cx, attr.span); let line_span = last_line_of_span(cx, attr.span);

View file

@ -6,6 +6,8 @@
#[cfg_attr(feature = "cargo-clippy", allow(dead_code, unused_extern_crates))] #[cfg_attr(feature = "cargo-clippy", allow(dead_code, unused_extern_crates))]
#[cfg_attr(feature = "cargo-clippy", #[cfg_attr(feature = "cargo-clippy",
allow(dead_code, unused_extern_crates))] allow(dead_code, unused_extern_crates))]
#[allow(unused_imports)]
#[macro_use]
extern crate clippy_lints; extern crate clippy_lints;
// don't lint on unused_import for `use` items // don't lint on unused_import for `use` items