Skip to content

rustdoc: Fix the strip-hidden ImplStripper #33074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 22 additions & 41 deletions src/librustdoc/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,62 +24,37 @@ use fold::FoldItem::Strip;

/// Strip items marked `#[doc(hidden)]`
pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
let mut stripped = DefIdSet();
let mut retained = DefIdSet();

// strip all #[doc(hidden)] items
let krate = {
struct Stripper<'a> {
stripped: &'a mut DefIdSet
retained: &'a mut DefIdSet
}
impl<'a> fold::DocFolder for Stripper<'a> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
if i.attrs.list("doc").has_word("hidden") {
debug!("found one in strip_hidden; removing");
self.stripped.insert(i.def_id);

// use a dedicated hidden item for given item type if any
match i.inner {
clean::StructFieldItem(..) | clean::ModuleItem(..) => {
return Strip(i).fold()
}
_ => return None,
}
} else {
self.retained.insert(i.def_id);
}
self.fold_item_recur(i)
}
}
let mut stripper = Stripper{ stripped: &mut stripped };
let mut stripper = Stripper{ retained: &mut retained };
stripper.fold_crate(krate)
};

// strip any traits implemented on stripped items
{
struct ImplStripper<'a> {
stripped: &'a mut DefIdSet
}
impl<'a> fold::DocFolder for ImplStripper<'a> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
if let clean::ImplItem(clean::Impl{
for_: clean::ResolvedPath{ did, .. },
ref trait_, ..
}) = i.inner {
// Impls for stripped types don't need to exist
if self.stripped.contains(&did) {
return None;
}
// Impls of stripped traits also don't need to exist
if let Some(did) = trait_.def_id() {
if self.stripped.contains(&did) {
return None;
}
}
}
self.fold_item_recur(i)
}
}
let mut stripper = ImplStripper{ stripped: &mut stripped };
stripper.fold_crate(krate)
}
// strip all impls referencing stripped items
let mut stripper = ImplStripper { retained: &retained };
stripper.fold_crate(krate)
}

/// Strip private items from the point of view of a crate or externally from a
Expand All @@ -101,11 +76,9 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
krate = ImportStripper.fold_crate(stripper.fold_crate(krate));
}

// strip all private implementations of traits
{
let mut stripper = ImplStripper(&retained);
stripper.fold_crate(krate)
}
// strip all impls referencing private items
let mut stripper = ImplStripper { retained: &retained };
stripper.fold_crate(krate)
}

struct Stripper<'a> {
Expand Down Expand Up @@ -204,13 +177,21 @@ impl<'a> fold::DocFolder for Stripper<'a> {
}
}

// This stripper discards all private impls of traits
struct ImplStripper<'a>(&'a DefIdSet);
// This stripper discards all impls which reference stripped items
struct ImplStripper<'a> {
retained: &'a DefIdSet
}

impl<'a> fold::DocFolder for ImplStripper<'a> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
if let clean::ImplItem(ref imp) = i.inner {
if let Some(did) = imp.for_.def_id() {
if did.is_local() && !self.retained.contains(&did) {
return None;
}
}
if let Some(did) = imp.trait_.def_id() {
if did.is_local() && !self.0.contains(&did) {
if did.is_local() && !self.retained.contains(&did) {
return None;
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/test/rustdoc/issue-33069.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub trait Bar {}

#[doc(hidden)]
pub mod hidden {
pub struct Foo;
}

// @has issue_33069/trait.Bar.html
// @!has - '//code' 'impl Bar for Foo'
impl Bar for hidden::Foo {}