]> git.lizzy.rs Git - rust.git/commitdiff
Fix the strip-hidden `ImplStripper`
authormitaa <mitaa.ceb@gmail.com>
Mon, 18 Apr 2016 15:32:00 +0000 (17:32 +0200)
committermitaa <mitaa.ceb@gmail.com>
Mon, 18 Apr 2016 15:32:00 +0000 (17:32 +0200)
Instead of stripping impls which reference *stripped* items, we keep impls
which reference *retained* items. We do this because when we strip an
item we immediately return, and do not recurse into it - leaving the
contained items non-stripped from the point of view of the `ImplStripper`.

src/librustdoc/passes.rs
src/test/rustdoc/issue-33069.rs [new file with mode: 0644]

index 0042afb1fd5147695274e7151c2c9265a5ff6587..15bb0f7592b01ee5898dfc8b1b11bcd66b9dd4e7 100644 (file)
 
 /// 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(..) => {
@@ -44,42 +42,19 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
                         }
                         _ => 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
@@ -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> {
@@ -204,13 +177,21 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
     }
 }
 
-// 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;
                 }
             }
diff --git a/src/test/rustdoc/issue-33069.rs b/src/test/rustdoc/issue-33069.rs
new file mode 100644 (file)
index 0000000..cd227fd
--- /dev/null
@@ -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 {}