add lint for using AttributeKind in find_attr

This commit is contained in:
Jana Dönszelmann
2026-02-13 15:22:48 +01:00
parent a2367eca47
commit 2bed584742
6 changed files with 184 additions and 4 deletions
+3
View File
@@ -77,6 +77,9 @@ macro_rules! find_attr {
rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => {
break 'done Some($e);
}
// FIXME: doesn't actually trigger in other crates :/
// https://github.com/rust-lang/rust/issues/110613
#[deny(unreachable_patterns)]
_ => {}
}
}
+96 -4
View File
@@ -1,6 +1,7 @@
//! Some lints that are only useful in the compiler or crates that use compiler internals, such as
//! Clippy.
use rustc_ast::{Pat, PatKind, Path};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
@@ -12,10 +13,10 @@
use {rustc_ast as ast, rustc_hir as hir};
use crate::lints::{
BadOptAccessDiag, DefaultHashTypesDiag, ImplicitSysrootCrateImportDiag, LintPassByHand,
NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag,
SymbolInternStringLiteralDiag, TyQualified, TykindDiag, TykindKind, TypeIrDirectUse,
TypeIrInherentUsage, TypeIrTraitUsage,
AttributeKindInFindAttr, BadOptAccessDiag, DefaultHashTypesDiag,
ImplicitSysrootCrateImportDiag, LintPassByHand, NonGlobImportTypeIrInherent, QueryInstability,
QueryUntracked, SpanUseEqCtxtDiag, SymbolInternStringLiteralDiag, TyQualified, TykindDiag,
TykindKind, TypeIrDirectUse, TypeIrInherentUsage, TypeIrTraitUsage,
};
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
@@ -621,3 +622,94 @@ fn is_whitelisted(crate_name: &str) -> bool {
}
}
}
declare_tool_lint! {
pub rustc::BAD_USE_OF_FIND_ATTR,
Allow,
"Forbid `AttributeKind::` as a prefix in `find_attr!` macros.",
report_in_external_macro: true
}
declare_lint_pass!(BadUseOfFindAttr => [BAD_USE_OF_FIND_ATTR]);
impl EarlyLintPass for BadUseOfFindAttr {
fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &rustc_ast::Arm) {
fn path_contains_attribute_kind(cx: &EarlyContext<'_>, path: &Path) {
for segment in &path.segments {
if segment.ident.as_str() == "AttributeKind" {
cx.emit_span_lint(
BAD_USE_OF_FIND_ATTR,
segment.span(),
AttributeKindInFindAttr {},
);
}
}
}
fn find_attr_kind_in_pat(cx: &EarlyContext<'_>, pat: &Pat) {
match &pat.kind {
PatKind::Struct(_, path, fields, _) => {
path_contains_attribute_kind(cx, path);
for field in fields {
find_attr_kind_in_pat(cx, &field.pat);
}
}
PatKind::TupleStruct(_, path, fields) => {
path_contains_attribute_kind(cx, path);
for field in fields {
find_attr_kind_in_pat(cx, &field);
}
}
PatKind::Or(options) => {
for pat in options {
find_attr_kind_in_pat(cx, pat);
}
}
PatKind::Path(_, path) => {
path_contains_attribute_kind(cx, path);
}
PatKind::Tuple(elems) => {
for pat in elems {
find_attr_kind_in_pat(cx, pat);
}
}
PatKind::Box(pat) => {
find_attr_kind_in_pat(cx, pat);
}
PatKind::Deref(pat) => {
find_attr_kind_in_pat(cx, pat);
}
PatKind::Ref(..) => {
find_attr_kind_in_pat(cx, pat);
}
PatKind::Slice(elems) => {
for pat in elems {
find_attr_kind_in_pat(cx, pat);
}
}
PatKind::Guard(pat, ..) => {
find_attr_kind_in_pat(cx, pat);
}
PatKind::Paren(pat) => {
find_attr_kind_in_pat(cx, pat);
}
PatKind::Expr(..)
| PatKind::Range(..)
| PatKind::MacCall(..)
| PatKind::Rest
| PatKind::Missing
| PatKind::Err(..)
| PatKind::Ident(..)
| PatKind::Never
| PatKind::Wild => {}
}
}
if let Some(expn_data) = arm.span.source_callee()
&& let ExpnKind::Macro(_, name) = expn_data.kind
&& name.as_str() == "find_attr"
{
find_attr_kind_in_pat(cx, &arm.pat);
}
}
}
+3
View File
@@ -665,6 +665,8 @@ fn register_internals(store: &mut LintStore) {
store.register_late_mod_pass(|_| Box::new(SymbolInternStringLiteral));
store.register_lints(&ImplicitSysrootCrateImport::lint_vec());
store.register_early_pass(|| Box::new(ImplicitSysrootCrateImport));
store.register_lints(&BadUseOfFindAttr::lint_vec());
store.register_early_pass(|| Box::new(BadUseOfFindAttr));
store.register_group(
false,
"rustc::internal",
@@ -684,6 +686,7 @@ fn register_internals(store: &mut LintStore) {
LintId::of(SPAN_USE_EQ_CTXT),
LintId::of(DIRECT_USE_OF_RUSTC_TYPE_IR),
LintId::of(IMPLICIT_SYSROOT_CRATE_IMPORT),
LintId::of(BAD_USE_OF_FIND_ATTR),
],
);
}
+6
View File
@@ -1143,6 +1143,12 @@ pub(crate) struct ImplicitSysrootCrateImportDiag<'a> {
pub name: &'a str,
}
#[derive(LintDiagnostic)]
#[diag("use of `AttributeKind` in `find_attr!(...)` invocation")]
#[note("`find_attr!(...)` already imports `AttributeKind::*`")]
#[help("remote `AttributeKind`")]
pub(crate) struct AttributeKindInFindAttr {}
// let_underscore.rs
#[derive(LintDiagnostic)]
pub(crate) enum NonBindingLet {
@@ -0,0 +1,24 @@
//@ compile-flags: -Z unstable-options
//@ ignore-stage1
#![feature(rustc_private)]
#![deny(rustc::bad_use_of_find_attr)]
extern crate rustc_hir;
use rustc_hir::{attrs::AttributeKind, find_attr};
fn main() {
let attrs = &[];
find_attr!(attrs, AttributeKind::Inline(..));
//~^ ERROR use of `AttributeKind` in `find_attr!(...)` invocation
find_attr!(attrs, AttributeKind::Inline{..} | AttributeKind::Deprecation {..});
//~^ ERROR use of `AttributeKind` in `find_attr!(...)` invocation
//~| ERROR use of `AttributeKind` in `find_attr!(...)` invocation
find_attr!(attrs, AttributeKind::Inline(..) => todo!());
//~^ ERROR use of `AttributeKind` in `find_attr!(...)` invocation
find_attr!(attrs, AttributeKind::Inline(..) if true => todo!());
//~^ ERROR use of `AttributeKind` in `find_attr!(...)` invocation
}
@@ -0,0 +1,52 @@
error: use of `AttributeKind` in `find_attr!(...)` invocation
--> $DIR/find_attr.rs:14:23
|
LL | find_attr!(attrs, AttributeKind::Inline(..));
| ^^^^^^^^^^^^^
|
= note: `find_attr!(...)` already imports `AttributeKind::*`
= help: remote `AttributeKind`
note: the lint level is defined here
--> $DIR/find_attr.rs:5:9
|
LL | #![deny(rustc::bad_use_of_find_attr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: use of `AttributeKind` in `find_attr!(...)` invocation
--> $DIR/find_attr.rs:16:23
|
LL | find_attr!(attrs, AttributeKind::Inline{..} | AttributeKind::Deprecation {..});
| ^^^^^^^^^^^^^
|
= note: `find_attr!(...)` already imports `AttributeKind::*`
= help: remote `AttributeKind`
error: use of `AttributeKind` in `find_attr!(...)` invocation
--> $DIR/find_attr.rs:16:51
|
LL | find_attr!(attrs, AttributeKind::Inline{..} | AttributeKind::Deprecation {..});
| ^^^^^^^^^^^^^
|
= note: `find_attr!(...)` already imports `AttributeKind::*`
= help: remote `AttributeKind`
error: use of `AttributeKind` in `find_attr!(...)` invocation
--> $DIR/find_attr.rs:20:23
|
LL | find_attr!(attrs, AttributeKind::Inline(..) => todo!());
| ^^^^^^^^^^^^^
|
= note: `find_attr!(...)` already imports `AttributeKind::*`
= help: remote `AttributeKind`
error: use of `AttributeKind` in `find_attr!(...)` invocation
--> $DIR/find_attr.rs:22:23
|
LL | find_attr!(attrs, AttributeKind::Inline(..) if true => todo!());
| ^^^^^^^^^^^^^
|
= note: `find_attr!(...)` already imports `AttributeKind::*`
= help: remote `AttributeKind`
error: aborting due to 5 previous errors