Skip to content

Commit e3f3a4b

Browse files
Don't emit duplicated_attribute lint on "complex" cfgs
1 parent 95c62ff commit e3f3a4b

File tree

3 files changed

+32
-88
lines changed

3 files changed

+32
-88
lines changed

clippy_lints/src/attrs/duplicated_attributes.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,31 @@ fn emit_if_duplicated(
2525
}
2626
}
2727

28+
#[allow(clippy::needless_return)]
2829
fn check_duplicated_attr(
2930
cx: &EarlyContext<'_>,
3031
attr: &MetaItem,
3132
attr_paths: &mut FxHashMap<String, Span>,
3233
parent: &mut Vec<String>,
3334
) {
35+
if attr.span.from_expansion() {
36+
return;
37+
}
3438
let Some(ident) = attr.ident() else { return };
3539
let name = ident.name;
3640
if name == sym::doc || name == sym::cfg_attr {
3741
// FIXME: Would be nice to handle `cfg_attr` as well. Only problem is to check that cfg
3842
// conditions are the same.
3943
return;
4044
}
41-
if let Some(value) = attr.value_str() {
45+
if let Some(direct_parent) = parent.last()
46+
&& ["cfg", "cfg_attr"].contains(&direct_parent.as_str())
47+
&& [sym::all, sym::not, sym::any].contains(&name)
48+
{
49+
// FIXME: We don't correctly check `cfg`s for now, so if it's more complex than just a one
50+
// level `cfg`, we leave.
51+
return;
52+
} else if let Some(value) = attr.value_str() {
4253
emit_if_duplicated(cx, attr, attr_paths, format!("{}:{name}={value}", parent.join(":")));
4354
} else if let Some(sub_attrs) = attr.meta_item_list() {
4455
parent.push(name.as_str().to_string());

tests/ui/duplicated_attributes.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22
#![cfg(any(unix, windows))]
33
#![allow(dead_code)]
44
#![allow(dead_code)] //~ ERROR: duplicated attribute
5-
#![cfg(any(unix, windows))]
6-
//~^ ERROR: duplicated attribute
7-
//~| ERROR: duplicated attribute
5+
#![cfg(any(unix, windows))] // Should not warn!
86

97
#[cfg(any(unix, windows, target_os = "linux"))]
108
#[allow(dead_code)]
119
#[allow(dead_code)] //~ ERROR: duplicated attribute
12-
#[cfg(any(unix, windows, target_os = "linux"))]
13-
//~^ ERROR: duplicated attribute
14-
//~| ERROR: duplicated attribute
10+
#[cfg(any(unix, windows, target_os = "linux"))] // Should not warn!
1511
fn foo() {}
1612

13+
#[cfg(unix)]
14+
#[cfg(windows)]
15+
#[cfg(unix)] //~ ERROR: duplicated attribute
16+
fn bar() {}
17+
1718
fn main() {}

tests/ui/duplicated_attributes.stderr

Lines changed: 13 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -18,106 +18,38 @@ LL | #![allow(dead_code)]
1818
= help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]`
1919

2020
error: duplicated attribute
21-
--> tests/ui/duplicated_attributes.rs:5:12
22-
|
23-
LL | #![cfg(any(unix, windows))]
24-
| ^^^^
25-
|
26-
note: first defined here
27-
--> tests/ui/duplicated_attributes.rs:2:12
28-
|
29-
LL | #![cfg(any(unix, windows))]
30-
| ^^^^
31-
help: remove this attribute
32-
--> tests/ui/duplicated_attributes.rs:5:12
33-
|
34-
LL | #![cfg(any(unix, windows))]
35-
| ^^^^
36-
37-
error: duplicated attribute
38-
--> tests/ui/duplicated_attributes.rs:5:18
39-
|
40-
LL | #![cfg(any(unix, windows))]
41-
| ^^^^^^^
42-
|
43-
note: first defined here
44-
--> tests/ui/duplicated_attributes.rs:2:18
45-
|
46-
LL | #![cfg(any(unix, windows))]
47-
| ^^^^^^^
48-
help: remove this attribute
49-
--> tests/ui/duplicated_attributes.rs:5:18
50-
|
51-
LL | #![cfg(any(unix, windows))]
52-
| ^^^^^^^
53-
54-
error: duplicated attribute
55-
--> tests/ui/duplicated_attributes.rs:11:9
21+
--> tests/ui/duplicated_attributes.rs:9:9
5622
|
5723
LL | #[allow(dead_code)]
5824
| ^^^^^^^^^
5925
|
6026
note: first defined here
61-
--> tests/ui/duplicated_attributes.rs:10:9
27+
--> tests/ui/duplicated_attributes.rs:8:9
6228
|
6329
LL | #[allow(dead_code)]
6430
| ^^^^^^^^^
6531
help: remove this attribute
66-
--> tests/ui/duplicated_attributes.rs:11:9
32+
--> tests/ui/duplicated_attributes.rs:9:9
6733
|
6834
LL | #[allow(dead_code)]
6935
| ^^^^^^^^^
7036

7137
error: duplicated attribute
72-
--> tests/ui/duplicated_attributes.rs:12:11
73-
|
74-
LL | #[cfg(any(unix, windows, target_os = "linux"))]
75-
| ^^^^
76-
|
77-
note: first defined here
78-
--> tests/ui/duplicated_attributes.rs:9:11
79-
|
80-
LL | #[cfg(any(unix, windows, target_os = "linux"))]
81-
| ^^^^
82-
help: remove this attribute
83-
--> tests/ui/duplicated_attributes.rs:12:11
84-
|
85-
LL | #[cfg(any(unix, windows, target_os = "linux"))]
86-
| ^^^^
87-
88-
error: duplicated attribute
89-
--> tests/ui/duplicated_attributes.rs:12:17
90-
|
91-
LL | #[cfg(any(unix, windows, target_os = "linux"))]
92-
| ^^^^^^^
93-
|
94-
note: first defined here
95-
--> tests/ui/duplicated_attributes.rs:9:17
96-
|
97-
LL | #[cfg(any(unix, windows, target_os = "linux"))]
98-
| ^^^^^^^
99-
help: remove this attribute
100-
--> tests/ui/duplicated_attributes.rs:12:17
101-
|
102-
LL | #[cfg(any(unix, windows, target_os = "linux"))]
103-
| ^^^^^^^
104-
105-
error: duplicated attribute
106-
--> tests/ui/duplicated_attributes.rs:12:26
38+
--> tests/ui/duplicated_attributes.rs:15:7
10739
|
108-
LL | #[cfg(any(unix, windows, target_os = "linux"))]
109-
| ^^^^^^^^^^^^^^^^^^^
40+
LL | #[cfg(unix)]
41+
| ^^^^
11042
|
11143
note: first defined here
112-
--> tests/ui/duplicated_attributes.rs:9:26
44+
--> tests/ui/duplicated_attributes.rs:13:7
11345
|
114-
LL | #[cfg(any(unix, windows, target_os = "linux"))]
115-
| ^^^^^^^^^^^^^^^^^^^
46+
LL | #[cfg(unix)]
47+
| ^^^^
11648
help: remove this attribute
117-
--> tests/ui/duplicated_attributes.rs:12:26
49+
--> tests/ui/duplicated_attributes.rs:15:7
11850
|
119-
LL | #[cfg(any(unix, windows, target_os = "linux"))]
120-
| ^^^^^^^^^^^^^^^^^^^
51+
LL | #[cfg(unix)]
52+
| ^^^^
12153

122-
error: aborting due to 7 previous errors
54+
error: aborting due to 3 previous errors
12355

0 commit comments

Comments
 (0)