Skip to content

Commit 4766af1

Browse files
Dylan-DPCehuss
authored andcommitted
Rollup merge of #99344 - notriddle:notriddle/multiple-macro-rules-w-same-name, r=GuillaumeGomez
rustdoc: avoid inlining items with duplicate `(type, name)` Fixes #99221
1 parent e6e5bc7 commit 4766af1

5 files changed

+107
-5
lines changed

src/librustdoc/clean/mod.rs

+37-5
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,43 @@ impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> {
5757
.map(|(item, renamed)| clean_maybe_renamed_foreign_item(cx, item, *renamed)),
5858
);
5959
items.extend(self.mods.iter().map(|x| x.clean(cx)));
60-
items.extend(
61-
self.items
62-
.iter()
63-
.flat_map(|(item, renamed)| clean_maybe_renamed_item(cx, item, *renamed)),
64-
);
60+
61+
// Split up imports from all other items.
62+
//
63+
// This covers the case where somebody does an import which should pull in an item,
64+
// but there's already an item with the same namespace and same name. Rust gives
65+
// priority to the not-imported one, so we should, too.
66+
let mut inserted = FxHashSet::default();
67+
items.extend(self.items.iter().flat_map(|(item, renamed)| {
68+
// First, lower everything other than imports.
69+
if matches!(item.kind, hir::ItemKind::Use(..)) {
70+
return Vec::new();
71+
}
72+
let v = clean_maybe_renamed_item(cx, item, *renamed);
73+
for item in &v {
74+
if let Some(name) = item.name {
75+
inserted.insert((item.type_(), name));
76+
}
77+
}
78+
v
79+
}));
80+
items.extend(self.items.iter().flat_map(|(item, renamed)| {
81+
// Now we actually lower the imports, skipping everything else.
82+
if !matches!(item.kind, hir::ItemKind::Use(..)) {
83+
return Vec::new();
84+
}
85+
let mut v = clean_maybe_renamed_item(cx, item, *renamed);
86+
v.drain_filter(|item| {
87+
if let Some(name) = item.name {
88+
// If an item with the same type and name already exists,
89+
// it takes priority over the inlined stuff.
90+
!inserted.insert((item.type_(), name))
91+
} else {
92+
false
93+
}
94+
});
95+
v
96+
}));
6597

6698
// determine if we should display the inner contents or
6799
// the outer `mod` item for the source code.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
pub struct Option;
2+
impl Option {
3+
pub fn unwrap(self) {}
4+
}
5+
6+
mod macros {
7+
use crate::Option;
8+
/// [`Option::unwrap`]
9+
#[macro_export]
10+
macro_rules! print {
11+
() => ()
12+
}
13+
}
14+
15+
mod structs {
16+
use crate::Option;
17+
/// [`Option::unwrap`]
18+
pub struct Print;
19+
}
20+
pub use structs::Print;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// aux-build:issue-99221-aux.rs
2+
// build-aux-docs
3+
// ignore-cross-compile
4+
5+
#![crate_name = "foo"]
6+
7+
#[macro_use]
8+
extern crate issue_99221_aux;
9+
10+
pub use issue_99221_aux::*;
11+
12+
// @count foo/index.html '//a[@class="macro"]' 1
13+
14+
mod inner {
15+
#[macro_export]
16+
macro_rules! print {
17+
() => ()
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// aux-build:issue-99221-aux.rs
2+
// build-aux-docs
3+
// ignore-cross-compile
4+
5+
#![crate_name = "foo"]
6+
7+
#[macro_use]
8+
extern crate issue_99221_aux;
9+
10+
pub use issue_99221_aux::*;
11+
12+
// @count foo/index.html '//a[@class="macro"]' 1
13+
14+
#[macro_export]
15+
macro_rules! print {
16+
() => ()
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// aux-build:issue-99221-aux.rs
2+
// build-aux-docs
3+
// ignore-cross-compile
4+
5+
#![crate_name = "foo"]
6+
7+
#[macro_use]
8+
extern crate issue_99221_aux;
9+
10+
pub use issue_99221_aux::*;
11+
12+
// @count foo/index.html '//a[@class="struct"][@title="foo::Print struct"]' 1
13+
14+
pub struct Print;

0 commit comments

Comments
 (0)