Skip to content

Commit 8100884

Browse files
committed
take namespace into consideration when doing shadowing
Signed-off-by: longfangsong <[email protected]>
1 parent 6ad7e7e commit 8100884

File tree

3 files changed

+51
-19
lines changed

3 files changed

+51
-19
lines changed

src/librustdoc/doctree.rs

+25-15
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ crate struct Item<'hir> {
1111
crate hir_item: &'hir hir::Item<'hir>,
1212
/// the explicit renamed name
1313
crate renamed_name: Option<Symbol>,
14+
/// the [`Namespace`] this Item belongs to
15+
crate namespace: Option<hir::def::Namespace>,
1416
/// whether the item is from a glob import
15-
/// if `from_glob` is true and we see another item with same name,
17+
/// if `from_glob` is true and we see another item with same name and namespace,
1618
/// then this item can be replaced with that one
1719
crate from_glob: bool,
1820
}
@@ -21,9 +23,10 @@ impl<'hir> Item<'hir> {
2123
pub(crate) fn new(
2224
hir_item: &'hir hir::Item<'hir>,
2325
renamed_name: Option<Symbol>,
26+
namespace: Option<hir::def::Namespace>,
2427
from_glob: bool,
2528
) -> Self {
26-
Self { hir_item, renamed_name, from_glob }
29+
Self { hir_item, renamed_name, namespace, from_glob }
2730
}
2831

2932
pub(crate) fn name(&self) -> Symbol {
@@ -43,7 +46,7 @@ crate struct Module<'hir> {
4346
crate is_crate: bool,
4447
/// whether the module is from a glob import
4548
/// if `from_glob` is true and we see another module with same name,
46-
/// then this item can be replaced with that one
49+
/// then this module can be replaced with that one
4750
crate from_glob: bool,
4851
}
4952

@@ -64,25 +67,29 @@ impl Module<'hir> {
6467
}
6568

6669
pub(crate) fn push_item(&mut self, new_item: Item<'hir>) {
67-
if !new_item.name().is_empty() {
68-
// todo: also check namespace
69-
if let Some(existing_item) =
70-
self.items.iter_mut().find(|item| item.name() == new_item.name())
70+
if !new_item.name().is_empty() && new_item.namespace.is_some() {
71+
if let Some(existing_item) = self
72+
.items
73+
.iter_mut()
74+
.find(|item| item.name() == new_item.name() && item.namespace == new_item.namespace)
7175
{
7276
match (existing_item.from_glob, new_item.from_glob) {
7377
(true, _) => {
74-
// `existing_item` is from glob, no matter whether `new_item` is from glob
78+
// `existing_item` is from glob, no matter whether `new_item` is from glob,
7579
// `new_item` should always shadow `existing_item`
7680
debug!("push_item: {:?} shadowed by {:?}", existing_item, new_item);
7781
*existing_item = new_item;
7882
return;
7983
}
8084
(false, true) => {
81-
// `existing_item` is not from glob but `new_item` is
85+
// `existing_item` is not from glob but `new_item` is,
8286
// just keep `existing_item` and return at once
8387
return;
8488
}
85-
(false, false) => unreachable!() // todo: how to handle this?
89+
(false, false) => {
90+
// should report "defined multiple time" error before reach this
91+
unreachable!()
92+
}
8693
}
8794
}
8895
}
@@ -94,18 +101,21 @@ impl Module<'hir> {
94101
if let Some(existing_mod) = self.mods.iter_mut().find(|mod_| mod_.name == new_mod.name) {
95102
match (existing_mod.from_glob, new_mod.from_glob) {
96103
(true, _) => {
97-
// `existing_mod` is from glob, no matter whether `new_mod` is from glob
104+
// `existing_mod` is from glob, no matter whether `new_mod` is from glob,
98105
// `new_mod` should always shadow `existing_mod`
99106
debug!("push_mod: {:?} shadowed by {:?}", existing_mod.name, new_mod.name);
100107
*existing_mod = new_mod;
101108
return;
102-
},
109+
}
103110
(false, true) => {
104-
// `existing_mod` is not from glob but `new_mod` is
111+
// `existing_mod` is not from glob but `new_mod` is,
105112
// just keep `existing_mod` and return at once
106113
return;
107-
},
108-
(false, false) => unreachable!(),
114+
}
115+
(false, false) => {
116+
// should report "defined multiple time" error before reach this
117+
unreachable!()
118+
}
109119
}
110120
}
111121
// no mod with same name exists, just collect `new_mod`

src/librustdoc/visit_ast.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
313313
}
314314
}
315315

316-
om.push_item(Item::new(item, renamed, from_glob))
316+
om.push_item(Item::new(
317+
item,
318+
renamed,
319+
self.cx.tcx.def_kind(item.def_id).ns(),
320+
from_glob,
321+
))
317322
}
318323
hir::ItemKind::Mod(ref m) => {
319324
om.push_mod(self.visit_mod_contents(
@@ -334,19 +339,34 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
334339
| hir::ItemKind::OpaqueTy(..)
335340
| hir::ItemKind::Static(..)
336341
| hir::ItemKind::Trait(..)
337-
| hir::ItemKind::TraitAlias(..) => om.push_item(Item::new(item, renamed, from_glob)),
342+
| hir::ItemKind::TraitAlias(..) => om.push_item(Item::new(
343+
item,
344+
renamed,
345+
self.cx.tcx.def_kind(item.def_id).ns(),
346+
from_glob,
347+
)),
338348
hir::ItemKind::Const(..) => {
339349
// Underscore constants do not correspond to a nameable item and
340350
// so are never useful in documentation.
341351
if name != kw::Underscore {
342-
om.push_item(Item::new(item, renamed, from_glob));
352+
om.push_item(Item::new(
353+
item,
354+
renamed,
355+
self.cx.tcx.def_kind(item.def_id).ns(),
356+
from_glob,
357+
));
343358
}
344359
}
345360
hir::ItemKind::Impl(ref impl_) => {
346361
// Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
347362
// them up regardless of where they're located.
348363
if !self.inlining && impl_.of_trait.is_none() {
349-
om.push_item(Item::new(item, None, from_glob));
364+
om.push_item(Item::new(
365+
item,
366+
None,
367+
self.cx.tcx.def_kind(item.def_id).ns(),
368+
from_glob,
369+
));
350370
}
351371
}
352372
}

src/test/rustdoc/glob-shadowing.rs

+2
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,5 @@ pub use sub2::describe;
4040

4141
#[doc(inline)]
4242
pub use sub1::*;
43+
44+
pub fn describe() {}

0 commit comments

Comments
 (0)