Rollup merge of #101631 - rust-lang:notriddle/duplicate-module, r=GuillaumeGomez
rustdoc: avoid cleaning modules with duplicate names Fixes #83375
This commit is contained in:
commit
6afbe3eca9
6 changed files with 164 additions and 5 deletions
|
@ -50,14 +50,23 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
|
||||||
let mut inserted = FxHashSet::default();
|
let mut inserted = FxHashSet::default();
|
||||||
items.extend(doc.foreigns.iter().map(|(item, renamed)| {
|
items.extend(doc.foreigns.iter().map(|(item, renamed)| {
|
||||||
let item = clean_maybe_renamed_foreign_item(cx, item, *renamed);
|
let item = clean_maybe_renamed_foreign_item(cx, item, *renamed);
|
||||||
if let Some(name) = item.name {
|
if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
|
||||||
inserted.insert((item.type_(), name));
|
inserted.insert((item.type_(), name));
|
||||||
}
|
}
|
||||||
item
|
item
|
||||||
}));
|
}));
|
||||||
items.extend(doc.mods.iter().map(|x| {
|
items.extend(doc.mods.iter().filter_map(|x| {
|
||||||
inserted.insert((ItemType::Module, x.name));
|
if !inserted.insert((ItemType::Module, x.name)) {
|
||||||
clean_doc_module(x, cx)
|
return None;
|
||||||
|
}
|
||||||
|
let item = clean_doc_module(x, cx);
|
||||||
|
if item.attrs.lists(sym::doc).has_word(sym::hidden) {
|
||||||
|
// Hidden modules are stripped at a later stage.
|
||||||
|
// If a hidden module has the same name as a visible one, we want
|
||||||
|
// to keep both of them around.
|
||||||
|
inserted.remove(&(ItemType::Module, x.name));
|
||||||
|
}
|
||||||
|
Some(item)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Split up imports from all other items.
|
// Split up imports from all other items.
|
||||||
|
@ -72,7 +81,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
|
||||||
}
|
}
|
||||||
let v = clean_maybe_renamed_item(cx, item, *renamed);
|
let v = clean_maybe_renamed_item(cx, item, *renamed);
|
||||||
for item in &v {
|
for item in &v {
|
||||||
if let Some(name) = item.name {
|
if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
|
||||||
inserted.insert((item.type_(), name));
|
inserted.insert((item.type_(), name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,8 +164,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
self.inside_public_path &= self.cx.tcx.visibility(def_id).is_public();
|
self.inside_public_path &= self.cx.tcx.visibility(def_id).is_public();
|
||||||
for &i in m.item_ids {
|
for &i in m.item_ids {
|
||||||
let item = self.cx.tcx.hir().item(i);
|
let item = self.cx.tcx.hir().item(i);
|
||||||
|
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
self.visit_item(item, None, &mut om);
|
self.visit_item(item, None, &mut om);
|
||||||
}
|
}
|
||||||
|
for &i in m.item_ids {
|
||||||
|
let item = self.cx.tcx.hir().item(i);
|
||||||
|
// To match the way import precedence works, visit glob imports last.
|
||||||
|
// Later passes in rustdoc will de-duplicate by name and kind, so if glob-
|
||||||
|
// imported items appear last, then they'll be the ones that get discarded.
|
||||||
|
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
|
||||||
|
self.visit_item(item, None, &mut om);
|
||||||
|
}
|
||||||
|
}
|
||||||
self.inside_public_path = orig_inside_public_path;
|
self.inside_public_path = orig_inside_public_path;
|
||||||
om
|
om
|
||||||
}
|
}
|
||||||
|
|
20
src/test/rustdoc/glob-shadowing-const.rs
Normal file
20
src/test/rustdoc/glob-shadowing-const.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// https://github.com/rust-lang/rust/pull/83872#issuecomment-820101008
|
||||||
|
#![crate_name="foo"]
|
||||||
|
|
||||||
|
mod sub4 {
|
||||||
|
/// 0
|
||||||
|
pub const X: usize = 0;
|
||||||
|
pub mod inner {
|
||||||
|
pub use super::*;
|
||||||
|
/// 1
|
||||||
|
pub const X: usize = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use sub4::inner::*;
|
||||||
|
|
||||||
|
// @has 'foo/index.html'
|
||||||
|
// @has - '//div[@class="item-right docblock-short"]' '1'
|
||||||
|
// @!has - '//div[@class="item-right docblock-short"]' '0'
|
||||||
|
fn main() { assert_eq!(X, 1); }
|
86
src/test/rustdoc/glob-shadowing.rs
Normal file
86
src/test/rustdoc/glob-shadowing.rs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// @has 'glob_shadowing/index.html'
|
||||||
|
// @count - '//div[@class="item-left module-item"]' 6
|
||||||
|
// @!has - '//div[@class="item-right docblock-short"]' 'sub1::describe'
|
||||||
|
// @has - '//div[@class="item-right docblock-short"]' 'sub2::describe'
|
||||||
|
|
||||||
|
// @!has - '//div[@class="item-right docblock-short"]' 'sub1::describe2'
|
||||||
|
|
||||||
|
// @!has - '//div[@class="item-right docblock-short"]' 'sub1::prelude'
|
||||||
|
// @has - '//div[@class="item-right docblock-short"]' 'mod::prelude'
|
||||||
|
|
||||||
|
// @has - '//div[@class="item-right docblock-short"]' 'sub1::Foo (struct)'
|
||||||
|
// @has - '//div[@class="item-right docblock-short"]' 'mod::Foo (function)'
|
||||||
|
|
||||||
|
// @has - '//div[@class="item-right docblock-short"]' 'sub4::inner::X'
|
||||||
|
|
||||||
|
// @has 'glob_shadowing/fn.describe.html'
|
||||||
|
// @has - '//div[@class="docblock"]' 'sub2::describe'
|
||||||
|
|
||||||
|
mod sub1 {
|
||||||
|
// this should be shadowed by sub2::describe
|
||||||
|
/// sub1::describe
|
||||||
|
pub fn describe() -> &'static str {
|
||||||
|
"sub1::describe"
|
||||||
|
}
|
||||||
|
|
||||||
|
// this should be shadowed by mod::prelude
|
||||||
|
/// sub1::prelude
|
||||||
|
pub mod prelude {
|
||||||
|
}
|
||||||
|
|
||||||
|
// this should *not* be shadowed, because sub1::Foo and mod::Foo are in different namespaces
|
||||||
|
/// sub1::Foo (struct)
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
|
// this should be shadowed,
|
||||||
|
// because both sub1::describe2 and sub3::describe2 are from glob reexport
|
||||||
|
/// sub1::describe2
|
||||||
|
pub fn describe2() -> &'static str {
|
||||||
|
"sub1::describe2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod sub2 {
|
||||||
|
/// sub2::describe
|
||||||
|
pub fn describe() -> &'static str {
|
||||||
|
"sub2::describe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod sub3 {
|
||||||
|
// this should be shadowed
|
||||||
|
// because both sub1::describe2 and sub3::describe2 are from glob reexport
|
||||||
|
/// sub3::describe2
|
||||||
|
pub fn describe2() -> &'static str {
|
||||||
|
"sub3::describe2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod sub4 {
|
||||||
|
// this should be shadowed by sub4::inner::X
|
||||||
|
/// sub4::X
|
||||||
|
pub const X: usize = 0;
|
||||||
|
pub mod inner {
|
||||||
|
pub use super::*;
|
||||||
|
/// sub4::inner::X
|
||||||
|
pub const X: usize = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// mod::Foo (function)
|
||||||
|
pub fn Foo() {}
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use sub2::describe;
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use sub1::*;
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use sub3::*;
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use sub4::inner::*;
|
||||||
|
|
||||||
|
/// mod::prelude
|
||||||
|
pub mod prelude {}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
pub mod sub {
|
||||||
|
pub struct Item;
|
||||||
|
|
||||||
|
pub mod prelude {
|
||||||
|
pub use super::Item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use sub::*;
|
||||||
|
|
||||||
|
// @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1
|
||||||
|
// @count foo/prelude/index.html '//div[@class="item-row"]' 0
|
||||||
|
pub mod prelude {}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
pub mod sub {
|
||||||
|
pub struct Item;
|
||||||
|
|
||||||
|
pub mod prelude {
|
||||||
|
pub use super::Item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @count foo/index.html '//a[@class="mod"][@title="foo::prelude mod"]' 1
|
||||||
|
// @count foo/prelude/index.html '//div[@class="item-row"]' 0
|
||||||
|
pub mod prelude {}
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use sub::*;
|
Loading…
Add table
Add a link
Reference in a new issue