about summary refs log tree commit diff
diff options
context:
space:
mode:
authornewt <hi@newty.dev>2025-07-25 00:34:01 +0100
committernewt <hi@newty.dev>2025-07-25 00:34:01 +0100
commitda6618097f9dea0baf5950b588d38fefa0544a07 (patch)
tree3c702cabf2c4cd5736735629ea3a340cd144d6c7
parent60a978d2e9c7b49f21de9d665365427882e781ae (diff)
downloadrust-da6618097f9dea0baf5950b588d38fefa0544a07.tar.gz
rust-da6618097f9dea0baf5950b588d38fefa0544a07.zip
Detect prefixed attributes as duplicated
-rw-r--r--clippy_lints/src/attrs/duplicated_attributes.rs44
-rw-r--r--tests/ui/duplicated_attributes.rs2
-rw-r--r--tests/ui/duplicated_attributes.stderr23
-rw-r--r--tests/ui/indexing_slicing_slice.rs1
-rw-r--r--tests/ui/indexing_slicing_slice.stderr38
-rw-r--r--tests/ui/needless_collect_indirect.rs3
-rw-r--r--tests/ui/needless_collect_indirect.stderr32
-rw-r--r--tests/ui/unnecessary_clippy_cfg.rs3
-rw-r--r--tests/ui/unnecessary_clippy_cfg.stderr46
9 files changed, 89 insertions, 103 deletions
diff --git a/clippy_lints/src/attrs/duplicated_attributes.rs b/clippy_lints/src/attrs/duplicated_attributes.rs
index c2406bcfb64..c956738edf0 100644
--- a/clippy_lints/src/attrs/duplicated_attributes.rs
+++ b/clippy_lints/src/attrs/duplicated_attributes.rs
@@ -2,6 +2,7 @@ use super::DUPLICATED_ATTRIBUTES;
 use clippy_utils::diagnostics::span_lint_and_then;
 use itertools::Itertools;
 use rustc_ast::{Attribute, MetaItem};
+use rustc_ast_pretty::pprust::path_to_string;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_lint::EarlyContext;
 use rustc_span::{Span, Symbol, sym};
@@ -35,31 +36,38 @@ fn check_duplicated_attr(
     if attr.span.from_expansion() {
         return;
     }
-    let Some(ident) = attr.ident() else { return };
-    let name = ident.name;
-    if name == sym::doc || name == sym::cfg_attr_trace || name == sym::rustc_on_unimplemented || name == sym::reason {
-        // FIXME: Would be nice to handle `cfg_attr` as well. Only problem is to check that cfg
-        // conditions are the same.
-        // `#[rustc_on_unimplemented]` contains duplicated subattributes, that's expected.
-        return;
-    }
-    if let Some(direct_parent) = parent.last()
-        && *direct_parent == sym::cfg_trace
-        && [sym::all, sym::not, sym::any].contains(&name)
-    {
-        // FIXME: We don't correctly check `cfg`s for now, so if it's more complex than just a one
-        // level `cfg`, we leave.
-        return;
+    let attr_path = if let Some(ident) = attr.ident() {
+        ident.name
+    } else {
+        Symbol::intern(&path_to_string(&attr.path))
+    };
+    if let Some(ident) = attr.ident() {
+        let name = ident.name;
+        if name == sym::doc || name == sym::cfg_attr_trace || name == sym::rustc_on_unimplemented || name == sym::reason
+        {
+            // FIXME: Would be nice to handle `cfg_attr` as well. Only problem is to check that cfg
+            // conditions are the same.
+            // `#[rustc_on_unimplemented]` contains duplicated subattributes, that's expected.
+            return;
+        }
+        if let Some(direct_parent) = parent.last()
+            && *direct_parent == sym::cfg_trace
+            && [sym::all, sym::not, sym::any].contains(&name)
+        {
+            // FIXME: We don't correctly check `cfg`s for now, so if it's more complex than just a one
+            // level `cfg`, we leave.
+            return;
+        }
     }
     if let Some(value) = attr.value_str() {
         emit_if_duplicated(
             cx,
             attr,
             attr_paths,
-            format!("{}:{name}={value}", parent.iter().join(":")),
+            format!("{}:{attr_path}={value}", parent.iter().join(":")),
         );
     } else if let Some(sub_attrs) = attr.meta_item_list() {
-        parent.push(name);
+        parent.push(attr_path);
         for sub_attr in sub_attrs {
             if let Some(meta) = sub_attr.meta_item() {
                 check_duplicated_attr(cx, meta, attr_paths, parent);
@@ -67,7 +75,7 @@ fn check_duplicated_attr(
         }
         parent.pop();
     } else {
-        emit_if_duplicated(cx, attr, attr_paths, format!("{}:{name}", parent.iter().join(":")));
+        emit_if_duplicated(cx, attr, attr_paths, format!("{}:{attr_path}", parent.iter().join(":")));
     }
 }
 
diff --git a/tests/ui/duplicated_attributes.rs b/tests/ui/duplicated_attributes.rs
index 3ca91d6f182..9a671499505 100644
--- a/tests/ui/duplicated_attributes.rs
+++ b/tests/ui/duplicated_attributes.rs
@@ -1,6 +1,6 @@
 //@aux-build:proc_macro_attr.rs
+#![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)] //~ ERROR: duplicated attribute
 #![feature(rustc_attrs)]
-#![warn(clippy::duplicated_attributes)]
 #![cfg(any(unix, windows))]
 #![allow(dead_code)]
 #![allow(dead_code)] //~ ERROR: duplicated attribute
diff --git a/tests/ui/duplicated_attributes.stderr b/tests/ui/duplicated_attributes.stderr
index 0903617a8d1..922939d60dd 100644
--- a/tests/ui/duplicated_attributes.stderr
+++ b/tests/ui/duplicated_attributes.stderr
@@ -1,4 +1,23 @@
 error: duplicated attribute
+  --> tests/ui/duplicated_attributes.rs:2:40
+   |
+LL | #![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)]
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first defined here
+  --> tests/ui/duplicated_attributes.rs:2:9
+   |
+LL | #![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: remove this attribute
+  --> tests/ui/duplicated_attributes.rs:2:40
+   |
+LL | #![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)]
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::duplicated-attributes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]`
+
+error: duplicated attribute
   --> tests/ui/duplicated_attributes.rs:6:10
    |
 LL | #![allow(dead_code)]
@@ -14,8 +33,6 @@ help: remove this attribute
    |
 LL | #![allow(dead_code)]
    |          ^^^^^^^^^
-   = note: `-D clippy::duplicated-attributes` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]`
 
 error: duplicated attribute
   --> tests/ui/duplicated_attributes.rs:14:9
@@ -34,5 +51,5 @@ help: remove this attribute
 LL | #[allow(dead_code)]
    |         ^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/indexing_slicing_slice.rs b/tests/ui/indexing_slicing_slice.rs
index cad77f56d03..dea31530a0b 100644
--- a/tests/ui/indexing_slicing_slice.rs
+++ b/tests/ui/indexing_slicing_slice.rs
@@ -1,6 +1,5 @@
 //@aux-build: proc_macros.rs
 
-#![warn(clippy::indexing_slicing)]
 // We also check the out_of_bounds_indexing lint here, because it lints similar things and
 // we want to avoid false positives.
 #![warn(clippy::out_of_bounds_indexing)]
diff --git a/tests/ui/indexing_slicing_slice.stderr b/tests/ui/indexing_slicing_slice.stderr
index e3ef89823e3..e3d6086544d 100644
--- a/tests/ui/indexing_slicing_slice.stderr
+++ b/tests/ui/indexing_slicing_slice.stderr
@@ -1,5 +1,5 @@
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:115:6
+  --> tests/ui/indexing_slicing_slice.rs:114:6
    |
 LL |     &x[index..];
    |      ^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     &x[index..];
    = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:117:6
+  --> tests/ui/indexing_slicing_slice.rs:116:6
    |
 LL |     &x[..index];
    |      ^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     &x[..index];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:119:6
+  --> tests/ui/indexing_slicing_slice.rs:118:6
    |
 LL |     &x[index_from..index_to];
    |      ^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     &x[index_from..index_to];
    = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:121:6
+  --> tests/ui/indexing_slicing_slice.rs:120:6
    |
 LL |     &x[index_from..][..index_to];
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     &x[index_from..][..index_to];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:121:6
+  --> tests/ui/indexing_slicing_slice.rs:120:6
    |
 LL |     &x[index_from..][..index_to];
    |      ^^^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     &x[index_from..][..index_to];
    = help: consider using `.get(n..)` or .get_mut(n..)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:124:6
+  --> tests/ui/indexing_slicing_slice.rs:123:6
    |
 LL |     &x[5..][..10];
    |      ^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL |     &x[5..][..10];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: range is out of bounds
-  --> tests/ui/indexing_slicing_slice.rs:124:8
+  --> tests/ui/indexing_slicing_slice.rs:123:8
    |
 LL |     &x[5..][..10];
    |        ^
@@ -58,7 +58,7 @@ LL |     &x[5..][..10];
    = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:127:6
+  --> tests/ui/indexing_slicing_slice.rs:126:6
    |
 LL |     &x[0..][..3];
    |      ^^^^^^^^^^^
@@ -66,7 +66,7 @@ LL |     &x[0..][..3];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:129:6
+  --> tests/ui/indexing_slicing_slice.rs:128:6
    |
 LL |     &x[1..][..5];
    |      ^^^^^^^^^^^
@@ -74,19 +74,19 @@ LL |     &x[1..][..5];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: range is out of bounds
-  --> tests/ui/indexing_slicing_slice.rs:137:12
+  --> tests/ui/indexing_slicing_slice.rs:136:12
    |
 LL |     &y[0..=4];
    |            ^
 
 error: range is out of bounds
-  --> tests/ui/indexing_slicing_slice.rs:139:11
+  --> tests/ui/indexing_slicing_slice.rs:138:11
    |
 LL |     &y[..=4];
    |           ^
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:145:6
+  --> tests/ui/indexing_slicing_slice.rs:144:6
    |
 LL |     &v[10..100];
    |      ^^^^^^^^^^
@@ -94,7 +94,7 @@ LL |     &v[10..100];
    = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:147:6
+  --> tests/ui/indexing_slicing_slice.rs:146:6
    |
 LL |     &x[10..][..100];
    |      ^^^^^^^^^^^^^^
@@ -102,13 +102,13 @@ LL |     &x[10..][..100];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: range is out of bounds
-  --> tests/ui/indexing_slicing_slice.rs:147:8
+  --> tests/ui/indexing_slicing_slice.rs:146:8
    |
 LL |     &x[10..][..100];
    |        ^^
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:150:6
+  --> tests/ui/indexing_slicing_slice.rs:149:6
    |
 LL |     &v[10..];
    |      ^^^^^^^
@@ -116,7 +116,7 @@ LL |     &v[10..];
    = help: consider using `.get(n..)` or .get_mut(n..)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:152:6
+  --> tests/ui/indexing_slicing_slice.rs:151:6
    |
 LL |     &v[..100];
    |      ^^^^^^^^
@@ -124,7 +124,7 @@ LL |     &v[..100];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_slice.rs:170:5
+  --> tests/ui/indexing_slicing_slice.rs:169:5
    |
 LL |     map_with_get[true];
    |     ^^^^^^^^^^^^^^^^^^
@@ -132,7 +132,7 @@ LL |     map_with_get[true];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_slice.rs:174:5
+  --> tests/ui/indexing_slicing_slice.rs:173:5
    |
 LL |     s[0];
    |     ^^^^
@@ -140,7 +140,7 @@ LL |     s[0];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_slice.rs:178:5
+  --> tests/ui/indexing_slicing_slice.rs:177:5
    |
 LL |     y[0];
    |     ^^^^
diff --git a/tests/ui/needless_collect_indirect.rs b/tests/ui/needless_collect_indirect.rs
index 57d0f2b9948..fff6d2f34b8 100644
--- a/tests/ui/needless_collect_indirect.rs
+++ b/tests/ui/needless_collect_indirect.rs
@@ -1,5 +1,4 @@
-#![allow(clippy::uninlined_format_args, clippy::useless_vec)]
-#![allow(clippy::needless_if, clippy::uninlined_format_args)]
+#![allow(clippy::uninlined_format_args, clippy::useless_vec, clippy::needless_if)]
 #![warn(clippy::needless_collect)]
 //@no-rustfix
 use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
diff --git a/tests/ui/needless_collect_indirect.stderr b/tests/ui/needless_collect_indirect.stderr
index c7bf1b14df8..24523c9f97b 100644
--- a/tests/ui/needless_collect_indirect.stderr
+++ b/tests/ui/needless_collect_indirect.stderr
@@ -1,5 +1,5 @@
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:9:39
+  --> tests/ui/needless_collect_indirect.rs:8:39
    |
 LL |     let indirect_iter = sample.iter().collect::<Vec<_>>();
    |                                       ^^^^^^^
@@ -18,7 +18,7 @@ LL ~     sample.iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:13:38
+  --> tests/ui/needless_collect_indirect.rs:12:38
    |
 LL |     let indirect_len = sample.iter().collect::<VecDeque<_>>();
    |                                      ^^^^^^^
@@ -35,7 +35,7 @@ LL ~     sample.iter().count();
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:17:40
+  --> tests/ui/needless_collect_indirect.rs:16:40
    |
 LL |     let indirect_empty = sample.iter().collect::<VecDeque<_>>();
    |                                        ^^^^^^^
@@ -52,7 +52,7 @@ LL ~     sample.iter().next().is_none();
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:21:43
+  --> tests/ui/needless_collect_indirect.rs:20:43
    |
 LL |     let indirect_contains = sample.iter().collect::<VecDeque<_>>();
    |                                           ^^^^^^^
@@ -69,7 +69,7 @@ LL ~     sample.iter().any(|x| x == &5);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:35:48
+  --> tests/ui/needless_collect_indirect.rs:34:48
    |
 LL |     let non_copy_contains = sample.into_iter().collect::<Vec<_>>();
    |                                                ^^^^^^^
@@ -86,7 +86,7 @@ LL ~     sample.into_iter().any(|x| x == a);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:66:51
+  --> tests/ui/needless_collect_indirect.rs:65:51
    |
 LL |         let buffer: Vec<&str> = string.split('/').collect();
    |                                                   ^^^^^^^
@@ -103,7 +103,7 @@ LL ~         string.split('/').count()
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:73:55
+  --> tests/ui/needless_collect_indirect.rs:72:55
    |
 LL |         let indirect_len: VecDeque<_> = sample.iter().collect();
    |                                                       ^^^^^^^
@@ -120,7 +120,7 @@ LL ~         sample.iter().count()
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:80:57
+  --> tests/ui/needless_collect_indirect.rs:79:57
    |
 LL |         let indirect_len: LinkedList<_> = sample.iter().collect();
    |                                                         ^^^^^^^
@@ -137,7 +137,7 @@ LL ~         sample.iter().count()
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:87:57
+  --> tests/ui/needless_collect_indirect.rs:86:57
    |
 LL |         let indirect_len: BinaryHeap<_> = sample.iter().collect();
    |                                                         ^^^^^^^
@@ -154,7 +154,7 @@ LL ~         sample.iter().count()
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:149:59
+  --> tests/ui/needless_collect_indirect.rs:148:59
    |
 LL |             let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
    |                                                           ^^^^^^^
@@ -172,7 +172,7 @@ LL ~             vec.iter().map(|k| k * k).any(|x| x == i);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:176:59
+  --> tests/ui/needless_collect_indirect.rs:175:59
    |
 LL |             let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
    |                                                           ^^^^^^^
@@ -190,7 +190,7 @@ LL ~             vec.iter().map(|k| k * k).any(|x| x == n);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:207:63
+  --> tests/ui/needless_collect_indirect.rs:206:63
    |
 LL |                 let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
    |                                                               ^^^^^^^
@@ -208,7 +208,7 @@ LL ~                 vec.iter().map(|k| k * k).any(|x| x == n);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:245:59
+  --> tests/ui/needless_collect_indirect.rs:244:59
    |
 LL |             let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
    |                                                           ^^^^^^^
@@ -226,7 +226,7 @@ LL ~                 vec.iter().map(|k| k * k).any(|x| x == n);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:272:26
+  --> tests/ui/needless_collect_indirect.rs:271:26
    |
 LL |         let w = v.iter().collect::<Vec<_>>();
    |                          ^^^^^^^
@@ -244,7 +244,7 @@ LL ~         for _ in 0..v.iter().count() {
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:296:30
+  --> tests/ui/needless_collect_indirect.rs:295:30
    |
 LL |         let mut w = v.iter().collect::<Vec<_>>();
    |                              ^^^^^^^
@@ -262,7 +262,7 @@ LL ~         while 1 == v.iter().count() {
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:320:30
+  --> tests/ui/needless_collect_indirect.rs:319:30
    |
 LL |         let mut w = v.iter().collect::<Vec<_>>();
    |                              ^^^^^^^
diff --git a/tests/ui/unnecessary_clippy_cfg.rs b/tests/ui/unnecessary_clippy_cfg.rs
index e7e01248dfb..65f67df7913 100644
--- a/tests/ui/unnecessary_clippy_cfg.rs
+++ b/tests/ui/unnecessary_clippy_cfg.rs
@@ -1,5 +1,6 @@
 //@no-rustfix
 
+#![allow(clippy::duplicated_attributes)]
 #![warn(clippy::unnecessary_clippy_cfg)]
 #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
@@ -7,7 +8,6 @@
 //~^ unnecessary_clippy_cfg
 #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
-//~| duplicated_attributes
 #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
 
@@ -17,7 +17,6 @@
 //~^ unnecessary_clippy_cfg
 #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
-//~| duplicated_attributes
 #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
 
diff --git a/tests/ui/unnecessary_clippy_cfg.stderr b/tests/ui/unnecessary_clippy_cfg.stderr
index f66c6894954..4f638d5c513 100644
--- a/tests/ui/unnecessary_clippy_cfg.stderr
+++ b/tests/ui/unnecessary_clippy_cfg.stderr
@@ -1,5 +1,5 @@
 error: no need to put clippy lints behind a `clippy` cfg
-  --> tests/ui/unnecessary_clippy_cfg.rs:4:1
+  --> tests/ui/unnecessary_clippy_cfg.rs:5:1
    |
 LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]`
@@ -8,7 +8,7 @@ LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_clippy_cfg)]`
 
 error: no need to put clippy lints behind a `clippy` cfg
-  --> tests/ui/unnecessary_clippy_cfg.rs:6:37
+  --> tests/ui/unnecessary_clippy_cfg.rs:7:37
    |
 LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
    = note: write instead: `#![deny(clippy::non_minimal_cfg)]`
 
 error: no need to put clippy lints behind a `clippy` cfg
-  --> tests/ui/unnecessary_clippy_cfg.rs:8:37
+  --> tests/ui/unnecessary_clippy_cfg.rs:9:37
    |
 LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,46 +52,10 @@ LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
    = note: write instead: `#[deny(clippy::non_minimal_cfg)]`
 
 error: no need to put clippy lints behind a `clippy` cfg
-  --> tests/ui/unnecessary_clippy_cfg.rs:21:1
+  --> tests/ui/unnecessary_clippy_cfg.rs:20:1
    |
 LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]`
 
-error: duplicated attribute
-  --> tests/ui/unnecessary_clippy_cfg.rs:8:26
-   |
-LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                          ^^^^^^^^^
-   |
-note: first defined here
-  --> tests/ui/unnecessary_clippy_cfg.rs:6:26
-   |
-LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                          ^^^^^^^^^
-help: remove this attribute
-  --> tests/ui/unnecessary_clippy_cfg.rs:8:26
-   |
-LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                          ^^^^^^^^^
-   = note: `-D clippy::duplicated-attributes` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]`
-
-error: duplicated attribute
-  --> tests/ui/unnecessary_clippy_cfg.rs:18:25
-   |
-LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                         ^^^^^^^^^
-   |
-note: first defined here
-  --> tests/ui/unnecessary_clippy_cfg.rs:16:25
-   |
-LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                         ^^^^^^^^^
-help: remove this attribute
-  --> tests/ui/unnecessary_clippy_cfg.rs:18:25
-   |
-LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                         ^^^^^^^^^
-
-error: aborting due to 10 previous errors
+error: aborting due to 8 previous errors