diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 9774173f24780..2920ec76591bb 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -181,6 +181,13 @@ impl AttributeExt for Attribute { } } + fn meta_item_list_any bool>(&self, func: F) -> bool { + match &self.kind { + AttrKind::Normal(normal) => normal.item.meta_item_list_any(func), + AttrKind::DocComment(..) => false, + } + } + /// Returns the string value in: /// /// ```text @@ -253,21 +260,14 @@ impl AttributeExt for Attribute { } fn is_doc_hidden(&self) -> bool { - self.has_name(sym::doc) - && self.meta_item_list().is_some_and(|l| list_contains_name(&l, sym::hidden)) + self.has_name(sym::doc) && self.meta_item_list_any(|item| item.has_name(sym::hidden)) } fn is_doc_keyword_or_attribute(&self) -> bool { - if self.has_name(sym::doc) - && let Some(items) = self.meta_item_list() - { - for item in items { - if item.has_name(sym::keyword) || item.has_name(sym::attribute) { - return true; - } - } - } - false + self.has_name(sym::doc) + && self.meta_item_list_any(|item| { + item.has_name(sym::keyword) || item.has_name(sym::attribute) + }) } fn is_rustc_doc_primitive(&self) -> bool { @@ -358,6 +358,15 @@ impl AttrItem { } } + pub fn meta_item_list_any bool>(&self, func: F) -> bool { + match &self.args.unparsed_ref() { + Some(AttrArgs::Delimited(args)) if args.delim == Delimiter::Parenthesis => { + MetaItemKind::meta_item_list_any(&args.tokens, func) + } + _ => false, + } + } + /// Returns the string value in: /// /// ```text @@ -565,6 +574,27 @@ impl MetaItemKind { Some(result) } + pub fn meta_item_list_any bool>( + tokens: &TokenStream, + func: F, + ) -> bool { + let mut iter = tokens.iter(); + while iter.peek().is_some() { + let item = match MetaItemInner::from_tokens(&mut iter) { + Some(item) => item, + None => return false, + }; + if func(&item) { + return true; + } + match iter.next() { + None | Some(TokenTree::Token(Token { kind: token::Comma, .. }, _)) => {} + _ => return false, + } + } + false + } + fn name_value_from_tokens(iter: &mut TokenStreamIter<'_>) -> Option { match iter.next() { Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) => { @@ -951,6 +981,13 @@ pub trait AttributeExt: Debug { /// Get the meta item list, `#[attr(meta item list)]` fn meta_item_list(&self) -> Option>; + fn meta_item_list_any bool>(&self, func: F) -> bool { + match self.meta_item_list() { + None => false, + Some(list) => list.iter().any(func), + } + } + /// Gets the value literal, as string, when using `#[attr = value]` fn value_str(&self) -> Option; @@ -1053,6 +1090,10 @@ impl Attribute { AttributeExt::meta_item_list(self) } + pub fn meta_item_list_any bool>(&self, func: F) -> bool { + AttributeExt::meta_item_list_any(self, func) + } + pub fn value_str(&self) -> Option { AttributeExt::value_str(self) }