Skip to content

Commit 4328207

Browse files
Auto merge of #142720 - yotamofek:pr/rustdoc/ext-crate-cleanup, r=<try>
De-dup common code from `ExternalCrate` methods <!-- homu-ignore:start --> <!-- If this PR is related to an unstable feature or an otherwise tracked effort, please link to the relevant tracking issue here. If you don't know of a related tracking issue or there are none, feel free to ignore this. This PR will get automatically assigned to a reviewer. In case you would like a specific user to review your work, you can assign it to them by using r? <reviewer name> --> <!-- homu-ignore:end --> Also, return an `impl Iterator` instead of collecting into a `Vec`. Not sure if that'll have a measurable perf impact, but I think this PR still cleans up the two methods it touches quite nicely. (I'm having trouble finding a name for the common method I extracted, currently called `foobar`, would love suggestions!)
2 parents 2fcf177 + aca0688 commit 4328207

File tree

3 files changed

+53
-71
lines changed

3 files changed

+53
-71
lines changed

src/librustdoc/clean/types.rs

Lines changed: 50 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::sync::{Arc, OnceLock as OnceCell};
44
use std::{fmt, iter};
55

66
use arrayvec::ArrayVec;
7+
use itertools::Either;
78
use rustc_abi::{ExternAbi, VariantIdx};
89
use rustc_attr_data_structures::{
910
AttributeKind, ConstStability, Deprecation, Stability, StableSince,
@@ -199,49 +200,49 @@ impl ExternalCrate {
199200
.unwrap_or(Unknown) // Well, at least we tried.
200201
}
201202

202-
pub(crate) fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> {
203+
fn mapped_root_modules<T>(
204+
&self,
205+
tcx: TyCtxt<'_>,
206+
f: impl Fn(DefId, TyCtxt<'_>) -> Option<(DefId, T)>,
207+
) -> impl Iterator<Item = (DefId, T)> {
203208
let root = self.def_id();
204209

205-
let as_keyword = |res: Res<!>| {
206-
if let Res::Def(DefKind::Mod, def_id) = res {
207-
let mut keyword = None;
208-
let meta_items = tcx
209-
.get_attrs(def_id, sym::doc)
210-
.flat_map(|attr| attr.meta_item_list().unwrap_or_default());
211-
for meta in meta_items {
212-
if meta.has_name(sym::keyword)
213-
&& let Some(v) = meta.value_str()
214-
{
215-
keyword = Some(v);
216-
break;
217-
}
218-
}
219-
return keyword.map(|p| (def_id, p));
220-
}
221-
None
222-
};
223210
if root.is_local() {
224-
tcx.hir_root_module()
225-
.item_ids
226-
.iter()
227-
.filter_map(|&id| {
228-
let item = tcx.hir_item(id);
229-
match item.kind {
230-
hir::ItemKind::Mod(..) => {
231-
as_keyword(Res::Def(DefKind::Mod, id.owner_id.to_def_id()))
232-
}
233-
_ => None,
234-
}
235-
})
236-
.collect()
211+
Either::Left(
212+
tcx.hir_root_module()
213+
.item_ids
214+
.iter()
215+
.filter(move |&&id| matches!(tcx.hir_item(id).kind, hir::ItemKind::Mod(..)))
216+
.filter_map(move |&id| f(id.owner_id.into(), tcx)),
217+
)
237218
} else {
238-
tcx.module_children(root).iter().map(|item| item.res).filter_map(as_keyword).collect()
219+
Either::Right(
220+
tcx.module_children(root)
221+
.iter()
222+
.filter_map(|item| {
223+
if let Res::Def(DefKind::Mod, did) = item.res { Some(did) } else { None }
224+
})
225+
.filter_map(move |did| f(did, tcx)),
226+
)
239227
}
240228
}
241229

242-
pub(crate) fn primitives(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, PrimitiveType)> {
243-
let root = self.def_id();
230+
pub(crate) fn keywords(&self, tcx: TyCtxt<'_>) -> impl Iterator<Item = (DefId, Symbol)> {
231+
fn as_keyword(did: DefId, tcx: TyCtxt<'_>) -> Option<(DefId, Symbol)> {
232+
tcx.get_attrs(did, sym::doc)
233+
.flat_map(|attr| attr.meta_item_list().unwrap_or_default())
234+
.filter(|meta| meta.has_name(sym::keyword))
235+
.find_map(|meta| meta.value_str())
236+
.map(|value| (did, value))
237+
}
244238

239+
self.mapped_root_modules(tcx, as_keyword)
240+
}
241+
242+
pub(crate) fn primitives(
243+
&self,
244+
tcx: TyCtxt<'_>,
245+
) -> impl Iterator<Item = (DefId, PrimitiveType)> {
245246
// Collect all inner modules which are tagged as implementations of
246247
// primitives.
247248
//
@@ -259,40 +260,21 @@ impl ExternalCrate {
259260
// Also note that this does not attempt to deal with modules tagged
260261
// duplicately for the same primitive. This is handled later on when
261262
// rendering by delegating everything to a hash map.
262-
let as_primitive = |res: Res<!>| {
263-
let Res::Def(DefKind::Mod, def_id) = res else { return None };
264-
tcx.get_attrs(def_id, sym::rustc_doc_primitive)
265-
.map(|attr| {
266-
let attr_value = attr.value_str().expect("syntax should already be validated");
267-
let Some(prim) = PrimitiveType::from_symbol(attr_value) else {
268-
span_bug!(
269-
attr.span(),
270-
"primitive `{attr_value}` is not a member of `PrimitiveType`"
271-
);
272-
};
273-
274-
(def_id, prim)
275-
})
276-
.next()
277-
};
263+
fn as_primitive(def_id: DefId, tcx: TyCtxt<'_>) -> Option<(DefId, PrimitiveType)> {
264+
tcx.get_attrs(def_id, sym::rustc_doc_primitive).next().map(|attr| {
265+
let attr_value = attr.value_str().expect("syntax should already be validated");
266+
let Some(prim) = PrimitiveType::from_symbol(attr_value) else {
267+
span_bug!(
268+
attr.span(),
269+
"primitive `{attr_value}` is not a member of `PrimitiveType`"
270+
);
271+
};
278272

279-
if root.is_local() {
280-
tcx.hir_root_module()
281-
.item_ids
282-
.iter()
283-
.filter_map(|&id| {
284-
let item = tcx.hir_item(id);
285-
match item.kind {
286-
hir::ItemKind::Mod(..) => {
287-
as_primitive(Res::Def(DefKind::Mod, id.owner_id.to_def_id()))
288-
}
289-
_ => None,
290-
}
291-
})
292-
.collect()
293-
} else {
294-
tcx.module_children(root).iter().map(|item| item.res).filter_map(as_primitive).collect()
273+
(def_id, prim)
274+
})
295275
}
276+
277+
self.mapped_root_modules(tcx, as_primitive)
296278
}
297279
}
298280

@@ -1966,7 +1948,7 @@ impl PrimitiveType {
19661948
let e = ExternalCrate { crate_num };
19671949
let crate_name = e.name(tcx);
19681950
debug!(?crate_num, ?crate_name);
1969-
for &(def_id, prim) in &e.primitives(tcx) {
1951+
for (def_id, prim) in e.primitives(tcx) {
19701952
// HACK: try to link to std instead where possible
19711953
if crate_name == sym::core && primitive_locations.contains_key(&prim) {
19721954
continue;

src/librustdoc/clean/utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
6161
let keywords = local_crate.keywords(cx.tcx);
6262
{
6363
let ItemKind::ModuleItem(m) = &mut module.inner.kind else { unreachable!() };
64-
m.items.extend(primitives.iter().map(|&(def_id, prim)| {
64+
m.items.extend(primitives.map(|(def_id, prim)| {
6565
Item::from_def_id_and_parts(
6666
def_id,
6767
Some(prim.as_sym()),
6868
ItemKind::PrimitiveItem(prim),
6969
cx,
7070
)
7171
}));
72-
m.items.extend(keywords.into_iter().map(|(def_id, kw)| {
72+
m.items.extend(keywords.map(|(def_id, kw)| {
7373
Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::KeywordItem, cx)
7474
}));
7575
}

src/librustdoc/passes/collect_trait_impls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
3535
});
3636

3737
let local_crate = ExternalCrate { crate_num: LOCAL_CRATE };
38-
let prims: FxHashSet<PrimitiveType> = local_crate.primitives(tcx).iter().map(|p| p.1).collect();
38+
let prims: FxHashSet<PrimitiveType> = local_crate.primitives(tcx).map(|(_, p)| p).collect();
3939

4040
let crate_items = {
4141
let mut coll = ItemAndAliasCollector::new(&cx.cache);

0 commit comments

Comments
 (0)