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 or the MIT license +// , 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::*;