blob: 1cebc18edc90a5a5aaae2f0f7edf394fa05347a5 [file] [log] [blame] [edit]
use super::USELESS_ATTRIBUTE;
use super::utils::{is_lint_level, is_word, namespace_and_lint};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::{SpanRangeExt, first_line_of_span};
use clippy_utils::sym;
use rustc_ast::{Attribute, Item, ItemKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, LintContext};
pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
for attr in attrs {
if attr.span.in_external_macro(cx.sess().source_map()) {
return;
}
if let Some(lint_list) = &attr.meta_item_list()
&& attr.ident().is_some_and(|ident| is_lint_level(ident.name, attr.id))
{
for lint in lint_list {
match item.kind {
ItemKind::Use(..) => {
let (namespace @ (Some(sym::clippy) | None), Some(name)) = namespace_and_lint(lint) else {
return;
};
if namespace.is_none()
&& matches!(
name,
sym::ambiguous_glob_reexports
| sym::dead_code
| sym::deprecated
| sym::deprecated_in_future
| sym::hidden_glob_reexports
| sym::unreachable_pub
| sym::unused
| sym::unused_braces
| sym::unused_import_braces
| sym::unused_imports
| sym::redundant_imports
)
{
return;
}
if namespace == Some(sym::clippy)
&& matches!(
name,
sym::wildcard_imports
| sym::enum_glob_use
| sym::redundant_pub_crate
| sym::macro_use_imports
| sym::unsafe_removed_from_name
| sym::module_name_repetitions
| sym::single_component_path_imports
| sym::disallowed_types
| sym::unused_trait_names
)
{
return;
}
},
ItemKind::ExternCrate(..) => {
if is_word(lint, sym::unused_imports) && skip_unused_imports {
return;
}
if is_word(lint, sym::unused_extern_crates) {
return;
}
},
_ => {},
}
}
let line_span = first_line_of_span(cx, attr.span);
if let Some(src) = line_span.get_source_text(cx)
&& src.contains("#[")
{
#[expect(clippy::collapsible_span_lint_calls)]
span_lint_and_then(cx, USELESS_ATTRIBUTE, line_span, "useless lint attribute", |diag| {
diag.span_suggestion(
line_span,
"if you just forgot a `!`, use",
src.replacen("#[", "#![", 1),
Applicability::MaybeIncorrect,
);
});
}
}
}
}