diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index b962694fe6841..bf35c93caae42 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -10,6 +10,7 @@ use std::num; use std::uint; +use std::hashmap::HashSet; use syntax::ast; @@ -50,9 +51,10 @@ pub fn strip_hidden(crate: clean::Crate) -> plugins::PluginResult { /// Strip private items from the point of view of a crate or externally from a /// crate, specified by the `xcrate` flag. -pub fn strip_private(crate: clean::Crate) -> plugins::PluginResult { - struct Stripper; - impl fold::DocFolder for Stripper { +pub fn strip_private(mut crate: clean::Crate) -> plugins::PluginResult { + // This stripper collects all *retained* nodes. + struct Stripper<'self>(&'self mut HashSet); + impl<'self> fold::DocFolder for Stripper<'self> { fn fold_item(&mut self, i: Item) -> Option { match i.inner { // These items can all get re-exported @@ -98,6 +100,7 @@ pub fn strip_private(crate: clean::Crate) -> plugins::PluginResult { }; let i = if fastreturn { + self.insert(i.id); return Some(i); } else { self.fold_item_recur(i) @@ -109,15 +112,50 @@ pub fn strip_private(crate: clean::Crate) -> plugins::PluginResult { // emptied modules/impls have no need to exist clean::ModuleItem(ref m) if m.items.len() == 0 => None, clean::ImplItem(ref i) if i.methods.len() == 0 => None, - _ => Some(i), + _ => { + self.insert(i.id); + Some(i) + } } } None => None, } } } - let mut stripper = Stripper; - let crate = stripper.fold_crate(crate); + + // This stripper discards all private impls of traits + struct ImplStripper<'self>(&'self HashSet); + impl<'self> fold::DocFolder for ImplStripper<'self> { + fn fold_item(&mut self, i: Item) -> Option { + match i.inner { + clean::ImplItem(ref imp) => { + match imp.trait_ { + Some(clean::ResolvedPath{ id, _ }) => { + if !self.contains(&id) { + return None; + } + } + Some(*) | None => {} + } + } + _ => {} + } + self.fold_item_recur(i) + } + } + + let mut retained = HashSet::new(); + // First, strip all private items + { + let mut stripper = Stripper(&mut retained); + crate = stripper.fold_crate(crate); + } + + // Next, strip all private implementations of traits + { + let mut stripper = ImplStripper(&retained); + crate = stripper.fold_crate(crate); + } (crate, None) }