diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 32f3706675a..1a281a3a8bb 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -222,7 +222,8 @@ fn build_type(cx: &DocContext, tcx: &TyCtxt, did: DefId) -> clean::ItemEnum { }, false) } -pub fn build_impls(cx: &DocContext, tcx: &TyCtxt, +pub fn build_impls(cx: &DocContext, + tcx: &TyCtxt, did: DefId) -> Vec { tcx.populate_inherent_implementations_for_type_if_necessary(did); let mut impls = Vec::new(); @@ -241,10 +242,12 @@ pub fn build_impls(cx: &DocContext, tcx: &TyCtxt, // 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) { + if !cx.all_crate_impls.borrow_mut().contains_key(&did.krate) { + let mut impls = Vec::new(); for item in tcx.sess.cstore.crate_top_level_items(did.krate) { populate_impls(cx, tcx, item.def, &mut impls); } + cx.all_crate_impls.borrow_mut().insert(did.krate, impls); fn populate_impls(cx: &DocContext, tcx: &TyCtxt, def: cstore::DefLike, @@ -266,6 +269,20 @@ pub fn build_impls(cx: &DocContext, tcx: &TyCtxt, } } + let mut candidates = cx.all_crate_impls.borrow_mut(); + let candidates = candidates.get_mut(&did.krate).unwrap(); + for i in (0..candidates.len()).rev() { + let remove = match candidates[i].inner { + clean::ImplItem(ref i) => { + i.for_.def_id() == Some(did) || i.for_.primitive_type().is_some() + } + _ => continue, + }; + if remove { + impls.push(candidates.swap_remove(i)); + } + } + return impls; } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6c9ee528782..231829a8ed3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1499,6 +1499,13 @@ impl Type { _ => None, } } + + fn def_id(&self) -> Option { + match *self { + ResolvedPath { did, .. } => Some(did), + _ => None, + } + } } impl PrimitiveType { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 345b84e0cac..c889a5f87b0 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -56,7 +56,7 @@ pub struct DocContext<'a, 'tcx: 'a> { pub external_traits: RefCell>>, pub external_typarams: RefCell>>, pub inlined: RefCell>>, - pub populated_crate_impls: RefCell>, + pub all_crate_impls: RefCell>>, pub deref_trait_did: Cell>, } @@ -179,7 +179,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec, externs: Externs, 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()), + all_crate_impls: RefCell::new(HashMap::new()), deref_trait_did: Cell::new(None), }; debug!("crate: {:?}", ctxt.map.krate()); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index e97357f9889..8cb3653008a 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -11,7 +11,7 @@ #![allow(deprecated)] use std::cell::{RefCell, Cell}; -use std::collections::{HashSet, HashMap}; +use std::collections::HashMap; use std::dynamic_lib::DynamicLibrary; use std::env; use std::ffi::OsString; @@ -114,7 +114,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()), + all_crate_impls: RefCell::new(HashMap::new()), deref_trait_did: Cell::new(None), };