Skip to content

Commit 92ed874

Browse files
committed
Auto merge of #92353 - Kobzol:doc-attr-lists-gat, r=GuillaumeGomez
Rustdoc: remove ListAttributesIter and use impl Iterator instead This is a continuation of #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](Kobzol@5470e2a), 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
2 parents 17dfae7 + 3a3e4b7 commit 92ed874

File tree

2 files changed

+19
-46
lines changed

2 files changed

+19
-46
lines changed

src/librustdoc/clean/types.rs

+17-46
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::lazy::SyncOnceCell as OnceCell;
55
use std::path::PathBuf;
66
use std::rc::Rc;
77
use std::sync::Arc;
8-
use std::{slice, vec};
8+
use std::vec;
99

1010
use arrayvec::ArrayVec;
1111

@@ -733,43 +733,12 @@ crate struct Module {
733733
crate span: Span,
734734
}
735735

736-
crate struct ListAttributesIter<'a> {
737-
attrs: slice::Iter<'a, ast::Attribute>,
738-
current_list: vec::IntoIter<ast::NestedMetaItem>,
739-
name: Symbol,
740-
}
741-
742-
impl<'a> Iterator for ListAttributesIter<'a> {
743-
type Item = ast::NestedMetaItem;
744-
745-
fn next(&mut self) -> Option<Self::Item> {
746-
if let Some(nested) = self.current_list.next() {
747-
return Some(nested);
748-
}
749-
750-
for attr in &mut self.attrs {
751-
if let Some(list) = attr.meta_item_list() {
752-
if attr.has_name(self.name) {
753-
self.current_list = list.into_iter();
754-
if let Some(nested) = self.current_list.next() {
755-
return Some(nested);
756-
}
757-
}
758-
}
759-
}
760-
761-
None
762-
}
763-
764-
fn size_hint(&self) -> (usize, Option<usize>) {
765-
let lower = self.current_list.len();
766-
(lower, None)
767-
}
768-
}
769-
770736
crate trait AttributesExt {
771-
/// Finds an attribute as List and returns the list of attributes nested inside.
772-
fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
737+
type AttributeIterator<'a>: Iterator<Item = ast::NestedMetaItem>
738+
where
739+
Self: 'a;
740+
741+
fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a>;
773742

774743
fn span(&self) -> Option<rustc_span::Span>;
775744

@@ -781,8 +750,13 @@ crate trait AttributesExt {
781750
}
782751

783752
impl AttributesExt for [ast::Attribute] {
784-
fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
785-
ListAttributesIter { attrs: self.iter(), current_list: Vec::new().into_iter(), name }
753+
type AttributeIterator<'a> = impl Iterator<Item = ast::NestedMetaItem> + 'a;
754+
755+
fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a> {
756+
self.iter()
757+
.filter(move |attr| attr.has_name(name))
758+
.filter_map(ast::Attribute::meta_item_list)
759+
.flatten()
786760
}
787761

788762
/// Return the span of the first doc-comment, if it exists.
@@ -902,12 +876,9 @@ crate trait NestedAttributesExt {
902876
fn get_word_attr(self, word: Symbol) -> Option<ast::NestedMetaItem>;
903877
}
904878

905-
impl<I> NestedAttributesExt for I
906-
where
907-
I: IntoIterator<Item = ast::NestedMetaItem>,
908-
{
909-
fn get_word_attr(self, word: Symbol) -> Option<ast::NestedMetaItem> {
910-
self.into_iter().find(|attr| attr.is_word() && attr.has_name(word))
879+
impl<I: Iterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I {
880+
fn get_word_attr(mut self, word: Symbol) -> Option<ast::NestedMetaItem> {
881+
self.find(|attr| attr.is_word() && attr.has_name(word))
911882
}
912883
}
913884

@@ -1015,7 +986,7 @@ crate struct Attributes {
1015986
}
1016987

1017988
impl Attributes {
1018-
crate fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
989+
crate fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::NestedMetaItem> + '_ {
1019990
self.other_attrs.lists(name)
1020991
}
1021992

src/librustdoc/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#![feature(once_cell)]
1717
#![feature(type_ascription)]
1818
#![feature(iter_intersperse)]
19+
#![feature(type_alias_impl_trait)]
20+
#![feature(generic_associated_types)]
1921
#![recursion_limit = "256"]
2022
#![warn(rustc::internal)]
2123
#![allow(clippy::collapsible_if, clippy::collapsible_else_if)]

0 commit comments

Comments
 (0)