@@ -11,8 +11,10 @@ crate struct Item<'hir> {
11
11
crate hir_item : & ' hir hir:: Item < ' hir > ,
12
12
/// the explicit renamed name
13
13
crate renamed_name : Option < Symbol > ,
14
+ /// the [`Namespace`] this Item belongs to
15
+ crate namespace : Option < hir:: def:: Namespace > ,
14
16
/// 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 ,
16
18
/// then this item can be replaced with that one
17
19
crate from_glob : bool ,
18
20
}
@@ -21,9 +23,10 @@ impl<'hir> Item<'hir> {
21
23
pub ( crate ) fn new (
22
24
hir_item : & ' hir hir:: Item < ' hir > ,
23
25
renamed_name : Option < Symbol > ,
26
+ namespace : Option < hir:: def:: Namespace > ,
24
27
from_glob : bool ,
25
28
) -> Self {
26
- Self { hir_item, renamed_name, from_glob }
29
+ Self { hir_item, renamed_name, namespace , from_glob }
27
30
}
28
31
29
32
pub ( crate ) fn name ( & self ) -> Symbol {
@@ -43,7 +46,7 @@ crate struct Module<'hir> {
43
46
crate is_crate : bool ,
44
47
/// whether the module is from a glob import
45
48
/// 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
47
50
crate from_glob : bool ,
48
51
}
49
52
@@ -64,25 +67,29 @@ impl Module<'hir> {
64
67
}
65
68
66
69
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 )
71
75
{
72
76
match ( existing_item. from_glob , new_item. from_glob ) {
73
77
( 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,
75
79
// `new_item` should always shadow `existing_item`
76
80
debug ! ( "push_item: {:?} shadowed by {:?}" , existing_item, new_item) ;
77
81
* existing_item = new_item;
78
82
return ;
79
83
}
80
84
( false , true ) => {
81
- // `existing_item` is not from glob but `new_item` is
85
+ // `existing_item` is not from glob but `new_item` is,
82
86
// just keep `existing_item` and return at once
83
87
return ;
84
88
}
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
+ }
86
93
}
87
94
}
88
95
}
@@ -94,18 +101,21 @@ impl Module<'hir> {
94
101
if let Some ( existing_mod) = self . mods . iter_mut ( ) . find ( |mod_| mod_. name == new_mod. name ) {
95
102
match ( existing_mod. from_glob , new_mod. from_glob ) {
96
103
( 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,
98
105
// `new_mod` should always shadow `existing_mod`
99
106
debug ! ( "push_mod: {:?} shadowed by {:?}" , existing_mod. name, new_mod. name) ;
100
107
* existing_mod = new_mod;
101
108
return ;
102
- } ,
109
+ }
103
110
( false , true ) => {
104
- // `existing_mod` is not from glob but `new_mod` is
111
+ // `existing_mod` is not from glob but `new_mod` is,
105
112
// just keep `existing_mod` and return at once
106
113
return ;
107
- } ,
108
- ( false , false ) => unreachable ! ( ) ,
114
+ }
115
+ ( false , false ) => {
116
+ // should report "defined multiple time" error before reach this
117
+ unreachable ! ( )
118
+ }
109
119
}
110
120
}
111
121
// no mod with same name exists, just collect `new_mod`
0 commit comments