@@ -181,6 +181,13 @@ impl AttributeExt for Attribute {
181181 }
182182 }
183183
184+ fn meta_item_list_any < F : Fn ( & MetaItemInner ) -> bool > ( & self , func : F ) -> bool {
185+ match & self . kind {
186+ AttrKind :: Normal ( normal) => normal. item . meta_item_list_any ( func) ,
187+ AttrKind :: DocComment ( ..) => false ,
188+ }
189+ }
190+
184191 /// Returns the string value in:
185192 ///
186193 /// ```text
@@ -253,21 +260,14 @@ impl AttributeExt for Attribute {
253260 }
254261
255262 fn is_doc_hidden ( & self ) -> bool {
256- self . has_name ( sym:: doc)
257- && self . meta_item_list ( ) . is_some_and ( |l| list_contains_name ( & l, sym:: hidden) )
263+ self . has_name ( sym:: doc) && self . meta_item_list_any ( |item| item. has_name ( sym:: hidden) )
258264 }
259265
260266 fn is_doc_keyword_or_attribute ( & self ) -> bool {
261- if self . has_name ( sym:: doc)
262- && let Some ( items) = self . meta_item_list ( )
263- {
264- for item in items {
265- if item. has_name ( sym:: keyword) || item. has_name ( sym:: attribute) {
266- return true ;
267- }
268- }
269- }
270- false
267+ self . has_name ( sym:: doc)
268+ && self . meta_item_list_any ( |item| {
269+ item. has_name ( sym:: keyword) || item. has_name ( sym:: attribute)
270+ } )
271271 }
272272
273273 fn is_rustc_doc_primitive ( & self ) -> bool {
@@ -358,6 +358,15 @@ impl AttrItem {
358358 }
359359 }
360360
361+ pub fn meta_item_list_any < F : Fn ( & MetaItemInner ) -> bool > ( & self , func : F ) -> bool {
362+ match & self . args . unparsed_ref ( ) {
363+ Some ( AttrArgs :: Delimited ( args) ) if args. delim == Delimiter :: Parenthesis => {
364+ MetaItemKind :: meta_item_list_any ( & args. tokens , func)
365+ }
366+ _ => false ,
367+ }
368+ }
369+
361370 /// Returns the string value in:
362371 ///
363372 /// ```text
@@ -565,6 +574,27 @@ impl MetaItemKind {
565574 Some ( result)
566575 }
567576
577+ pub fn meta_item_list_any < F : Fn ( & MetaItemInner ) -> bool > (
578+ tokens : & TokenStream ,
579+ func : F ,
580+ ) -> bool {
581+ let mut iter = tokens. iter ( ) ;
582+ while iter. peek ( ) . is_some ( ) {
583+ let item = match MetaItemInner :: from_tokens ( & mut iter) {
584+ Some ( item) => item,
585+ None => return false ,
586+ } ;
587+ if func ( & item) {
588+ return true ;
589+ }
590+ match iter. next ( ) {
591+ None | Some ( TokenTree :: Token ( Token { kind : token:: Comma , .. } , _) ) => { }
592+ _ => return false ,
593+ }
594+ }
595+ false
596+ }
597+
568598 fn name_value_from_tokens ( iter : & mut TokenStreamIter < ' _ > ) -> Option < MetaItemKind > {
569599 match iter. next ( ) {
570600 Some ( TokenTree :: Delimited ( .., Delimiter :: Invisible ( _) , inner_tokens) ) => {
@@ -951,6 +981,13 @@ pub trait AttributeExt: Debug {
951981 /// Get the meta item list, `#[attr(meta item list)]`
952982 fn meta_item_list ( & self ) -> Option < ThinVec < MetaItemInner > > ;
953983
984+ fn meta_item_list_any < F : Fn ( & MetaItemInner ) -> bool > ( & self , func : F ) -> bool {
985+ match self . meta_item_list ( ) {
986+ None => false ,
987+ Some ( list) => list. iter ( ) . any ( func) ,
988+ }
989+ }
990+
954991 /// Gets the value literal, as string, when using `#[attr = value]`
955992 fn value_str ( & self ) -> Option < Symbol > ;
956993
@@ -1053,6 +1090,10 @@ impl Attribute {
10531090 AttributeExt :: meta_item_list ( self )
10541091 }
10551092
1093+ pub fn meta_item_list_any < F : Fn ( & MetaItemInner ) -> bool > ( & self , func : F ) -> bool {
1094+ AttributeExt :: meta_item_list_any ( self , func)
1095+ }
1096+
10561097 pub fn value_str ( & self ) -> Option < Symbol > {
10571098 AttributeExt :: value_str ( self )
10581099 }
0 commit comments