diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index 8f47bc7653b7..39f406077995 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -61,11 +61,21 @@ declare_clippy_lint! { /// /// This lint permits lint attributes for lints emitted on the items themself. /// For `use` items these lints are: + /// * ambiguous_glob_reexports + /// * dead_code /// * deprecated + /// * hidden_glob_reexports /// * unreachable_pub - /// * unused_imports + /// * unused + /// * unused_braces + /// * unused_import_braces + /// * clippy::disallowed_types /// * clippy::enum_glob_use /// * clippy::macro_use_imports + /// * clippy::module_name_repetitions + /// * clippy::redundant_pub_crate + /// * clippy::single_component_path_imports + /// * clippy::unsafe_removed_from_name /// * clippy::wildcard_imports /// /// For `extern crate` items these lints are: diff --git a/clippy_lints/src/attrs/useless_attribute.rs b/clippy_lints/src/attrs/useless_attribute.rs index 7575f502a7c2..f0868231d01a 100644 --- a/clippy_lints/src/attrs/useless_attribute.rs +++ b/clippy_lints/src/attrs/useless_attribute.rs @@ -2,6 +2,7 @@ use super::utils::{extract_clippy_lint, is_lint_level, is_word}; use super::{Attribute, USELESS_ATTRIBUTE}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{first_line_of_span, snippet_opt}; +use rustc_ast::NestedMetaItem; use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LintContext}; @@ -20,26 +21,40 @@ pub(super) fn check(cx: &LateContext<'_>, item: &Item<'_>, attrs: &[Attribute]) for lint in lint_list { match item.kind { ItemKind::Use(..) => { - if is_word(lint, sym::unused_imports) - || is_word(lint, sym::deprecated) - || is_word(lint, sym!(unreachable_pub)) - || is_word(lint, sym!(unused)) - || is_word(lint, sym!(unused_import_braces)) - || extract_clippy_lint(lint).map_or(false, |s| { - matches!( - s.as_str(), - "wildcard_imports" - | "enum_glob_use" - | "redundant_pub_crate" - | "macro_use_imports" - | "unsafe_removed_from_name" - | "module_name_repetitions" - | "single_component_path_imports" - ) - }) + if let NestedMetaItem::MetaItem(meta_item) = lint + && meta_item.is_word() + && let Some(ident) = meta_item.ident() + && matches!( + ident.name.as_str(), + "ambiguous_glob_reexports" + | "dead_code" + | "deprecated" + | "hidden_glob_reexports" + | "unreachable_pub" + | "unused" + | "unused_braces" + | "unused_import_braces" + | "unused_imports" + ) { return; } + + if extract_clippy_lint(lint).is_some_and(|symbol| { + matches!( + symbol.as_str(), + "wildcard_imports" + | "enum_glob_use" + | "redundant_pub_crate" + | "macro_use_imports" + | "unsafe_removed_from_name" + | "module_name_repetitions" + | "single_component_path_imports" + | "disallowed_types" + ) + }) { + return; + } }, ItemKind::ExternCrate(..) => { if is_word(lint, sym::unused_imports) && skip_unused_imports { diff --git a/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs b/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs index 7f28efd676f2..f02bd07cfe7b 100644 --- a/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs +++ b/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs @@ -40,3 +40,9 @@ fn main() { let _ = HashMap; let _: usize = 64_usize; } + +mod useless_attribute { + // Regression test for https://github.com/rust-lang/rust-clippy/issues/12753 + #[allow(clippy::disallowed_types)] + use std::collections::HashMap; +} diff --git a/tests/ui/useless_attribute.fixed b/tests/ui/useless_attribute.fixed index 81759086f79e..231fc0a892ad 100644 --- a/tests/ui/useless_attribute.fixed +++ b/tests/ui/useless_attribute.fixed @@ -86,8 +86,51 @@ mod module { #[rustfmt::skip] #[allow(unused_import_braces)] +#[allow(unused_braces)] use module::{Struct}; fn main() { test_indented_attr(); } + +// Regression test for https://github.com/rust-lang/rust-clippy/issues/4467 +#[allow(dead_code)] +use std::collections as puppy_doggy; + +// Regression test for https://github.com/rust-lang/rust-clippy/issues/11595 +pub mod hidden_glob_reexports { + #![allow(unreachable_pub)] + + mod my_prelude { + pub struct MyCoolTypeInternal; + pub use MyCoolTypeInternal as MyCoolType; + } + + mod my_uncool_type { + pub(crate) struct MyUncoolType; + } + + // This exports `MyCoolType`. + pub use my_prelude::*; + + // This hides `my_prelude::MyCoolType`. + #[allow(hidden_glob_reexports)] + use my_uncool_type::MyUncoolType as MyCoolType; +} + +// Regression test for https://github.com/rust-lang/rust-clippy/issues/10878 +pub mod ambiguous_glob_exports { + #![allow(unreachable_pub)] + + mod my_prelude { + pub struct MyType; + } + + mod my_type { + pub struct MyType; + } + + #[allow(ambiguous_glob_reexports)] + pub use my_prelude::*; + pub use my_type::*; +} diff --git a/tests/ui/useless_attribute.rs b/tests/ui/useless_attribute.rs index 59a9dcf093bc..8dfcd2110a4b 100644 --- a/tests/ui/useless_attribute.rs +++ b/tests/ui/useless_attribute.rs @@ -86,8 +86,51 @@ mod module { #[rustfmt::skip] #[allow(unused_import_braces)] +#[allow(unused_braces)] use module::{Struct}; fn main() { test_indented_attr(); } + +// Regression test for https://github.com/rust-lang/rust-clippy/issues/4467 +#[allow(dead_code)] +use std::collections as puppy_doggy; + +// Regression test for https://github.com/rust-lang/rust-clippy/issues/11595 +pub mod hidden_glob_reexports { + #![allow(unreachable_pub)] + + mod my_prelude { + pub struct MyCoolTypeInternal; + pub use MyCoolTypeInternal as MyCoolType; + } + + mod my_uncool_type { + pub(crate) struct MyUncoolType; + } + + // This exports `MyCoolType`. + pub use my_prelude::*; + + // This hides `my_prelude::MyCoolType`. + #[allow(hidden_glob_reexports)] + use my_uncool_type::MyUncoolType as MyCoolType; +} + +// Regression test for https://github.com/rust-lang/rust-clippy/issues/10878 +pub mod ambiguous_glob_exports { + #![allow(unreachable_pub)] + + mod my_prelude { + pub struct MyType; + } + + mod my_type { + pub struct MyType; + } + + #[allow(ambiguous_glob_reexports)] + pub use my_prelude::*; + pub use my_type::*; +}