提交 8c669d7f 编写于 作者: A Alex Crichton

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.
上级 c2564b8f
......@@ -67,12 +67,12 @@ fn try_inline_def(cx: &core::DocContext,
}
ast::DefStruct(did) => {
record_extern_fqn(cx, did, clean::TypeStruct);
ret.extend(build_impls(tcx, did).move_iter());
ret.extend(build_impls(cx, tcx, did).move_iter());
clean::StructItem(build_struct(tcx, did))
}
ast::DefTy(did) => {
record_extern_fqn(cx, did, clean::TypeEnum);
ret.extend(build_impls(tcx, did).move_iter());
ret.extend(build_impls(cx, tcx, did).move_iter());
build_type(tcx, did)
}
// 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 {
})
}
fn build_impls(tcx: &ty::ctxt,
fn build_impls(cx: &core::DocContext,
tcx: &ty::ctxt,
did: ast::DefId) -> Vec<clean::Item> {
ty::populate_implementations_for_type_if_necessary(tcx, did);
let mut impls = Vec::new();
......@@ -205,6 +206,38 @@ fn build_impls(tcx: &ty::ctxt,
}
}
// If this is the first time we've inlined something from this crate, then
// we inline *all* impls from the crate into this crate. Note that there's
// currently no way for us to filter this based on type, and we likely need
// many impls for a variety of reasons.
//
// Primarily, the impls will be used to populate the documentation for this
// type being inlined, but impls can also be used when generating
// documentation for primitives (no way to find those specifically).
if cx.populated_crate_impls.borrow_mut().insert(did.krate) {
csearch::each_top_level_item_of_crate(&tcx.sess.cstore,
did.krate,
|def, _, _| {
populate_impls(tcx, def, &mut impls)
});
fn populate_impls(tcx: &ty::ctxt,
def: decoder::DefLike,
impls: &mut Vec<clean::Item>) {
match def {
decoder::DlImpl(did) => impls.push(build_impl(tcx, did)),
decoder::DlDef(ast::DefMod(did)) => {
csearch::each_child_of_item(&tcx.sess.cstore,
did,
|def, _, _| {
populate_impls(tcx, def, impls)
})
}
_ => {}
}
}
}
impls
}
......@@ -268,7 +301,8 @@ fn build_module(cx: &core::DocContext, tcx: &ty::ctxt,
None => {}
}
}
decoder::DlImpl(did) => items.push(build_impl(tcx, did)),
// All impls were inlined above
decoder::DlImpl(..) => {}
decoder::DlField => fail!("unimplemented field"),
}
});
......
......@@ -42,6 +42,7 @@ pub struct DocContext {
pub external_traits: RefCell<Option<HashMap<ast::DefId, clean::Trait>>>,
pub external_typarams: RefCell<Option<HashMap<ast::DefId, String>>>,
pub inlined: RefCell<Option<HashSet<ast::DefId>>>,
pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
}
impl DocContext {
......@@ -114,6 +115,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
external_typarams: RefCell::new(Some(HashMap::new())),
external_paths: RefCell::new(Some(HashMap::new())),
inlined: RefCell::new(Some(HashSet::new())),
populated_crate_impls: RefCell::new(HashSet::new()),
}, CrateAnalysis {
exported_items: exported_items,
public_items: public_items,
......
......@@ -79,6 +79,7 @@ pub fn run(input: &str,
external_traits: RefCell::new(None),
external_typarams: RefCell::new(None),
inlined: RefCell::new(None),
populated_crate_impls: RefCell::new(HashSet::new()),
};
super::ctxtkey.replace(Some(ctx));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册