diff options
| author | bors <bors@rust-lang.org> | 2022-01-25 15:43:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-01-25 15:43:29 +0000 |
| commit | 92ed8747f255b2695c33b64982e6959711a72cb9 (patch) | |
| tree | 2d93b34de6249b0f75fd8862846dcd545825407c | |
| parent | 17dfae79bbc3dabe1427073086acf7f7bd45148c (diff) | |
| parent | 3a3e4b78593bc2669828dfc2e36070897b9c6a4d (diff) | |
| download | rust-92ed8747f255b2695c33b64982e6959711a72cb9.tar.gz rust-92ed8747f255b2695c33b64982e6959711a72cb9.zip | |
Auto merge of #92353 - Kobzol:doc-attr-lists-gat, r=GuillaumeGomez
Rustdoc: remove ListAttributesIter and use impl Iterator instead This is a continuation of https://github.com/rust-lang/rust/pull/92227. I found that `ListAttributesIter` did not optimize well and replacing it with a simple `impl Iterator` resulted in 1-3 % instruction count wins locally. Because I needed to use `impl Iterator` on a slice of AST attributes, I had to implement it using GAT + impl trait. I also have a version without GAT [here](https://github.com/Kobzol/rust/commit/5470e2a65cbd3086d19f0847f44ca9cbbc049689), if GATs are not welcome in rustdoc :D Locally it resulted in equal performance numbers. Can I ask for a perf. run? Thanks. r? rust-lang/rustdoc
| -rw-r--r-- | src/librustdoc/clean/types.rs | 63 | ||||
| -rw-r--r-- | src/librustdoc/lib.rs | 2 |
2 files changed, 19 insertions, 46 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 0c0787c6b2f..dac23691a30 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<ast::NestedMetaItem>, - name: Symbol, -} - -impl<'a> Iterator for ListAttributesIter<'a> { - type Item = ast::NestedMetaItem; - - fn next(&mut self) -> Option<Self::Item> { - 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<usize>) { - 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<Item = ast::NestedMetaItem> + where + Self: 'a; + + fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a>; fn span(&self) -> Option<rustc_span::Span>; @@ -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<Item = ast::NestedMetaItem> + '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. @@ -902,12 +876,9 @@ crate trait NestedAttributesExt { fn get_word_attr(self, word: Symbol) -> Option<ast::NestedMetaItem>; } -impl<I> NestedAttributesExt for I -where - I: IntoIterator<Item = ast::NestedMetaItem>, -{ - fn get_word_attr(self, word: Symbol) -> Option<ast::NestedMetaItem> { - self.into_iter().find(|attr| attr.is_word() && attr.has_name(word)) +impl<I: Iterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I { + fn get_word_attr(mut self, word: Symbol) -> Option<ast::NestedMetaItem> { + self.find(|attr| attr.is_word() && attr.has_name(word)) } } @@ -1015,7 +986,7 @@ crate struct Attributes { } impl Attributes { - crate fn lists(&self, name: Symbol) -> ListAttributesIter<'_> { + crate fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::NestedMetaItem> + '_ { self.other_attrs.lists(name) } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index d854aa86b3a..a7c3c0bb606 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)] |
