diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index aab44ddce0e6a..c092c66ad1650 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -117,6 +117,7 @@ pub struct Crate { // These are later on moved into `CACHEKEY`, leaving the map empty. // Only here so that they can be filtered through the rustdoc passes. pub external_traits: FxHashMap, + pub masked_crates: FxHashSet, } impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { @@ -141,6 +142,18 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { // Clean the crate, translating the entire libsyntax AST to one that is // understood by rustdoc. let mut module = self.module.clean(cx); + let mut masked_crates = FxHashSet(); + + match module.inner { + ModuleItem(ref module) => { + for it in &module.items { + if it.is_extern_crate() && it.attrs.has_doc_masked() { + masked_crates.insert(it.def_id.krate); + } + } + } + _ => unreachable!(), + } let ExternalCrate { name, src, primitives, .. } = LOCAL_CRATE.clean(cx); { @@ -173,6 +186,7 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { primitives, access_levels: Arc::new(mem::replace(&mut access_levels, Default::default())), external_traits: mem::replace(&mut external_traits, Default::default()), + masked_crates, } } } @@ -326,6 +340,9 @@ impl Item { pub fn is_import(&self) -> bool { self.type_() == ItemType::Import } + pub fn is_extern_crate(&self) -> bool { + self.type_() == ItemType::ExternCrate + } pub fn is_stripped(&self) -> bool { match self.inner { StrippedItem(..) => true, _ => false } @@ -571,6 +588,20 @@ impl Attributes { None } + pub fn has_doc_masked(&self) -> bool { + for attr in &self.other_attrs { + if !attr.check_name("doc") { continue; } + + if let Some(items) = attr.meta_item_list() { + if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name("masked")) { + return true; + } + } + } + + false + } + pub fn from_ast(diagnostic: &::errors::Handler, attrs: &[ast::Attribute]) -> Attributes { let mut doc_strings = vec![]; let mut sp = None; @@ -1651,6 +1682,16 @@ impl GetDefId for Type { fn def_id(&self) -> Option { match *self { ResolvedPath { did, .. } => Some(did), + Primitive(p) => ::html::render::cache().primitive_locations.get(&p).cloned(), + BorrowedRef { type_: box Generic(..), .. } => + Primitive(PrimitiveType::Reference).def_id(), + BorrowedRef { ref type_, .. } => type_.def_id(), + Tuple(..) => Primitive(PrimitiveType::Tuple).def_id(), + BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(), + Slice(..) => Primitive(PrimitiveType::Slice).def_id(), + Array(..) => Primitive(PrimitiveType::Array).def_id(), + RawPointer(..) => Primitive(PrimitiveType::RawPointer).def_id(), + QPath { ref self_type, .. } => self_type.def_id(), _ => None, } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index cc84e340c74f8..75e922d08c804 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -268,6 +268,7 @@ pub struct Cache { deref_trait_did: Option, deref_mut_trait_did: Option, owned_box_did: Option, + masked_crates: FxHashSet, // In rare case where a structure is defined in one module but implemented // in another, if the implementing module is parsed before defining module, @@ -540,6 +541,7 @@ pub fn run(mut krate: clean::Crate, deref_trait_did, deref_mut_trait_did, owned_box_did, + masked_crates: mem::replace(&mut krate.masked_crates, FxHashSet()), typarams: external_typarams, }; @@ -1104,12 +1106,16 @@ impl DocFolder for Cache { // Collect all the implementors of traits. if let clean::ImplItem(ref i) = item.inner { - if let Some(did) = i.trait_.def_id() { - self.implementors.entry(did).or_insert(vec![]).push(Implementor { - def_id: item.def_id, - stability: item.stability.clone(), - impl_: i.clone(), - }); + if !self.masked_crates.contains(&item.def_id.krate) { + if let Some(did) = i.trait_.def_id() { + if i.for_.def_id().map_or(true, |d| !self.masked_crates.contains(&d.krate)) { + self.implementors.entry(did).or_insert(vec![]).push(Implementor { + def_id: item.def_id, + stability: item.stability.clone(), + impl_: i.clone(), + }); + } + } } } @@ -1271,18 +1277,24 @@ impl DocFolder for Cache { // primitive rather than always to a struct/enum. // Note: matching twice to restrict the lifetime of the `i` borrow. let did = if let clean::Item { inner: clean::ImplItem(ref i), .. } = item { - match i.for_ { - clean::ResolvedPath { did, .. } | - clean::BorrowedRef { - type_: box clean::ResolvedPath { did, .. }, .. - } => { - Some(did) - } - ref t => { - t.primitive_type().and_then(|t| { - self.primitive_locations.get(&t).cloned() - }) + let masked_trait = i.trait_.def_id().map_or(false, + |d| self.masked_crates.contains(&d.krate)); + if !masked_trait { + match i.for_ { + clean::ResolvedPath { did, .. } | + clean::BorrowedRef { + type_: box clean::ResolvedPath { did, .. }, .. + } => { + Some(did) + } + ref t => { + t.primitive_type().and_then(|t| { + self.primitive_locations.get(&t).cloned() + }) + } } + } else { + None } } else { unreachable!() diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 33bf0d68126d4..6fa4a8738ac7b 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -347,19 +347,24 @@ use prelude::v1::*; debug_assert_ne, unreachable, unimplemented, write, writeln, try)] extern crate core as __core; -#[allow(deprecated)] extern crate rand as core_rand; +#[doc(masked)] +#[allow(deprecated)] +extern crate rand as core_rand; #[macro_use] #[macro_reexport(vec, format)] extern crate alloc; extern crate alloc_system; extern crate std_unicode; +#[doc(masked)] extern crate libc; // We always need an unwinder currently for backtraces +#[doc(masked)] #[allow(unused_extern_crates)] extern crate unwind; // compiler-rt intrinsics +#[doc(masked)] extern crate compiler_builtins; // During testing, this crate is not actually the "real" std library, but rather