@@ -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`
0 commit comments