Skip to content

Commit 8c669d7

Browse files
committed
rustdoc: Suck in all impls from external crates
There is currently no way to query all impls for a type from an external crate, and with primitive types in play this is also quite difficult. Instead of filtering, just suck in all impls from upstream crates into the local AST, and have them get stripped later. This will allow population of all implementations of traits for primitive types, as well as filling in some corner cases with inlining documentation in other cases.
1 parent c2564b8 commit 8c669d7

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

src/librustdoc/clean/inline.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ fn try_inline_def(cx: &core::DocContext,
6767
}
6868
ast::DefStruct(did) => {
6969
record_extern_fqn(cx, did, clean::TypeStruct);
70-
ret.extend(build_impls(tcx, did).move_iter());
70+
ret.extend(build_impls(cx, tcx, did).move_iter());
7171
clean::StructItem(build_struct(tcx, did))
7272
}
7373
ast::DefTy(did) => {
7474
record_extern_fqn(cx, did, clean::TypeEnum);
75-
ret.extend(build_impls(tcx, did).move_iter());
75+
ret.extend(build_impls(cx, tcx, did).move_iter());
7676
build_type(tcx, did)
7777
}
7878
// Assume that the enum type is reexported next to the variant, and
@@ -193,7 +193,8 @@ fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
193193
})
194194
}
195195

196-
fn build_impls(tcx: &ty::ctxt,
196+
fn build_impls(cx: &core::DocContext,
197+
tcx: &ty::ctxt,
197198
did: ast::DefId) -> Vec<clean::Item> {
198199
ty::populate_implementations_for_type_if_necessary(tcx, did);
199200
let mut impls = Vec::new();
@@ -205,6 +206,38 @@ fn build_impls(tcx: &ty::ctxt,
205206
}
206207
}
207208

209+
// If this is the first time we've inlined something from this crate, then
210+
// we inline *all* impls from the crate into this crate. Note that there's
211+
// currently no way for us to filter this based on type, and we likely need
212+
// many impls for a variety of reasons.
213+
//
214+
// Primarily, the impls will be used to populate the documentation for this
215+
// type being inlined, but impls can also be used when generating
216+
// documentation for primitives (no way to find those specifically).
217+
if cx.populated_crate_impls.borrow_mut().insert(did.krate) {
218+
csearch::each_top_level_item_of_crate(&tcx.sess.cstore,
219+
did.krate,
220+
|def, _, _| {
221+
populate_impls(tcx, def, &mut impls)
222+
});
223+
224+
fn populate_impls(tcx: &ty::ctxt,
225+
def: decoder::DefLike,
226+
impls: &mut Vec<clean::Item>) {
227+
match def {
228+
decoder::DlImpl(did) => impls.push(build_impl(tcx, did)),
229+
decoder::DlDef(ast::DefMod(did)) => {
230+
csearch::each_child_of_item(&tcx.sess.cstore,
231+
did,
232+
|def, _, _| {
233+
populate_impls(tcx, def, impls)
234+
})
235+
}
236+
_ => {}
237+
}
238+
}
239+
}
240+
208241
impls
209242
}
210243

@@ -268,7 +301,8 @@ fn build_module(cx: &core::DocContext, tcx: &ty::ctxt,
268301
None => {}
269302
}
270303
}
271-
decoder::DlImpl(did) => items.push(build_impl(tcx, did)),
304+
// All impls were inlined above
305+
decoder::DlImpl(..) => {}
272306
decoder::DlField => fail!("unimplemented field"),
273307
}
274308
});

src/librustdoc/core.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub struct DocContext {
4242
pub external_traits: RefCell<Option<HashMap<ast::DefId, clean::Trait>>>,
4343
pub external_typarams: RefCell<Option<HashMap<ast::DefId, String>>>,
4444
pub inlined: RefCell<Option<HashSet<ast::DefId>>>,
45+
pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
4546
}
4647

4748
impl DocContext {
@@ -114,6 +115,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
114115
external_typarams: RefCell::new(Some(HashMap::new())),
115116
external_paths: RefCell::new(Some(HashMap::new())),
116117
inlined: RefCell::new(Some(HashSet::new())),
118+
populated_crate_impls: RefCell::new(HashSet::new()),
117119
}, CrateAnalysis {
118120
exported_items: exported_items,
119121
public_items: public_items,

src/librustdoc/test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub fn run(input: &str,
7979
external_traits: RefCell::new(None),
8080
external_typarams: RefCell::new(None),
8181
inlined: RefCell::new(None),
82+
populated_crate_impls: RefCell::new(HashSet::new()),
8283
};
8384
super::ctxtkey.replace(Some(ctx));
8485

0 commit comments

Comments
 (0)