@@ -42,7 +42,14 @@ pub fn find_path(
4242 cfg. prefer_no_std = cfg. prefer_no_std || db. crate_supports_no_std ( from. krate ( ) ) ;
4343
4444 find_path_inner (
45- & FindPathCtx { db, prefix : prefix_kind, cfg, ignore_local_imports, from } ,
45+ & FindPathCtx {
46+ db,
47+ prefix : prefix_kind,
48+ cfg,
49+ ignore_local_imports,
50+ from,
51+ from_def_map : & from. def_map ( db) ,
52+ } ,
4653 item,
4754 MAX_PATH_LEN ,
4855 )
@@ -93,15 +100,15 @@ struct FindPathCtx<'db> {
93100 cfg : ImportPathConfig ,
94101 ignore_local_imports : bool ,
95102 from : ModuleId ,
103+ from_def_map : & ' db DefMap ,
96104}
97105
98106/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId
99107fn find_path_inner ( ctx : & FindPathCtx < ' _ > , item : ItemInNs , max_len : usize ) -> Option < ModPath > {
100- let def_map = ctx. from . def_map ( ctx. db ) ;
101108 // - if the item is a module, jump straight to module search
102109 if let ItemInNs :: Types ( ModuleDefId :: ModuleId ( module_id) ) = item {
103110 let mut visited_modules = FxHashSet :: default ( ) ;
104- return find_path_for_module ( ctx, & def_map , & mut visited_modules, module_id, max_len)
111+ return find_path_for_module ( ctx, & mut visited_modules, module_id, max_len)
105112 . map ( |( item, _) | item) ;
106113 }
107114
@@ -111,14 +118,15 @@ fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Opt
111118 } ;
112119 if may_be_in_scope {
113120 // - if the item is already in scope, return the name under which it is
114- let scope_name = find_in_scope ( ctx. db , & def_map, ctx. from , item, ctx. ignore_local_imports ) ;
121+ let scope_name =
122+ find_in_scope ( ctx. db , ctx. from_def_map , ctx. from , item, ctx. ignore_local_imports ) ;
115123 if let Some ( scope_name) = scope_name {
116124 return Some ( ModPath :: from_segments ( ctx. prefix . path_kind ( ) , iter:: once ( scope_name) ) ) ;
117125 }
118126 }
119127
120128 // - if the item is in the prelude, return the name from there
121- if let Some ( value) = find_in_prelude ( ctx. db , & def_map , item, ctx. from ) {
129+ if let Some ( value) = find_in_prelude ( ctx. db , ctx . from_def_map , item, ctx. from ) {
122130 return Some ( value) ;
123131 }
124132
@@ -137,13 +145,12 @@ fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Opt
137145
138146 let mut visited_modules = FxHashSet :: default ( ) ;
139147
140- calculate_best_path ( ctx, & def_map , & mut visited_modules, item, max_len) . map ( |( item, _) | item)
148+ calculate_best_path ( ctx, & mut visited_modules, item, max_len) . map ( |( item, _) | item)
141149}
142150
143151#[ tracing:: instrument( skip_all) ]
144152fn find_path_for_module (
145153 ctx : & FindPathCtx < ' _ > ,
146- def_map : & DefMap ,
147154 visited_modules : & mut FxHashSet < ModuleId > ,
148155 module_id : ModuleId ,
149156 max_len : usize ,
@@ -152,21 +159,21 @@ fn find_path_for_module(
152159 return None ;
153160 }
154161
155- let is_crate_root = module_id. as_crate_root ( ) ;
156- // - if the item is the crate root, return `crate`
157- if is_crate_root == Some ( ctx. from . derive_crate_root ( ) ) {
158- return Some ( ( ModPath :: from_segments ( PathKind :: Crate , None ) , Stable ) ) ;
159- }
162+ if let Some ( crate_root) = module_id. as_crate_root ( ) {
163+ if crate_root == ctx. from . derive_crate_root ( ) {
164+ // - if the item is the crate root, return `crate`
165+ return Some ( ( ModPath :: from_segments ( PathKind :: Crate , None ) , Stable ) ) ;
166+ }
167+ // - otherwise if the item is the crate root of a dependency crate, return the name from the extern prelude
160168
161- // - if the item is the crate root of a dependency crate, return the name from the extern prelude
162- if let Some ( crate_root) = is_crate_root {
163169 let root_def_map = ctx. from . derive_crate_root ( ) . def_map ( ctx. db ) ;
164170 // rev here so we prefer looking at renamed extern decls first
165171 for ( name, ( def_id, _extern_crate) ) in root_def_map. extern_prelude ( ) . rev ( ) {
166172 if crate_root != def_id {
167173 continue ;
168174 }
169- let name_already_occupied_in_type_ns = def_map
175+ let name_already_occupied_in_type_ns = ctx
176+ . from_def_map
170177 . with_ancestor_maps ( ctx. db , ctx. from . local_id , & mut |def_map, local_id| {
171178 def_map[ local_id]
172179 . scope
@@ -191,7 +198,7 @@ fn find_path_for_module(
191198 if may_be_in_scope {
192199 let scope_name = find_in_scope (
193200 ctx. db ,
194- def_map ,
201+ ctx . from_def_map ,
195202 ctx. from ,
196203 ItemInNs :: Types ( module_id. into ( ) ) ,
197204 ctx. ignore_local_imports ,
@@ -206,22 +213,21 @@ fn find_path_for_module(
206213 }
207214
208215 // - if the module can be referenced as self, super or crate, do that
209- if let Some ( mod_path) = is_kw_kind_relative_to_from ( def_map , module_id, ctx. from ) {
216+ if let Some ( mod_path) = is_kw_kind_relative_to_from ( ctx . from_def_map , module_id, ctx. from ) {
210217 if ctx. prefix != PrefixKind :: ByCrate || mod_path. kind == PathKind :: Crate {
211218 return Some ( ( mod_path, Stable ) ) ;
212219 }
213220 }
214221
215222 // - if the module is in the prelude, return it by that path
216223 if let Some ( mod_path) =
217- find_in_prelude ( ctx. db , def_map , ItemInNs :: Types ( module_id. into ( ) ) , ctx. from )
224+ find_in_prelude ( ctx. db , ctx . from_def_map , ItemInNs :: Types ( module_id. into ( ) ) , ctx. from )
218225 {
219226 return Some ( ( mod_path, Stable ) ) ;
220227 }
221- calculate_best_path ( ctx, def_map , visited_modules, ItemInNs :: Types ( module_id. into ( ) ) , max_len)
228+ calculate_best_path ( ctx, visited_modules, ItemInNs :: Types ( module_id. into ( ) ) , max_len)
222229}
223230
224- // FIXME: Do we still need this now that we record import origins, and hence aliases?
225231fn find_in_scope (
226232 db : & dyn DefDatabase ,
227233 def_map : & DefMap ,
@@ -246,7 +252,6 @@ fn find_in_prelude(
246252 from : ModuleId ,
247253) -> Option < ModPath > {
248254 let ( prelude_module, _) = local_def_map. prelude ( ) ?;
249- // Preludes in block DefMaps are ignored, only the crate DefMap is searched
250255 let prelude_def_map = prelude_module. def_map ( db) ;
251256 let prelude_scope = & prelude_def_map[ prelude_module. local_id ] . scope ;
252257 let ( name, vis, _declared) = prelude_scope. name_of ( item) ?;
@@ -304,7 +309,6 @@ fn is_kw_kind_relative_to_from(
304309#[ tracing:: instrument( skip_all) ]
305310fn calculate_best_path (
306311 ctx : & FindPathCtx < ' _ > ,
307- def_map : & DefMap ,
308312 visited_modules : & mut FxHashSet < ModuleId > ,
309313 item : ItemInNs ,
310314 max_len : usize ,
@@ -337,14 +341,14 @@ fn calculate_best_path(
337341 // Item was defined in the same crate that wants to import it. It cannot be found in any
338342 // dependency in this case.
339343 // FIXME: cache the `find_local_import_locations` output?
340- for ( module_id, name) in find_local_import_locations ( db, item, ctx. from ) {
344+ for ( module_id, name) in find_local_import_locations ( db, item, ctx. from , ctx . from_def_map ) {
341345 if !visited_modules. insert ( module_id) {
342346 continue ;
343347 }
344348 // we are looking for paths of length up to best_path_len, any longer will make it be
345349 // less optimal. The -1 is due to us pushing name onto it afterwards.
346350 if let Some ( path) =
347- find_path_for_module ( ctx, def_map , visited_modules, module_id, best_path_len - 1 )
351+ find_path_for_module ( ctx, visited_modules, module_id, best_path_len - 1 )
348352 {
349353 process ( path, name, & mut best_path_len) ;
350354 }
@@ -365,13 +369,8 @@ fn calculate_best_path(
365369
366370 // Determine best path for containing module and append last segment from `info`.
367371 // FIXME: we should guide this to look up the path locally, or from the same crate again?
368- let path = find_path_for_module (
369- ctx,
370- def_map,
371- visited_modules,
372- info. container ,
373- best_path_len - 1 ,
374- ) ;
372+ let path =
373+ find_path_for_module ( ctx, visited_modules, info. container , best_path_len - 1 ) ;
375374 let Some ( ( path, path_stability) ) = path else {
376375 continue ;
377376 } ;
@@ -461,15 +460,14 @@ fn find_local_import_locations(
461460 db : & dyn DefDatabase ,
462461 item : ItemInNs ,
463462 from : ModuleId ,
463+ def_map : & DefMap ,
464464) -> Vec < ( ModuleId , Name ) > {
465465 let _p = tracing:: span!( tracing:: Level :: INFO , "find_local_import_locations" ) . entered ( ) ;
466466
467467 // `from` can import anything below `from` with visibility of at least `from`, and anything
468468 // above `from` with any visibility. That means we do not need to descend into private siblings
469469 // of `from` (and similar).
470470
471- let def_map = from. def_map ( db) ;
472-
473471 // Compute the initial worklist. We start with all direct child modules of `from` as well as all
474472 // of its (recursive) parent modules.
475473 let data = & def_map[ from. local_id ] ;
0 commit comments