1+ //! Utility functions for attributes, including Clippy's built-in ones
2+
13use crate :: source:: SpanRangeExt ;
24use crate :: { sym, tokenize_with_text} ;
35use rustc_ast:: attr;
@@ -12,7 +14,8 @@ use rustc_session::Session;
1214use rustc_span:: { Span , Symbol } ;
1315use std:: str:: FromStr ;
1416
15- pub fn get_attr < ' a , A : AttributeExt + ' a > (
17+ /// Given `attrs`, extract all the instances of a built-in Clippy attribute called `name`
18+ pub fn get_builtin_attr < ' a , A : AttributeExt + ' a > (
1619 sess : & ' a Session ,
1720 attrs : & ' a [ A ] ,
1821 name : Symbol ,
@@ -59,9 +62,11 @@ pub fn get_attr<'a, A: AttributeExt + 'a>(
5962 } )
6063}
6164
62- pub fn get_unique_attr < ' a , A : AttributeExt > ( sess : & ' a Session , attrs : & ' a [ A ] , name : Symbol ) -> Option < & ' a A > {
65+ /// If `attrs` contain exactly one instance of a built-in Clippy attribute called `name`,
66+ /// returns that attribute, and `None` otherwise
67+ pub fn get_unique_builtin_attr < ' a , A : AttributeExt > ( sess : & ' a Session , attrs : & ' a [ A ] , name : Symbol ) -> Option < & ' a A > {
6368 let mut unique_attr: Option < & A > = None ;
64- for attr in get_attr ( sess, attrs, name) {
69+ for attr in get_builtin_attr ( sess, attrs, name) {
6570 if let Some ( duplicate) = unique_attr {
6671 sess. dcx ( )
6772 . struct_span_err ( attr. span ( ) , format ! ( "`{name}` is defined multiple times" ) )
@@ -74,13 +79,13 @@ pub fn get_unique_attr<'a, A: AttributeExt>(sess: &'a Session, attrs: &'a [A], n
7479 unique_attr
7580}
7681
77- /// Returns true if the attributes contain any of `proc_macro`,
78- /// `proc_macro_derive` or ` proc_macro_attribute`, false otherwise
82+ /// Checks whether `attrs` contain any of `proc_macro`, `proc_macro_derive` or
83+ /// `proc_macro_attribute`
7984pub fn is_proc_macro ( attrs : & [ impl AttributeExt ] ) -> bool {
8085 attrs. iter ( ) . any ( AttributeExt :: is_proc_macro_attr)
8186}
8287
83- /// Returns true if the attributes contain `#[doc(hidden)]`
88+ /// Checks whether `attrs` contain `#[doc(hidden)]`
8489pub fn is_doc_hidden ( attrs : & [ impl AttributeExt ] ) -> bool {
8590 attrs
8691 . iter ( )
@@ -89,6 +94,7 @@ pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool {
8994 . any ( |l| attr:: list_contains_name ( & l, sym:: hidden) )
9095}
9196
97+ /// Checks whether the given ADT, or any of its fields/variants, are marked as `#[non_exhaustive]`
9298pub fn has_non_exhaustive_attr ( tcx : TyCtxt < ' _ > , adt : AdtDef < ' _ > ) -> bool {
9399 adt. is_variant_list_non_exhaustive ( )
94100 || find_attr ! ( tcx. get_all_attrs( adt. did( ) ) , AttributeKind :: NonExhaustive ( ..) )
@@ -101,7 +107,7 @@ pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
101107 . any ( |field_def| find_attr ! ( tcx. get_all_attrs( field_def. did) , AttributeKind :: NonExhaustive ( ..) ) )
102108}
103109
104- /// Checks if the given span contains a `#[cfg(..)]` attribute
110+ /// Checks whether the given span contains a `#[cfg(..)]` attribute
105111pub fn span_contains_cfg ( cx : & LateContext < ' _ > , s : Span ) -> bool {
106112 s. check_source_text ( cx, |src| {
107113 let mut iter = tokenize_with_text ( src) ;
@@ -123,6 +129,8 @@ pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
123129 false
124130 } )
125131}
132+
133+ /// Currently used to keep track of the current value of `#[clippy::cognitive_complexity(N)]`
126134pub struct LimitStack {
127135 default : u64 ,
128136 stack : Vec < u64 > ,
@@ -134,6 +142,7 @@ impl Drop for LimitStack {
134142 }
135143}
136144
145+ #[ expect( missing_docs, reason = "they're all trivial..." ) ]
137146impl LimitStack {
138147 #[ must_use]
139148 /// Initialize the stack starting with a default value, which usually comes from configuration
@@ -157,7 +166,7 @@ impl LimitStack {
157166}
158167
159168fn parse_attrs < F : FnMut ( u64 ) > ( sess : & Session , attrs : & [ impl AttributeExt ] , name : Symbol , mut f : F ) {
160- for attr in get_attr ( sess, attrs, name) {
169+ for attr in get_builtin_attr ( sess, attrs, name) {
161170 let Some ( value) = attr. value_str ( ) else {
162171 sess. dcx ( ) . span_err ( attr. span ( ) , "bad clippy attribute" ) ;
163172 continue ;
0 commit comments