@@ -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,7 +68,17 @@ impl CrateDefMap {
6868 mode : ResolveMode ,
6969 original_module : LocalModuleId ,
7070 path : & Path ,
71+ shadow : BuiltinShadowMode ,
7172 ) -> ResolvePathResult {
73+ // if it is not the last segment, we prefer the module to the builtin
74+ let prefer_module = |index| {
75+ if index == path. segments . len ( ) - 1 {
76+ shadow
77+ } else {
78+ BuiltinShadowMode :: Module
79+ }
80+ } ;
81+
7282 let mut segments = path. segments . iter ( ) . enumerate ( ) ;
7383 let mut curr_per_ns: PerNs = match path. kind {
7484 PathKind :: DollarCrate ( krate) => {
@@ -96,20 +106,20 @@ impl CrateDefMap {
96106 if self . edition == Edition :: Edition2015
97107 && ( path. kind == PathKind :: Abs || mode == ResolveMode :: Import ) =>
98108 {
99- let segment = match segments. next ( ) {
100- Some ( ( _ , segment) ) => segment,
109+ let ( idx , segment) = match segments. next ( ) {
110+ Some ( ( idx , segment) ) => ( idx , segment) ,
101111 None => return ResolvePathResult :: empty ( ReachedFixedPoint :: Yes ) ,
102112 } ;
103113 log:: debug!( "resolving {:?} in crate root (+ extern prelude)" , segment) ;
104- self . resolve_name_in_crate_root_or_extern_prelude ( & segment. name )
114+ self . resolve_name_in_crate_root_or_extern_prelude ( & segment. name , prefer_module ( idx ) )
105115 }
106116 PathKind :: Plain => {
107- let segment = match segments. next ( ) {
108- Some ( ( _ , segment) ) => segment,
117+ let ( idx , segment) = match segments. next ( ) {
118+ Some ( ( idx , segment) ) => ( idx , segment) ,
109119 None => return ResolvePathResult :: empty ( ReachedFixedPoint :: Yes ) ,
110120 } ;
111121 log:: debug!( "resolving {:?} in module" , segment) ;
112- self . resolve_name_in_module ( db, original_module, & segment. name )
122+ self . resolve_name_in_module ( db, original_module, & segment. name , prefer_module ( idx ) )
113123 }
114124 PathKind :: Super => {
115125 if let Some ( p) = self . modules [ original_module] . parent {
@@ -160,7 +170,7 @@ impl CrateDefMap {
160170 Path { segments : path. segments [ i..] . to_vec ( ) , kind : PathKind :: Self_ } ;
161171 log:: debug!( "resolving {:?} in other crate" , path) ;
162172 let defp_map = db. crate_def_map ( module. krate ) ;
163- let ( def, s) = defp_map. resolve_path ( db, module. local_id , & path) ;
173+ let ( def, s) = defp_map. resolve_path ( db, module. local_id , & path, shadow ) ;
164174 return ResolvePathResult :: with (
165175 def,
166176 ReachedFixedPoint :: Yes ,
@@ -169,7 +179,7 @@ impl CrateDefMap {
169179 }
170180
171181 // Since it is a qualified path here, it should not contains legacy macros
172- match self [ module. local_id ] . scope . get ( & segment. name ) {
182+ match self [ module. local_id ] . scope . get ( & segment. name , prefer_module ( i ) ) {
173183 Some ( res) => res. def ,
174184 _ => {
175185 log:: debug!( "path segment {:?} not found" , segment. name) ;
@@ -212,6 +222,7 @@ impl CrateDefMap {
212222 }
213223 } ;
214224 }
225+
215226 ResolvePathResult :: with ( curr_per_ns, ReachedFixedPoint :: Yes , None )
216227 }
217228
@@ -220,6 +231,7 @@ impl CrateDefMap {
220231 db : & impl DefDatabase ,
221232 module : LocalModuleId ,
222233 name : & Name ,
234+ shadow : BuiltinShadowMode ,
223235 ) -> PerNs {
224236 // Resolve in:
225237 // - legacy scope of macro
@@ -228,23 +240,33 @@ impl CrateDefMap {
228240 // - std prelude
229241 let from_legacy_macro =
230242 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 ) ;
243+ let from_scope =
244+ self [ module] . scope . get ( name, shadow) . map_or_else ( PerNs :: none, |res| res. def ) ;
232245 let from_extern_prelude =
233246 self . extern_prelude . get ( name) . map_or ( PerNs :: none ( ) , |& it| PerNs :: types ( it) ) ;
234- let from_prelude = self . resolve_in_prelude ( db, name) ;
247+ let from_prelude = self . resolve_in_prelude ( db, name, shadow ) ;
235248
236249 from_legacy_macro. or ( from_scope) . or ( from_extern_prelude) . or ( from_prelude)
237250 }
238251
239- fn resolve_name_in_crate_root_or_extern_prelude ( & self , name : & Name ) -> PerNs {
252+ fn resolve_name_in_crate_root_or_extern_prelude (
253+ & self ,
254+ name : & Name ,
255+ shadow : BuiltinShadowMode ,
256+ ) -> PerNs {
240257 let from_crate_root =
241- self [ self . root ] . scope . get ( name) . map_or_else ( PerNs :: none, |res| res. def ) ;
258+ self [ self . root ] . scope . get ( name, shadow ) . map_or_else ( PerNs :: none, |res| res. def ) ;
242259 let from_extern_prelude = self . resolve_name_in_extern_prelude ( name) ;
243260
244261 from_crate_root. or ( from_extern_prelude)
245262 }
246263
247- fn resolve_in_prelude ( & self , db : & impl DefDatabase , name : & Name ) -> PerNs {
264+ fn resolve_in_prelude (
265+ & self ,
266+ db : & impl DefDatabase ,
267+ name : & Name ,
268+ shadow : BuiltinShadowMode ,
269+ ) -> PerNs {
248270 if let Some ( prelude) = self . prelude {
249271 let keep;
250272 let def_map = if prelude. krate == self . krate {
@@ -254,7 +276,10 @@ impl CrateDefMap {
254276 keep = db. crate_def_map ( prelude. krate ) ;
255277 & keep
256278 } ;
257- def_map[ prelude. local_id ] . scope . get ( name) . map_or_else ( PerNs :: none, |res| res. def )
279+ def_map[ prelude. local_id ]
280+ . scope
281+ . get ( name, shadow)
282+ . map_or_else ( PerNs :: none, |res| res. def )
258283 } else {
259284 PerNs :: none ( )
260285 }
0 commit comments