diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 00c6e38839f54..3614b57df9da5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -5,7 +5,7 @@ use std::lazy::SyncOnceCell as OnceCell; use std::path::PathBuf; use std::rc::Rc; use std::sync::Arc; -use std::{slice, vec}; +use std::vec; use arrayvec::ArrayVec; @@ -733,43 +733,12 @@ crate struct Module { crate span: Span, } -crate struct ListAttributesIter<'a> { - attrs: slice::Iter<'a, ast::Attribute>, - current_list: vec::IntoIter, - name: Symbol, -} - -impl<'a> Iterator for ListAttributesIter<'a> { - type Item = ast::NestedMetaItem; - - fn next(&mut self) -> Option { - if let Some(nested) = self.current_list.next() { - return Some(nested); - } - - for attr in &mut self.attrs { - if let Some(list) = attr.meta_item_list() { - if attr.has_name(self.name) { - self.current_list = list.into_iter(); - if let Some(nested) = self.current_list.next() { - return Some(nested); - } - } - } - } - - None - } - - fn size_hint(&self) -> (usize, Option) { - let lower = self.current_list.len(); - (lower, None) - } -} - crate trait AttributesExt { - /// Finds an attribute as List and returns the list of attributes nested inside. - fn lists(&self, name: Symbol) -> ListAttributesIter<'_>; + type AttributeIterator<'a>: Iterator + where + Self: 'a; + + fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a>; fn span(&self) -> Option; @@ -781,8 +750,13 @@ crate trait AttributesExt { } impl AttributesExt for [ast::Attribute] { - fn lists(&self, name: Symbol) -> ListAttributesIter<'_> { - ListAttributesIter { attrs: self.iter(), current_list: Vec::new().into_iter(), name } + type AttributeIterator<'a> = impl Iterator + 'a; + + fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a> { + self.iter() + .filter(move |attr| attr.has_name(name)) + .filter_map(ast::Attribute::meta_item_list) + .flatten() } /// Return the span of the first doc-comment, if it exists. @@ -901,12 +875,9 @@ crate trait NestedAttributesExt { fn get_word_attr(self, word: Symbol) -> Option; } -impl NestedAttributesExt for I -where - I: IntoIterator, -{ - fn get_word_attr(self, word: Symbol) -> Option { - self.into_iter().find(|attr| attr.is_word() && attr.has_name(word)) +impl> NestedAttributesExt for I { + fn get_word_attr(mut self, word: Symbol) -> Option { + self.find(|attr| attr.is_word() && attr.has_name(word)) } } @@ -1014,7 +985,7 @@ crate struct Attributes { } impl Attributes { - crate fn lists(&self, name: Symbol) -> ListAttributesIter<'_> { + crate fn lists(&self, name: Symbol) -> impl Iterator + '_ { self.other_attrs.lists(name) } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index a647a0fbfa55d..0020a1ec1f547 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -16,6 +16,8 @@ #![feature(once_cell)] #![feature(type_ascription)] #![feature(iter_intersperse)] +#![feature(type_alias_impl_trait)] +#![feature(generic_associated_types)] #![recursion_limit = "256"] #![warn(rustc::internal)] #![allow(clippy::collapsible_if, clippy::collapsible_else_if)]