Skip to content

Commit d1d1739

Browse files
committed
Get rid of ExternCrate::primitives
1 parent 3bef65f commit d1d1739

File tree

4 files changed

+77
-77
lines changed

4 files changed

+77
-77
lines changed

src/librustdoc/clean/mod.rs

+3-72
Original file line numberDiff line numberDiff line change
@@ -87,73 +87,9 @@ impl Clean<ExternalCrate> for CrateNum {
8787
let tcx = cx.tcx;
8888
let root = DefId { krate: *self, index: CRATE_DEF_INDEX };
8989

90-
// Collect all inner modules which are tagged as implementations of
91-
// primitives.
92-
//
93-
// Note that this loop only searches the top-level items of the crate,
94-
// and this is intentional. If we were to search the entire crate for an
95-
// item tagged with `#[doc(primitive)]` then we would also have to
96-
// search the entirety of external modules for items tagged
97-
// `#[doc(primitive)]`, which is a pretty inefficient process (decoding
98-
// all that metadata unconditionally).
99-
//
100-
// In order to keep the metadata load under control, the
101-
// `#[doc(primitive)]` feature is explicitly designed to only allow the
102-
// primitive tags to show up as the top level items in a crate.
103-
//
104-
// Also note that this does not attempt to deal with modules tagged
105-
// duplicately for the same primitive. This is handled later on when
106-
// rendering by delegating everything to a hash map.
107-
let mut as_primitive = |res: Res| {
90+
let as_keyword = |res: Res| {
10891
if let Res::Def(DefKind::Mod, def_id) = res {
109-
let attrs = cx.tcx.get_attrs(def_id).clean(cx);
110-
let mut prim = None;
111-
for attr in attrs.lists(sym::doc) {
112-
if let Some(v) = attr.value_str() {
113-
if attr.has_name(sym::primitive) {
114-
prim = PrimitiveType::from_symbol(v);
115-
if prim.is_some() {
116-
break;
117-
}
118-
// FIXME: should warn on unknown primitives?
119-
}
120-
}
121-
}
122-
return prim.map(|p| (def_id, p));
123-
}
124-
None
125-
};
126-
let primitives = if root.is_local() {
127-
tcx.hir()
128-
.krate()
129-
.item
130-
.item_ids
131-
.iter()
132-
.filter_map(|&id| {
133-
let item = tcx.hir().item(id);
134-
match item.kind {
135-
hir::ItemKind::Mod(_) => {
136-
as_primitive(Res::Def(DefKind::Mod, id.def_id.to_def_id()))
137-
}
138-
hir::ItemKind::Use(ref path, hir::UseKind::Single)
139-
if item.vis.node.is_pub() =>
140-
{
141-
as_primitive(path.res).map(|(_, prim)| {
142-
// Pretend the primitive is local.
143-
(id.def_id.to_def_id(), prim)
144-
})
145-
}
146-
_ => None,
147-
}
148-
})
149-
.collect()
150-
} else {
151-
tcx.item_children(root).iter().map(|item| item.res).filter_map(as_primitive).collect()
152-
};
153-
154-
let mut as_keyword = |res: Res| {
155-
if let Res::Def(DefKind::Mod, def_id) = res {
156-
let attrs = tcx.get_attrs(def_id).clean(cx);
92+
let attrs = tcx.get_attrs(def_id);
15793
let mut keyword = None;
15894
for attr in attrs.lists(sym::doc) {
15995
if attr.has_name(sym::keyword) {
@@ -192,12 +128,7 @@ impl Clean<ExternalCrate> for CrateNum {
192128
tcx.item_children(root).iter().map(|item| item.res).filter_map(as_keyword).collect()
193129
};
194130

195-
ExternalCrate {
196-
crate_num: *self,
197-
attrs: tcx.get_attrs(root).clean(cx),
198-
primitives,
199-
keywords,
200-
}
131+
ExternalCrate { crate_num: *self, attrs: tcx.get_attrs(root).clean(cx), keywords }
201132
}
202133
}
203134

src/librustdoc/clean/types.rs

+71-3
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel};
1717
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1818
use rustc_data_structures::thin_vec::ThinVec;
1919
use rustc_hir as hir;
20-
use rustc_hir::def::{CtorKind, Res};
21-
use rustc_hir::def_id::{CrateNum, DefId, DefIndex};
20+
use rustc_hir::def::{CtorKind, DefKind, Res};
21+
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
2222
use rustc_hir::lang_items::LangItem;
2323
use rustc_hir::{BodyId, Mutability};
2424
use rustc_index::vec::IndexVec;
@@ -74,7 +74,6 @@ crate struct TraitWithExtraInfo {
7474
crate struct ExternalCrate {
7575
crate crate_num: CrateNum,
7676
crate attrs: Attributes,
77-
crate primitives: ThinVec<(DefId, PrimitiveType)>,
7877
crate keywords: ThinVec<(DefId, Symbol)>,
7978
}
8079

@@ -88,6 +87,75 @@ impl ExternalCrate {
8887
crate fn name(&self, tcx: TyCtxt<'_>) -> Symbol {
8988
tcx.crate_name(self.crate_num)
9089
}
90+
91+
crate fn primitives(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, PrimitiveType)> {
92+
let root = DefId { krate: self.crate_num, index: CRATE_DEF_INDEX };
93+
94+
// Collect all inner modules which are tagged as implementations of
95+
// primitives.
96+
//
97+
// Note that this loop only searches the top-level items of the crate,
98+
// and this is intentional. If we were to search the entire crate for an
99+
// item tagged with `#[doc(primitive)]` then we would also have to
100+
// search the entirety of external modules for items tagged
101+
// `#[doc(primitive)]`, which is a pretty inefficient process (decoding
102+
// all that metadata unconditionally).
103+
//
104+
// In order to keep the metadata load under control, the
105+
// `#[doc(primitive)]` feature is explicitly designed to only allow the
106+
// primitive tags to show up as the top level items in a crate.
107+
//
108+
// Also note that this does not attempt to deal with modules tagged
109+
// duplicately for the same primitive. This is handled later on when
110+
// rendering by delegating everything to a hash map.
111+
let as_primitive = |res: Res| {
112+
if let Res::Def(DefKind::Mod, def_id) = res {
113+
let attrs = tcx.get_attrs(def_id);
114+
let mut prim = None;
115+
for attr in attrs.lists(sym::doc) {
116+
if let Some(v) = attr.value_str() {
117+
if attr.has_name(sym::primitive) {
118+
prim = PrimitiveType::from_symbol(v);
119+
if prim.is_some() {
120+
break;
121+
}
122+
// FIXME: should warn on unknown primitives?
123+
}
124+
}
125+
}
126+
return prim.map(|p| (def_id, p));
127+
}
128+
None
129+
};
130+
131+
if root.is_local() {
132+
tcx.hir()
133+
.krate()
134+
.item
135+
.item_ids
136+
.iter()
137+
.filter_map(|&id| {
138+
let item = tcx.hir().item(id);
139+
match item.kind {
140+
hir::ItemKind::Mod(_) => {
141+
as_primitive(Res::Def(DefKind::Mod, id.def_id.to_def_id()))
142+
}
143+
hir::ItemKind::Use(ref path, hir::UseKind::Single)
144+
if item.vis.node.is_pub() =>
145+
{
146+
as_primitive(path.res).map(|(_, prim)| {
147+
// Pretend the primitive is local.
148+
(id.def_id.to_def_id(), prim)
149+
})
150+
}
151+
_ => None,
152+
}
153+
})
154+
.collect()
155+
} else {
156+
tcx.item_children(root).iter().map(|item| item.res).filter_map(as_primitive).collect()
157+
}
158+
}
91159
}
92160

93161
/// Anything with a source location and set of attributes and, optionally, a

src/librustdoc/clean/utils.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
5757
let local_crate = LOCAL_CRATE.clean(cx);
5858
let src = local_crate.src(cx.tcx);
5959
let name = local_crate.name(cx.tcx);
60-
let ExternalCrate { primitives, keywords, .. } = local_crate;
60+
let primitives = local_crate.primitives(cx.tcx);
61+
let ExternalCrate { keywords, .. } = local_crate;
6162
{
6263
let m = match *module.kind {
6364
ItemKind::ModuleItem(ref mut m) => m,

src/librustdoc/formats/cache.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl Cache {
176176
// Favor linking to as local extern as possible, so iterate all crates in
177177
// reverse topological order.
178178
for &(_, ref e) in krate.externs.iter().rev() {
179-
for &(def_id, prim) in &e.primitives {
179+
for &(def_id, prim) in &e.primitives(tcx) {
180180
self.primitive_locations.insert(prim, def_id);
181181
}
182182
}

0 commit comments

Comments
 (0)