Skip to content

Commit c491e19

Browse files
new attribute #[doc(masked)] to hide internal crates from std docs
1 parent 2f1ef9e commit c491e19

File tree

3 files changed

+76
-18
lines changed

3 files changed

+76
-18
lines changed

src/librustdoc/clean/mod.rs

+41
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ pub struct Crate {
117117
// These are later on moved into `CACHEKEY`, leaving the map empty.
118118
// Only here so that they can be filtered through the rustdoc passes.
119119
pub external_traits: FxHashMap<DefId, Trait>,
120+
pub masked_crates: FxHashSet<CrateNum>,
120121
}
121122

122123
impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
@@ -141,6 +142,18 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
141142
// Clean the crate, translating the entire libsyntax AST to one that is
142143
// understood by rustdoc.
143144
let mut module = self.module.clean(cx);
145+
let mut masked_crates = FxHashSet();
146+
147+
match module.inner {
148+
ModuleItem(ref module) => {
149+
for it in &module.items {
150+
if it.is_extern_crate() && it.attrs.has_doc_masked() {
151+
masked_crates.insert(it.def_id.krate);
152+
}
153+
}
154+
}
155+
_ => unreachable!(),
156+
}
144157

145158
let ExternalCrate { name, src, primitives, .. } = LOCAL_CRATE.clean(cx);
146159
{
@@ -173,6 +186,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
173186
primitives,
174187
access_levels: Arc::new(mem::replace(&mut access_levels, Default::default())),
175188
external_traits: mem::replace(&mut external_traits, Default::default()),
189+
masked_crates,
176190
}
177191
}
178192
}
@@ -326,6 +340,9 @@ impl Item {
326340
pub fn is_import(&self) -> bool {
327341
self.type_() == ItemType::Import
328342
}
343+
pub fn is_extern_crate(&self) -> bool {
344+
self.type_() == ItemType::ExternCrate
345+
}
329346

330347
pub fn is_stripped(&self) -> bool {
331348
match self.inner { StrippedItem(..) => true, _ => false }
@@ -571,6 +588,20 @@ impl Attributes {
571588
None
572589
}
573590

591+
pub fn has_doc_masked(&self) -> bool {
592+
for attr in &self.other_attrs {
593+
if !attr.check_name("doc") { continue; }
594+
595+
if let Some(items) = attr.meta_item_list() {
596+
if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name("masked")) {
597+
return true;
598+
}
599+
}
600+
}
601+
602+
false
603+
}
604+
574605
pub fn from_ast(diagnostic: &::errors::Handler, attrs: &[ast::Attribute]) -> Attributes {
575606
let mut doc_strings = vec![];
576607
let mut sp = None;
@@ -1651,6 +1682,16 @@ impl GetDefId for Type {
16511682
fn def_id(&self) -> Option<DefId> {
16521683
match *self {
16531684
ResolvedPath { did, .. } => Some(did),
1685+
Primitive(p) => ::html::render::cache().primitive_locations.get(&p).cloned(),
1686+
BorrowedRef { type_: box Generic(..), .. } =>
1687+
Primitive(PrimitiveType::Reference).def_id(),
1688+
BorrowedRef { ref type_, .. } => type_.def_id(),
1689+
Tuple(..) => Primitive(PrimitiveType::Tuple).def_id(),
1690+
BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(),
1691+
Slice(..) => Primitive(PrimitiveType::Slice).def_id(),
1692+
Array(..) => Primitive(PrimitiveType::Array).def_id(),
1693+
RawPointer(..) => Primitive(PrimitiveType::RawPointer).def_id(),
1694+
QPath { ref self_type, .. } => self_type.def_id(),
16541695
_ => None,
16551696
}
16561697
}

src/librustdoc/html/render.rs

+29-17
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ pub struct Cache {
268268
deref_trait_did: Option<DefId>,
269269
deref_mut_trait_did: Option<DefId>,
270270
owned_box_did: Option<DefId>,
271+
masked_crates: FxHashSet<CrateNum>,
271272

272273
// In rare case where a structure is defined in one module but implemented
273274
// in another, if the implementing module is parsed before defining module,
@@ -540,6 +541,7 @@ pub fn run(mut krate: clean::Crate,
540541
deref_trait_did,
541542
deref_mut_trait_did,
542543
owned_box_did,
544+
masked_crates: mem::replace(&mut krate.masked_crates, FxHashSet()),
543545
typarams: external_typarams,
544546
};
545547

@@ -1104,12 +1106,16 @@ impl DocFolder for Cache {
11041106

11051107
// Collect all the implementors of traits.
11061108
if let clean::ImplItem(ref i) = item.inner {
1107-
if let Some(did) = i.trait_.def_id() {
1108-
self.implementors.entry(did).or_insert(vec![]).push(Implementor {
1109-
def_id: item.def_id,
1110-
stability: item.stability.clone(),
1111-
impl_: i.clone(),
1112-
});
1109+
if !self.masked_crates.contains(&item.def_id.krate) {
1110+
if let Some(did) = i.trait_.def_id() {
1111+
if i.for_.def_id().map_or(true, |d| !self.masked_crates.contains(&d.krate)) {
1112+
self.implementors.entry(did).or_insert(vec![]).push(Implementor {
1113+
def_id: item.def_id,
1114+
stability: item.stability.clone(),
1115+
impl_: i.clone(),
1116+
});
1117+
}
1118+
}
11131119
}
11141120
}
11151121

@@ -1271,18 +1277,24 @@ impl DocFolder for Cache {
12711277
// primitive rather than always to a struct/enum.
12721278
// Note: matching twice to restrict the lifetime of the `i` borrow.
12731279
let did = if let clean::Item { inner: clean::ImplItem(ref i), .. } = item {
1274-
match i.for_ {
1275-
clean::ResolvedPath { did, .. } |
1276-
clean::BorrowedRef {
1277-
type_: box clean::ResolvedPath { did, .. }, ..
1278-
} => {
1279-
Some(did)
1280-
}
1281-
ref t => {
1282-
t.primitive_type().and_then(|t| {
1283-
self.primitive_locations.get(&t).cloned()
1284-
})
1280+
let masked_trait = i.trait_.def_id().map_or(false,
1281+
|d| self.masked_crates.contains(&d.krate));
1282+
if !masked_trait {
1283+
match i.for_ {
1284+
clean::ResolvedPath { did, .. } |
1285+
clean::BorrowedRef {
1286+
type_: box clean::ResolvedPath { did, .. }, ..
1287+
} => {
1288+
Some(did)
1289+
}
1290+
ref t => {
1291+
t.primitive_type().and_then(|t| {
1292+
self.primitive_locations.get(&t).cloned()
1293+
})
1294+
}
12851295
}
1296+
} else {
1297+
None
12861298
}
12871299
} else {
12881300
unreachable!()

src/libstd/lib.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -347,19 +347,24 @@ use prelude::v1::*;
347347
debug_assert_ne, unreachable, unimplemented, write, writeln, try)]
348348
extern crate core as __core;
349349

350-
#[allow(deprecated)] extern crate rand as core_rand;
350+
#[doc(masked)]
351+
#[allow(deprecated)]
352+
extern crate rand as core_rand;
351353
#[macro_use]
352354
#[macro_reexport(vec, format)]
353355
extern crate alloc;
354356
extern crate alloc_system;
355357
extern crate std_unicode;
358+
#[doc(masked)]
356359
extern crate libc;
357360

358361
// We always need an unwinder currently for backtraces
362+
#[doc(masked)]
359363
#[allow(unused_extern_crates)]
360364
extern crate unwind;
361365

362366
// compiler-rt intrinsics
367+
#[doc(masked)]
363368
extern crate compiler_builtins;
364369

365370
// During testing, this crate is not actually the "real" std library, but rather

0 commit comments

Comments
 (0)