From e3f3a4b7dc0eb64b92497045db475fa8f0bbe5d0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 25 Mar 2024 12:15:48 +0100 Subject: [PATCH] Don't emit `duplicated_attribute` lint on "complex" `cfg`s --- .../src/attrs/duplicated_attributes.rs | 13 ++- tests/ui/duplicated_attributes.rs | 13 +-- tests/ui/duplicated_attributes.stderr | 94 +++---------------- 3 files changed, 32 insertions(+), 88 deletions(-) diff --git a/clippy_lints/src/attrs/duplicated_attributes.rs b/clippy_lints/src/attrs/duplicated_attributes.rs index 3c5ac597fd5d..d0ccfc4c36d2 100644 --- a/clippy_lints/src/attrs/duplicated_attributes.rs +++ b/clippy_lints/src/attrs/duplicated_attributes.rs @@ -25,12 +25,16 @@ fn emit_if_duplicated( } } +#[allow(clippy::needless_return)] fn check_duplicated_attr( cx: &EarlyContext<'_>, attr: &MetaItem, attr_paths: &mut FxHashMap, parent: &mut Vec, ) { + 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 { @@ -38,7 +42,14 @@ fn check_duplicated_attr( // conditions are the same. return; } - if let Some(value) = attr.value_str() { + if let Some(direct_parent) = parent.last() + && ["cfg", "cfg_attr"].contains(&direct_parent.as_str()) + && [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; + } else if let Some(value) = attr.value_str() { emit_if_duplicated(cx, attr, attr_paths, format!("{}:{name}={value}", parent.join(":"))); } else if let Some(sub_attrs) = attr.meta_item_list() { parent.push(name.as_str().to_string()); diff --git a/tests/ui/duplicated_attributes.rs b/tests/ui/duplicated_attributes.rs index 0f036c684c1c..d051c881f15b 100644 --- a/tests/ui/duplicated_attributes.rs +++ b/tests/ui/duplicated_attributes.rs @@ -2,16 +2,17 @@ #![cfg(any(unix, windows))] #![allow(dead_code)] #![allow(dead_code)] //~ ERROR: duplicated attribute -#![cfg(any(unix, windows))] -//~^ ERROR: duplicated attribute -//~| ERROR: duplicated attribute +#![cfg(any(unix, windows))] // Should not warn! #[cfg(any(unix, windows, target_os = "linux"))] #[allow(dead_code)] #[allow(dead_code)] //~ ERROR: duplicated attribute -#[cfg(any(unix, windows, target_os = "linux"))] -//~^ ERROR: duplicated attribute -//~| ERROR: duplicated attribute +#[cfg(any(unix, windows, target_os = "linux"))] // Should not warn! fn foo() {} +#[cfg(unix)] +#[cfg(windows)] +#[cfg(unix)] //~ ERROR: duplicated attribute +fn bar() {} + fn main() {} diff --git a/tests/ui/duplicated_attributes.stderr b/tests/ui/duplicated_attributes.stderr index 1c6578dbb43a..9e26ba990ac1 100644 --- a/tests/ui/duplicated_attributes.stderr +++ b/tests/ui/duplicated_attributes.stderr @@ -18,106 +18,38 @@ LL | #![allow(dead_code)] = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]` error: duplicated attribute - --> tests/ui/duplicated_attributes.rs:5:12 - | -LL | #![cfg(any(unix, windows))] - | ^^^^ - | -note: first defined here - --> tests/ui/duplicated_attributes.rs:2:12 - | -LL | #![cfg(any(unix, windows))] - | ^^^^ -help: remove this attribute - --> tests/ui/duplicated_attributes.rs:5:12 - | -LL | #![cfg(any(unix, windows))] - | ^^^^ - -error: duplicated attribute - --> tests/ui/duplicated_attributes.rs:5:18 - | -LL | #![cfg(any(unix, windows))] - | ^^^^^^^ - | -note: first defined here - --> tests/ui/duplicated_attributes.rs:2:18 - | -LL | #![cfg(any(unix, windows))] - | ^^^^^^^ -help: remove this attribute - --> tests/ui/duplicated_attributes.rs:5:18 - | -LL | #![cfg(any(unix, windows))] - | ^^^^^^^ - -error: duplicated attribute - --> tests/ui/duplicated_attributes.rs:11:9 + --> tests/ui/duplicated_attributes.rs:9:9 | LL | #[allow(dead_code)] | ^^^^^^^^^ | note: first defined here - --> tests/ui/duplicated_attributes.rs:10:9 + --> tests/ui/duplicated_attributes.rs:8:9 | LL | #[allow(dead_code)] | ^^^^^^^^^ help: remove this attribute - --> tests/ui/duplicated_attributes.rs:11:9 + --> tests/ui/duplicated_attributes.rs:9:9 | LL | #[allow(dead_code)] | ^^^^^^^^^ error: duplicated attribute - --> tests/ui/duplicated_attributes.rs:12:11 - | -LL | #[cfg(any(unix, windows, target_os = "linux"))] - | ^^^^ - | -note: first defined here - --> tests/ui/duplicated_attributes.rs:9:11 - | -LL | #[cfg(any(unix, windows, target_os = "linux"))] - | ^^^^ -help: remove this attribute - --> tests/ui/duplicated_attributes.rs:12:11 - | -LL | #[cfg(any(unix, windows, target_os = "linux"))] - | ^^^^ - -error: duplicated attribute - --> tests/ui/duplicated_attributes.rs:12:17 - | -LL | #[cfg(any(unix, windows, target_os = "linux"))] - | ^^^^^^^ - | -note: first defined here - --> tests/ui/duplicated_attributes.rs:9:17 - | -LL | #[cfg(any(unix, windows, target_os = "linux"))] - | ^^^^^^^ -help: remove this attribute - --> tests/ui/duplicated_attributes.rs:12:17 - | -LL | #[cfg(any(unix, windows, target_os = "linux"))] - | ^^^^^^^ - -error: duplicated attribute - --> tests/ui/duplicated_attributes.rs:12:26 + --> tests/ui/duplicated_attributes.rs:15:7 | -LL | #[cfg(any(unix, windows, target_os = "linux"))] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[cfg(unix)] + | ^^^^ | note: first defined here - --> tests/ui/duplicated_attributes.rs:9:26 + --> tests/ui/duplicated_attributes.rs:13:7 | -LL | #[cfg(any(unix, windows, target_os = "linux"))] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[cfg(unix)] + | ^^^^ help: remove this attribute - --> tests/ui/duplicated_attributes.rs:12:26 + --> tests/ui/duplicated_attributes.rs:15:7 | -LL | #[cfg(any(unix, windows, target_os = "linux"))] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[cfg(unix)] + | ^^^^ -error: aborting due to 7 previous errors +error: aborting due to 3 previous errors