Skip to content

Commit 0f49e89

Browse files
authored
Merge pull request #2936 from flip1995/useless_lint_attr
Fix useless_attribute lint for extern crate items with macro_use
2 parents 7877730 + ac77a26 commit 0f49e89

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

clippy_lints/src/attrs.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,31 @@ declare_clippy_lint! {
3939
}
4040

4141
/// **What it does:** Checks for `extern crate` and `use` items annotated with
42-
/// lint attributes
42+
/// lint attributes.
43+
///
44+
/// This lint whitelists `#[allow(unused_imports)]` and `#[allow(deprecated)]` on
45+
/// `use` items and `#[allow(unused_imports)]` on `extern crate` items with a
46+
/// `#[macro_use]` attribute.
4347
///
4448
/// **Why is this bad?** Lint attributes have no effect on crate imports. Most
45-
/// likely a `!` was
46-
/// forgotten
49+
/// likely a `!` was forgotten.
4750
///
48-
/// **Known problems:** Technically one might allow `unused_import` on a `use`
49-
/// item,
50-
/// but it's easier to remove the unused item.
51+
/// **Known problems:** None.
5152
///
5253
/// **Example:**
5354
/// ```rust
55+
/// // Bad
5456
/// #[deny(dead_code)]
5557
/// extern crate foo;
56-
/// #[allow(unused_import)]
58+
/// #[forbid(dead_code)]
5759
/// use foo::bar;
60+
///
61+
/// // Ok
62+
/// #[allow(unused_imports)]
63+
/// use foo::baz;
64+
/// #[allow(unused_imports)]
65+
/// #[macro_use]
66+
/// extern crate baz;
5867
/// ```
5968
declare_clippy_lint! {
6069
pub USELESS_ATTRIBUTE,
@@ -154,17 +163,26 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
154163
check_attrs(cx, item.span, item.name, &item.attrs)
155164
}
156165
match item.node {
157-
ItemKind::ExternCrate(_) | ItemKind::Use(_, _) => {
166+
ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
167+
let skip_unused_imports = item.attrs.iter().any(|attr| attr.name() == "macro_use");
168+
158169
for attr in &item.attrs {
159170
if let Some(ref lint_list) = attr.meta_item_list() {
160171
match &*attr.name().as_str() {
161172
"allow" | "warn" | "deny" | "forbid" => {
162-
// whitelist `unused_imports` and `deprecated`
173+
// whitelist `unused_imports` and `deprecated` for `use` items
174+
// and `unused_imports` for `extern crate` items with `macro_use`
163175
for lint in lint_list {
164-
if is_word(lint, "unused_imports") || is_word(lint, "deprecated") {
165-
if let ItemKind::Use(_, _) = item.node {
166-
return;
167-
}
176+
match item.node {
177+
ItemKind::Use(..) => if is_word(lint, "unused_imports")
178+
|| is_word(lint, "deprecated") {
179+
return
180+
},
181+
ItemKind::ExternCrate(..) => if is_word(lint, "unused_imports")
182+
&& skip_unused_imports {
183+
return
184+
},
185+
_ => {},
168186
}
169187
}
170188
let line_span = last_line_of_span(cx, attr.span);

tests/ui/useless_attribute.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#[cfg_attr(feature = "cargo-clippy", allow(dead_code, unused_extern_crates))]
77
#[cfg_attr(feature = "cargo-clippy",
88
allow(dead_code, unused_extern_crates))]
9+
#[allow(unused_imports)]
10+
#[macro_use]
911
extern crate clippy_lints;
1012

1113
// don't lint on unused_import for `use` items

0 commit comments

Comments
 (0)