blob: 5bf077990e1fe1696f5663ed6b3e340488f41720 [file] [log] [blame] [edit]
use super::{ALLOW_ATTRIBUTES_WITHOUT_REASON, Attribute};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use rustc_ast::{MetaItemInner, MetaItemKind};
use rustc_lint::{EarlyContext, LintContext};
use rustc_span::sym;
use rustc_span::symbol::Symbol;
pub(super) fn check<'cx>(cx: &EarlyContext<'cx>, name: Symbol, items: &[MetaItemInner], attr: &'cx Attribute) {
// Check if the reason is present
if let Some(item) = items.last().and_then(MetaItemInner::meta_item)
&& let MetaItemKind::NameValue(_) = &item.kind
&& item.path == sym::reason
{
return;
}
// Check if the attribute is in an external macro and therefore out of the developer's control
if attr.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, attr) {
return;
}
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
span_lint_and_then(
cx,
ALLOW_ATTRIBUTES_WITHOUT_REASON,
attr.span,
format!("`{name}` attribute without specifying a reason"),
|diag| {
diag.help("try adding a reason at the end with `, reason = \"..\"`");
},
);
}