about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCorey Farwell <coreyf@rwell.org>2017-08-26 06:46:32 -0700
committerGitHub <noreply@github.com>2017-08-26 06:46:32 -0700
commite9a6dccce0351b6484f25dcf5ee7dd6a71fbea7a (patch)
tree3d0e878b2ca07c72b84e9779f5139028c4bacc0a
parent1412ff5512f3642feb2a2f363d92f4a4416dfcb2 (diff)
parent5d71280c64e92c8526b6933c591456377acd8dc7 (diff)
downloadrust-e9a6dccce0351b6484f25dcf5ee7dd6a71fbea7a.tar.gz
rust-e9a6dccce0351b6484f25dcf5ee7dd6a71fbea7a.zip
Rollup merge of #43966 - GuillaumeGomez:remove-dup, r=QuietMisdreavus
Remove duplicates in rustdoc

Fixes #43934.

Two things however:

 1. I'm not happy with the current check. It seems completely overkill and unsatisfying.
 2. I have no idea how to test if there is only one element and not two.

r? @rust-lang/docs
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/html/render.rs31
-rw-r--r--src/test/rustdoc/remove-duplicates.rs24
3 files changed, 59 insertions, 0 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 92b3180c5cb..7d6ad5286d1 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -323,6 +323,10 @@ impl Item {
     pub fn is_union(&self) -> bool {
         self.type_() == ItemType::Union
     }
+    pub fn is_import(&self) -> bool {
+        self.type_() == ItemType::Import
+    }
+
     pub fn is_stripped(&self) -> bool {
         match self.inner { StrippedItem(..) => true, _ => false }
     }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 6593d6dfd6c..e113165b9ab 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1764,6 +1764,37 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
     }
 
     indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
+    // This call is to remove reexport duplicates in cases such as:
+    //
+    // ```
+    // pub mod foo {
+    //     pub mod bar {
+    //         pub trait Double { fn foo(); }
+    //     }
+    // }
+    //
+    // pub use foo::bar::*;
+    // pub use foo::*;
+    // ```
+    //
+    // `Double` will appear twice in the generated docs.
+    //
+    // FIXME: This code is quite ugly and could be improved. Small issue: DefId
+    // can be identical even if the elements are different (mostly in imports).
+    // So in case this is an import, we keep everything by adding a "unique id"
+    // (which is the position in the vector).
+    indices.dedup_by_key(|i| (items[*i].def_id,
+                              if items[*i].name.as_ref().is_some() {
+                                  Some(full_path(cx, &items[*i]).clone())
+                              } else {
+                                  None
+                              },
+                              items[*i].type_(),
+                              if items[*i].is_import() {
+                                  *i
+                              } else {
+                                  0
+                              }));
 
     debug!("{:?}", indices);
     let mut curty = None;
diff --git a/src/test/rustdoc/remove-duplicates.rs b/src/test/rustdoc/remove-duplicates.rs
new file mode 100644
index 00000000000..6c4f6d0700a
--- /dev/null
+++ b/src/test/rustdoc/remove-duplicates.rs
@@ -0,0 +1,24 @@
+// 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.
+
+#![crate_name = "foo"]
+
+mod foo {
+    pub use bar::*;
+    pub mod bar {
+        pub trait Foo {
+            fn foo();
+        }
+    }
+}
+
+// @count foo/index.html '//*[@class="trait"]' 1
+pub use foo::bar::*;
+pub use foo::*;