about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonathan Brouwer <jonathantbrouwer@gmail.com>2025-07-03 09:10:49 +0200
committerJonathan Brouwer <jonathantbrouwer@gmail.com>2025-07-04 20:30:42 +0200
commit9c9ee348072ef5c8f29ccd8c0496d2269ba244df (patch)
tree63f8c498f5f004fdd8edaec0e3fcb9cfb35ed10c
parent2e9b29406a3090e6791b64078fbef0cd314bb2c3 (diff)
downloadrust-9c9ee348072ef5c8f29ccd8c0496d2269ba244df.tar.gz
rust-9c9ee348072ef5c8f29ccd8c0496d2269ba244df.zip
Port `#[non_exhaustive]` to the new attribute parsing infrastructure
-rw-r--r--clippy_lints/src/exhaustive_items.rs6
-rw-r--r--clippy_lints/src/manual_non_exhaustive.rs13
-rw-r--r--clippy_utils/src/attrs.rs9
3 files changed, 16 insertions, 12 deletions
diff --git a/clippy_lints/src/exhaustive_items.rs b/clippy_lints/src/exhaustive_items.rs
index 86d9038ec45..7dda3e0fdb9 100644
--- a/clippy_lints/src/exhaustive_items.rs
+++ b/clippy_lints/src/exhaustive_items.rs
@@ -4,7 +4,9 @@ use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
+use rustc_attr_data_structures::AttributeKind;
+use rustc_attr_data_structures::find_attr;
+
 
 declare_clippy_lint! {
     /// ### What it does
@@ -85,7 +87,7 @@ impl LateLintPass<'_> for ExhaustiveItems {
         };
         if cx.effective_visibilities.is_exported(item.owner_id.def_id)
             && let attrs = cx.tcx.hir_attrs(item.hir_id())
-            && !attrs.iter().any(|a| a.has_name(sym::non_exhaustive))
+            && !find_attr!(attrs, AttributeKind::NonExhaustive(..))
             && fields.iter().all(|f| cx.tcx.visibility(f.def_id).is_public())
         {
             span_lint_and_then(cx, lint, item.span, msg, |diag| {
diff --git a/clippy_lints/src/manual_non_exhaustive.rs b/clippy_lints/src/manual_non_exhaustive.rs
index 3562b1ff5cc..51696b38880 100644
--- a/clippy_lints/src/manual_non_exhaustive.rs
+++ b/clippy_lints/src/manual_non_exhaustive.rs
@@ -4,7 +4,6 @@ use clippy_utils::is_doc_hidden;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_indent;
 use itertools::Itertools;
-use rustc_ast::attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@@ -12,7 +11,9 @@ use rustc_hir::{Expr, ExprKind, Item, ItemKind, QPath, TyKind, VariantData};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{Span, sym};
+use rustc_span::Span;
+use rustc_attr_data_structures::find_attr;
+use rustc_attr_data_structures::AttributeKind;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -93,7 +94,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {
                         .then_some((v.def_id, v.span))
                 });
                 if let Ok((id, span)) = iter.exactly_one()
-                    && !attr::contains_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive)
+                    && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(..))
                 {
                     self.potential_enums.push((item.owner_id.def_id, id, item.span, span));
                 }
@@ -113,10 +114,10 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {
                         item.span,
                         "this seems like a manual implementation of the non-exhaustive pattern",
                         |diag| {
-                            if let Some(non_exhaustive) =
-                                attr::find_by_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive)
+                            if let Some(non_exhaustive_span) =
+                                find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(span) => *span)
                             {
-                                diag.span_note(non_exhaustive.span(), "the struct is already non-exhaustive");
+                                diag.span_note(non_exhaustive_span, "the struct is already non-exhaustive");
                             } else {
                                 let indent = snippet_indent(cx, item.span).unwrap_or_default();
                                 diag.span_suggestion_verbose(
diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs
index 8a0ff5323c9..4c7a589e185 100644
--- a/clippy_utils/src/attrs.rs
+++ b/clippy_utils/src/attrs.rs
@@ -7,9 +7,10 @@ use rustc_middle::ty::{AdtDef, TyCtxt};
 use rustc_session::Session;
 use rustc_span::{Span, Symbol};
 use std::str::FromStr;
-
+use rustc_attr_data_structures::find_attr;
 use crate::source::SpanRangeExt;
 use crate::{sym, tokenize_with_text};
+use rustc_attr_data_structures::AttributeKind;
 
 /// Deprecation status of attributes known by Clippy.
 pub enum DeprecationStatus {
@@ -165,13 +166,13 @@ pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool {
 
 pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
     adt.is_variant_list_non_exhaustive()
-        || tcx.has_attr(adt.did(), sym::non_exhaustive)
+        || find_attr!(tcx.get_all_attrs(adt.did()), AttributeKind::NonExhaustive(..))
         || adt.variants().iter().any(|variant_def| {
-            variant_def.is_field_list_non_exhaustive() || tcx.has_attr(variant_def.def_id, sym::non_exhaustive)
+            variant_def.is_field_list_non_exhaustive() || find_attr!(tcx.get_all_attrs(variant_def.def_id), AttributeKind::NonExhaustive(..))
         })
         || adt
             .all_fields()
-            .any(|field_def| tcx.has_attr(field_def.did, sym::non_exhaustive))
+            .any(|field_def| find_attr!(tcx.get_all_attrs(field_def.did), AttributeKind::NonExhaustive(..)))
 }
 
 /// Checks if the given span contains a `#[cfg(..)]` attribute