@@ -16,7 +16,7 @@ use test_utils::tested_by;
1616
1717use crate :: {
1818 db:: DefDatabase ,
19- nameres:: CrateDefMap ,
19+ nameres:: { BuiltinShadowMode , CrateDefMap } ,
2020 path:: { Path , PathKind } ,
2121 per_ns:: PerNs ,
2222 AdtId , EnumVariantId , LocalModuleId , ModuleDefId , ModuleId ,
@@ -68,8 +68,10 @@ impl CrateDefMap {
6868 mode : ResolveMode ,
6969 original_module : LocalModuleId ,
7070 path : & Path ,
71+ shadow : BuiltinShadowMode ,
7172 ) -> ResolvePathResult {
72- let mut segments = path. segments . iter ( ) . enumerate ( ) ;
73+ let mut segments = path. segments . iter ( ) . enumerate ( ) . peekable ( ) ;
74+
7375 let mut curr_per_ns: PerNs = match path. kind {
7476 PathKind :: DollarCrate ( krate) => {
7577 if krate == self . krate {
@@ -101,15 +103,24 @@ impl CrateDefMap {
101103 None => return ResolvePathResult :: empty ( ReachedFixedPoint :: Yes ) ,
102104 } ;
103105 log:: debug!( "resolving {:?} in crate root (+ extern prelude)" , segment) ;
104- self . resolve_name_in_crate_root_or_extern_prelude ( & segment. name )
106+
107+ self . resolve_name_in_crate_root_or_extern_prelude (
108+ & segment. name ,
109+ prefer_module ( & mut segments, shadow) ,
110+ )
105111 }
106112 PathKind :: Plain => {
107113 let segment = match segments. next ( ) {
108114 Some ( ( _, segment) ) => segment,
109115 None => return ResolvePathResult :: empty ( ReachedFixedPoint :: Yes ) ,
110116 } ;
111117 log:: debug!( "resolving {:?} in module" , segment) ;
112- self . resolve_name_in_module ( db, original_module, & segment. name )
118+ self . resolve_name_in_module (
119+ db,
120+ original_module,
121+ & segment. name ,
122+ prefer_module ( & mut segments, shadow) ,
123+ )
113124 }
114125 PathKind :: Super => {
115126 if let Some ( p) = self . modules [ original_module] . parent {
@@ -139,7 +150,7 @@ impl CrateDefMap {
139150 }
140151 } ;
141152
142- for ( i, segment) in segments {
153+ while let Some ( ( i, segment) ) = segments. next ( ) {
143154 let curr = match curr_per_ns. take_types ( ) {
144155 Some ( r) => r,
145156 None => {
@@ -160,7 +171,7 @@ impl CrateDefMap {
160171 Path { segments : path. segments [ i..] . to_vec ( ) , kind : PathKind :: Self_ } ;
161172 log:: debug!( "resolving {:?} in other crate" , path) ;
162173 let defp_map = db. crate_def_map ( module. krate ) ;
163- let ( def, s) = defp_map. resolve_path ( db, module. local_id , & path) ;
174+ let ( def, s) = defp_map. resolve_path ( db, module. local_id , & path, shadow ) ;
164175 return ResolvePathResult :: with (
165176 def,
166177 ReachedFixedPoint :: Yes ,
@@ -169,7 +180,10 @@ impl CrateDefMap {
169180 }
170181
171182 // Since it is a qualified path here, it should not contains legacy macros
172- match self [ module. local_id ] . scope . get ( & segment. name ) {
183+ match self [ module. local_id ]
184+ . scope
185+ . get ( & segment. name , prefer_module ( & mut segments, shadow) )
186+ {
173187 Some ( res) => res. def ,
174188 _ => {
175189 log:: debug!( "path segment {:?} not found" , segment. name) ;
@@ -212,14 +226,30 @@ impl CrateDefMap {
212226 }
213227 } ;
214228 }
215- ResolvePathResult :: with ( curr_per_ns, ReachedFixedPoint :: Yes , None )
229+ return ResolvePathResult :: with ( curr_per_ns, ReachedFixedPoint :: Yes , None ) ;
230+
231+ // if it is not the last segment, we prefer builtin as module
232+ fn prefer_module < I > (
233+ segments : & mut std:: iter:: Peekable < I > ,
234+ shadow : BuiltinShadowMode ,
235+ ) -> BuiltinShadowMode
236+ where
237+ I : Iterator ,
238+ {
239+ if segments. peek ( ) . is_some ( ) {
240+ BuiltinShadowMode :: Module
241+ } else {
242+ shadow
243+ }
244+ }
216245 }
217246
218247 fn resolve_name_in_module (
219248 & self ,
220249 db : & impl DefDatabase ,
221250 module : LocalModuleId ,
222251 name : & Name ,
252+ shadow : BuiltinShadowMode ,
223253 ) -> PerNs {
224254 // Resolve in:
225255 // - legacy scope of macro
@@ -228,23 +258,33 @@ impl CrateDefMap {
228258 // - std prelude
229259 let from_legacy_macro =
230260 self [ module] . scope . get_legacy_macro ( name) . map_or_else ( PerNs :: none, PerNs :: macros) ;
231- let from_scope = self [ module] . scope . get ( name) . map_or_else ( PerNs :: none, |res| res. def ) ;
261+ let from_scope =
262+ self [ module] . scope . get ( name, shadow) . map_or_else ( PerNs :: none, |res| res. def ) ;
232263 let from_extern_prelude =
233264 self . extern_prelude . get ( name) . map_or ( PerNs :: none ( ) , |& it| PerNs :: types ( it) ) ;
234- let from_prelude = self . resolve_in_prelude ( db, name) ;
265+ let from_prelude = self . resolve_in_prelude ( db, name, shadow ) ;
235266
236267 from_legacy_macro. or ( from_scope) . or ( from_extern_prelude) . or ( from_prelude)
237268 }
238269
239- fn resolve_name_in_crate_root_or_extern_prelude ( & self , name : & Name ) -> PerNs {
270+ fn resolve_name_in_crate_root_or_extern_prelude (
271+ & self ,
272+ name : & Name ,
273+ shadow : BuiltinShadowMode ,
274+ ) -> PerNs {
240275 let from_crate_root =
241- self [ self . root ] . scope . get ( name) . map_or_else ( PerNs :: none, |res| res. def ) ;
276+ self [ self . root ] . scope . get ( name, shadow ) . map_or_else ( PerNs :: none, |res| res. def ) ;
242277 let from_extern_prelude = self . resolve_name_in_extern_prelude ( name) ;
243278
244279 from_crate_root. or ( from_extern_prelude)
245280 }
246281
247- fn resolve_in_prelude ( & self , db : & impl DefDatabase , name : & Name ) -> PerNs {
282+ fn resolve_in_prelude (
283+ & self ,
284+ db : & impl DefDatabase ,
285+ name : & Name ,
286+ shadow : BuiltinShadowMode ,
287+ ) -> PerNs {
248288 if let Some ( prelude) = self . prelude {
249289 let keep;
250290 let def_map = if prelude. krate == self . krate {
@@ -254,7 +294,10 @@ impl CrateDefMap {
254294 keep = db. crate_def_map ( prelude. krate ) ;
255295 & keep
256296 } ;
257- def_map[ prelude. local_id ] . scope . get ( name) . map_or_else ( PerNs :: none, |res| res. def )
297+ def_map[ prelude. local_id ]
298+ . scope
299+ . get ( name, shadow)
300+ . map_or_else ( PerNs :: none, |res| res. def )
258301 } else {
259302 PerNs :: none ( )
260303 }
0 commit comments