@@ -39,22 +39,31 @@ declare_clippy_lint! {
39
39
}
40
40
41
41
/// **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.
43
47
///
44
48
/// **Why is this bad?** Lint attributes have no effect on crate imports. Most
45
- /// likely a `!` was
46
- /// forgotten
49
+ /// likely a `!` was forgotten.
47
50
///
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.
51
52
///
52
53
/// **Example:**
53
54
/// ```rust
55
+ /// // Bad
54
56
/// #[deny(dead_code)]
55
57
/// extern crate foo;
56
- /// #[allow(unused_import )]
58
+ /// #[forbid(dead_code )]
57
59
/// 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;
58
67
/// ```
59
68
declare_clippy_lint ! {
60
69
pub USELESS_ATTRIBUTE ,
@@ -154,17 +163,26 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
154
163
check_attrs ( cx, item. span , item. name , & item. attrs )
155
164
}
156
165
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
+
158
169
for attr in & item. attrs {
159
170
if let Some ( ref lint_list) = attr. meta_item_list ( ) {
160
171
match & * attr. name ( ) . as_str ( ) {
161
172
"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`
163
175
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
+ _ => { } ,
168
186
}
169
187
}
170
188
let line_span = last_line_of_span ( cx, attr. span ) ;
0 commit comments