Skip to content

Commit 5470e2a

Browse files
committed
Rustdoc: remove ListAttributesIter and use impl Iterator instead
1 parent e91ad5f commit 5470e2a

File tree

7 files changed

+35
-75
lines changed

7 files changed

+35
-75
lines changed

src/librustdoc/clean/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -729,15 +729,14 @@ fn clean_fn_or_proc_macro(
729729
match macro_kind {
730730
Some(kind) => {
731731
if kind == MacroKind::Derive {
732-
*name = attrs
733-
.lists(sym::proc_macro_derive)
732+
*name = attr_items(attrs, sym::proc_macro_derive)
734733
.find_map(|mi| mi.ident())
735734
.expect("proc-macro derives require a name")
736735
.name;
737736
}
738737

739738
let mut helpers = Vec::new();
740-
for mi in attrs.lists(sym::proc_macro_derive) {
739+
for mi in attr_items(attrs, sym::proc_macro_derive) {
741740
if !mi.has_name(sym::attributes) {
742741
continue;
743742
}
@@ -1955,7 +1954,8 @@ fn clean_use_statement(
19551954

19561955
let visibility = cx.tcx.visibility(import.def_id);
19571956
let attrs = cx.tcx.hir().attrs(import.hir_id());
1958-
let inline_attr = attrs.lists(sym::doc).get_word_attr(sym::inline);
1957+
let inline_attr =
1958+
attr_items(attrs, sym::doc).find(|attr| attr.is_word() && attr.has_name(sym::inline));
19591959
let pub_underscore = visibility.is_public() && name == kw::Underscore;
19601960
let current_mod = cx.tcx.parent_module_from_def_id(import.def_id);
19611961

src/librustdoc/clean/types.rs

Lines changed: 18 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::lazy::SyncOnceCell as OnceCell;
66
use std::path::PathBuf;
77
use std::rc::Rc;
88
use std::sync::Arc;
9-
use std::{slice, vec};
9+
use std::vec;
1010

1111
use arrayvec::ArrayVec;
1212

@@ -215,8 +215,7 @@ impl ExternalCrate {
215215
// Failing that, see if there's an attribute specifying where to find this
216216
// external crate
217217
let did = DefId { krate: self.crate_num, index: CRATE_DEF_INDEX };
218-
tcx.get_attrs(did)
219-
.lists(sym::doc)
218+
attr_items(tcx.get_attrs(did), sym::doc)
220219
.filter(|a| a.has_name(sym::html_root_url))
221220
.filter_map(|a| a.value_str())
222221
.map(to_remote)
@@ -232,7 +231,7 @@ impl ExternalCrate {
232231
if let Res::Def(DefKind::Mod, def_id) = res {
233232
let attrs = tcx.get_attrs(def_id);
234233
let mut keyword = None;
235-
for attr in attrs.lists(sym::doc) {
234+
for attr in attr_items(attrs, sym::doc) {
236235
if attr.has_name(sym::keyword) {
237236
if let Some(v) = attr.value_str() {
238237
keyword = Some(v);
@@ -294,7 +293,7 @@ impl ExternalCrate {
294293
if let Res::Def(DefKind::Mod, def_id) = res {
295294
let attrs = tcx.get_attrs(def_id);
296295
let mut prim = None;
297-
for attr in attrs.lists(sym::doc) {
296+
for attr in attr_items(attrs, sym::doc) {
298297
if let Some(v) = attr.value_str() {
299298
if attr.has_name(sym::primitive) {
300299
prim = PrimitiveType::from_symbol(v);
@@ -725,44 +724,19 @@ crate struct Module {
725724
crate span: Span,
726725
}
727726

728-
crate struct ListAttributesIter<'a> {
729-
attrs: slice::Iter<'a, ast::Attribute>,
730-
current_list: vec::IntoIter<ast::NestedMetaItem>,
727+
/// Finds attributes with the given name and returns their nested items.
728+
crate fn attr_items(
729+
attrs: &[ast::Attribute],
731730
name: Symbol,
732-
}
733-
734-
impl<'a> Iterator for ListAttributesIter<'a> {
735-
type Item = ast::NestedMetaItem;
736-
737-
fn next(&mut self) -> Option<Self::Item> {
738-
if let Some(nested) = self.current_list.next() {
739-
return Some(nested);
740-
}
741-
742-
for attr in &mut self.attrs {
743-
if let Some(list) = attr.meta_item_list() {
744-
if attr.has_name(self.name) {
745-
self.current_list = list.into_iter();
746-
if let Some(nested) = self.current_list.next() {
747-
return Some(nested);
748-
}
749-
}
750-
}
751-
}
752-
753-
None
754-
}
755-
756-
fn size_hint(&self) -> (usize, Option<usize>) {
757-
let lower = self.current_list.len();
758-
(lower, None)
759-
}
731+
) -> impl Iterator<Item = ast::NestedMetaItem> + '_ {
732+
attrs
733+
.iter()
734+
.filter(move |attr| attr.has_name(name))
735+
.filter_map(ast::Attribute::meta_item_list)
736+
.flatten()
760737
}
761738

762739
crate trait AttributesExt {
763-
/// Finds an attribute as List and returns the list of attributes nested inside.
764-
fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
765-
766740
fn span(&self) -> Option<rustc_span::Span>;
767741

768742
fn inner_docs(&self) -> bool;
@@ -773,10 +747,6 @@ crate trait AttributesExt {
773747
}
774748

775749
impl AttributesExt for [ast::Attribute] {
776-
fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
777-
ListAttributesIter { attrs: self.iter(), current_list: Vec::new().into_iter(), name }
778-
}
779-
780750
/// Return the span of the first doc-comment, if it exists.
781751
fn span(&self) -> Option<rustc_span::Span> {
782752
self.iter().find(|attr| attr.doc_str().is_some()).map(|attr| attr.span)
@@ -860,7 +830,7 @@ impl AttributesExt for [ast::Attribute] {
860830

861831
// treat #[target_feature(enable = "feat")] attributes as if they were
862832
// #[doc(cfg(target_feature = "feat"))] attributes as well
863-
for attr in self.lists(sym::target_feature) {
833+
for attr in attr_items(self, sym::target_feature) {
864834
if attr.has_name(sym::enable) {
865835
if let Some(feat) = attr.value_str() {
866836
let meta = attr::mk_name_value_item_str(
@@ -882,18 +852,11 @@ impl AttributesExt for [ast::Attribute] {
882852
crate trait NestedAttributesExt {
883853
/// Returns `true` if the attribute list contains a specific `Word`
884854
fn has_word(self, word: Symbol) -> bool;
885-
fn get_word_attr(self, word: Symbol) -> Option<ast::NestedMetaItem>;
886855
}
887856

888-
impl<I: Iterator<Item = ast::NestedMetaItem> + IntoIterator<Item = ast::NestedMetaItem>>
889-
NestedAttributesExt for I
890-
{
891-
fn has_word(self, word: Symbol) -> bool {
892-
self.into_iter().any(|attr| attr.is_word() && attr.has_name(word))
893-
}
894-
895-
fn get_word_attr(mut self, word: Symbol) -> Option<ast::NestedMetaItem> {
896-
self.find(|attr| attr.is_word() && attr.has_name(word))
857+
impl<I: Iterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I {
858+
fn has_word(mut self, word: Symbol) -> bool {
859+
self.any(|attr| attr.is_word() && attr.has_name(word))
897860
}
898861
}
899862

@@ -1001,10 +964,6 @@ crate struct Attributes {
1001964
}
1002965

1003966
impl Attributes {
1004-
crate fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
1005-
self.other_attrs.lists(name)
1006-
}
1007-
1008967
crate fn has_doc_flag(&self, flag: Symbol) -> bool {
1009968
for attr in &self.other_attrs {
1010969
if !attr.has_name(sym::doc) {
@@ -1110,7 +1069,7 @@ impl Attributes {
11101069
crate fn get_doc_aliases(&self) -> Box<[Symbol]> {
11111070
let mut aliases = FxHashSet::default();
11121071

1113-
for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) {
1072+
for attr in attr_items(&self.other_attrs, sym::doc).filter(|a| a.has_name(sym::alias)) {
11141073
if let Some(values) = attr.meta_item_list() {
11151074
for l in values {
11161075
match l.literal().unwrap().kind {

src/librustdoc/core.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use std::mem;
3232
use std::rc::Rc;
3333

3434
use crate::clean::inline::build_external_trait;
35-
use crate::clean::{self, ItemId, TraitWithExtraInfo};
35+
use crate::clean::{self, attr_items, ItemId, TraitWithExtraInfo};
3636
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
3737
use crate::formats::cache::Cache;
3838
use crate::passes::{self, Condition::*};
@@ -435,7 +435,7 @@ crate fn run_global_ctxt(
435435

436436
// Process all of the crate attributes, extracting plugin metadata along
437437
// with the passes which we are supposed to run.
438-
for attr in krate.module.attrs.lists(sym::doc) {
438+
for attr in attr_items(&krate.module.attrs.other_attrs, sym::doc) {
439439
let diag = ctxt.sess().diagnostic();
440440

441441
let name = attr.name_or_empty();

src/librustdoc/html/render/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use super::{
2222
BASIC_KEYWORDS,
2323
};
2424

25-
use crate::clean::{self, ExternalCrate};
25+
use crate::clean::{self, attr_items, ExternalCrate};
2626
use crate::config::RenderOptions;
2727
use crate::docfs::{DocFS, PathError};
2828
use crate::error::Error;
@@ -430,7 +430,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
430430

431431
// Crawl the crate attributes looking for attributes which control how we're
432432
// going to emit HTML
433-
for attr in krate.module.attrs.lists(sym::doc) {
433+
for attr in attr_items(&krate.module.attrs.other_attrs, sym::doc) {
434434
match (attr.name_or_empty(), attr.value_str()) {
435435
(sym::html_favicon_url, Some(s)) => {
436436
layout.favicon = s.to_string();

src/librustdoc/passes/check_doc_test_visibility.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo
9696
}
9797
}
9898

99-
if cx.tcx.hir().attrs(hir_id).lists(sym::doc).has_word(sym::hidden)
99+
if attr_items(&cx.tcx.hir().attrs(hir_id), sym::doc).has_word(sym::hidden)
100100
|| inherits_doc_hidden(cx.tcx, hir_id)
101101
|| cx.tcx.hir().span(hir_id).in_derive_expansion()
102102
{

src/librustdoc/passes/strip_hidden.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_span::symbol::sym;
33
use std::mem;
44

55
use crate::clean;
6-
use crate::clean::{Item, ItemIdSet, NestedAttributesExt};
6+
use crate::clean::{attr_items, Item, ItemIdSet, NestedAttributesExt};
77
use crate::core::DocContext;
88
use crate::fold::{strip_item, DocFolder};
99
use crate::passes::{ImplStripper, Pass};
@@ -36,7 +36,7 @@ struct Stripper<'a> {
3636

3737
impl<'a> DocFolder for Stripper<'a> {
3838
fn fold_item(&mut self, i: Item) -> Option<Item> {
39-
if i.attrs.lists(sym::doc).has_word(sym::hidden) {
39+
if attr_items(&i.attrs.other_attrs, sym::doc).has_word(sym::hidden) {
4040
debug!("strip_hidden: stripping {:?} {:?}", i.type_(), i.name);
4141
// use a dedicated hidden item for given item type if any
4242
match *i.kind {

src/librustdoc/visit_ast.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_span::Span;
1616

1717
use std::mem;
1818

19-
use crate::clean::{self, cfg::Cfg, AttributesExt, NestedAttributesExt};
19+
use crate::clean::{self, attr_items, cfg::Cfg, NestedAttributesExt};
2020
use crate::core;
2121

2222
/// This module is used to store stuff from Rust's AST in a more convenient
@@ -55,7 +55,7 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec<String> {
5555
crate fn inherits_doc_hidden(tcx: TyCtxt<'_>, mut node: hir::HirId) -> bool {
5656
while let Some(id) = tcx.hir().get_enclosing_scope(node) {
5757
node = id;
58-
if tcx.hir().attrs(node).lists(sym::doc).has_word(sym::hidden) {
58+
if attr_items(tcx.hir().attrs(node), sym::doc).has_word(sym::hidden) {
5959
return true;
6060
}
6161
}
@@ -199,16 +199,17 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
199199

200200
let use_attrs = tcx.hir().attrs(id);
201201
// Don't inline `doc(hidden)` imports so they can be stripped at a later stage.
202-
let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline)
203-
|| use_attrs.lists(sym::doc).has_word(sym::hidden);
202+
let is_no_inline = attr_items(&use_attrs, sym::doc).any(|attr| {
203+
attr.is_word() && (attr.has_name(sym::no_inline) || attr.has_name(sym::hidden))
204+
});
204205

205206
// For cross-crate impl inlining we need to know whether items are
206207
// reachable in documentation -- a previously unreachable item can be
207208
// made reachable by cross-crate inlining which we're checking here.
208209
// (this is done here because we need to know this upfront).
209210
if !res_did.is_local() && !is_no_inline {
210211
let attrs = clean::inline::load_attrs(self.cx, res_did);
211-
let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden);
212+
let self_is_hidden = attr_items(attrs, sym::doc).has_word(sym::hidden);
212213
if !self_is_hidden {
213214
if let Res::Def(kind, did) = res {
214215
if kind == DefKind::Mod {

0 commit comments

Comments
 (0)