11//! An algorithm to find a path to refer to a certain item. 
22
3- use  std:: { 
4-     cmp:: Ordering , 
5-     iter:: { self ,  once} , 
6- } ; 
3+ use  std:: { cmp:: Ordering ,  iter} ; 
74
85use  hir_expand:: { 
96    name:: { known,  AsName ,  Name } , 
@@ -17,7 +14,7 @@ use crate::{
1714    nameres:: DefMap , 
1815    path:: { ModPath ,  PathKind } , 
1916    visibility:: { Visibility ,  VisibilityExplicitness } , 
20-     ModuleDefId ,  ModuleId , 
17+     ImportPathConfig ,   ModuleDefId ,  ModuleId , 
2118} ; 
2219
2320/// Find a path that can be used to refer to a certain item. This can depend on 
@@ -28,21 +25,10 @@ pub fn find_path(
2825    from :  ModuleId , 
2926    prefix_kind :  PrefixKind , 
3027    ignore_local_imports :  bool , 
31-     prefer_no_std :  bool , 
32-     prefer_prelude :  bool , 
28+     cfg :  ImportPathConfig , 
3329)  -> Option < ModPath >  { 
3430    let  _p = tracing:: span!( tracing:: Level :: INFO ,  "find_path" ) . entered ( ) ; 
35-     find_path_inner ( 
36-         FindPathCtx  { 
37-             db, 
38-             prefix :  prefix_kind, 
39-             prefer_no_std, 
40-             prefer_prelude, 
41-             ignore_local_imports, 
42-         } , 
43-         item, 
44-         from, 
45-     ) 
31+     find_path_inner ( FindPathCtx  {  db,  prefix :  prefix_kind,  cfg,  ignore_local_imports } ,  item,  from) 
4632} 
4733
4834#[ derive( Copy ,  Clone ,  Debug ) ]  
@@ -88,16 +74,15 @@ impl PrefixKind {
8874struct  FindPathCtx < ' db >  { 
8975    db :  & ' db  dyn  DefDatabase , 
9076    prefix :  PrefixKind , 
91-     prefer_no_std :  bool , 
92-     prefer_prelude :  bool , 
77+     cfg :  ImportPathConfig , 
9378    ignore_local_imports :  bool , 
9479} 
9580
9681/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId 
9782fn  find_path_inner ( ctx :  FindPathCtx < ' _ > ,  item :  ItemInNs ,  from :  ModuleId )  -> Option < ModPath >  { 
9883    // - if the item is a builtin, it's in scope 
9984    if  let  ItemInNs :: Types ( ModuleDefId :: BuiltinType ( builtin) )  = item { 
100-         return  Some ( ModPath :: from_segments ( PathKind :: Plain ,  once ( builtin. as_name ( ) ) ) ) ; 
85+         return  Some ( ModPath :: from_segments ( PathKind :: Plain ,  iter :: once ( builtin. as_name ( ) ) ) ) ; 
10186    } 
10287
10388    let  def_map = from. def_map ( ctx. db ) ; 
@@ -107,7 +92,11 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
10792        let  mut  visited_modules = FxHashSet :: default ( ) ; 
10893        return  find_path_for_module ( 
10994            FindPathCtx  { 
110-                 prefer_no_std :  ctx. prefer_no_std  || ctx. db . crate_supports_no_std ( crate_root. krate ) , 
95+                 cfg :  ImportPathConfig  { 
96+                     prefer_no_std :  ctx. cfg . prefer_no_std 
97+                         || ctx. db . crate_supports_no_std ( crate_root. krate ) , 
98+                     ..ctx. cfg 
99+                 } , 
111100                ..ctx
112101            } , 
113102            & def_map, 
@@ -132,7 +121,7 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
132121        // - if the item is already in scope, return the name under which it is 
133122        let  scope_name = find_in_scope ( ctx. db ,  & def_map,  from,  item,  ctx. ignore_local_imports ) ; 
134123        if  let  Some ( scope_name)  = scope_name { 
135-             return  Some ( ModPath :: from_segments ( prefix. path_kind ( ) ,  Some ( scope_name) ) ) ; 
124+             return  Some ( ModPath :: from_segments ( prefix. path_kind ( ) ,  iter :: once ( scope_name) ) ) ; 
136125        } 
137126    } 
138127
@@ -160,7 +149,11 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
160149
161150    calculate_best_path ( 
162151        FindPathCtx  { 
163-             prefer_no_std :  ctx. prefer_no_std  || ctx. db . crate_supports_no_std ( crate_root. krate ) , 
152+             cfg :  ImportPathConfig  { 
153+                 prefer_no_std :  ctx. cfg . prefer_no_std 
154+                     || ctx. db . crate_supports_no_std ( crate_root. krate ) , 
155+                 ..ctx. cfg 
156+             } , 
164157            ..ctx
165158        } , 
166159        & def_map, 
@@ -213,7 +206,7 @@ fn find_path_for_module(
213206            }  else  { 
214207                PathKind :: Plain 
215208            } ; 
216-             return  Some ( ( ModPath :: from_segments ( kind,  once ( name. clone ( ) ) ) ,  Stable ) ) ; 
209+             return  Some ( ( ModPath :: from_segments ( kind,  iter :: once ( name. clone ( ) ) ) ,  Stable ) ) ; 
217210        } 
218211    } 
219212    let  prefix = if  module_id. is_within_block ( )  {  PrefixKind :: Plain  }  else  {  ctx. prefix  } ; 
@@ -231,7 +224,10 @@ fn find_path_for_module(
231224        ) ; 
232225        if  let  Some ( scope_name)  = scope_name { 
233226            // - if the item is already in scope, return the name under which it is 
234-             return  Some ( ( ModPath :: from_segments ( prefix. path_kind ( ) ,  once ( scope_name) ) ,  Stable ) ) ; 
227+             return  Some ( ( 
228+                 ModPath :: from_segments ( prefix. path_kind ( ) ,  iter:: once ( scope_name) ) , 
229+                 Stable , 
230+             ) ) ; 
235231        } 
236232    } 
237233
@@ -305,7 +301,7 @@ fn find_in_prelude(
305301        } ) ; 
306302
307303    if  found_and_same_def. unwrap_or ( true )  { 
308-         Some ( ModPath :: from_segments ( PathKind :: Plain ,  once ( name. clone ( ) ) ) ) 
304+         Some ( ModPath :: from_segments ( PathKind :: Plain ,  iter :: once ( name. clone ( ) ) ) ) 
309305    }  else  { 
310306        None 
311307    } 
@@ -381,9 +377,7 @@ fn calculate_best_path(
381377                path. 0 . push_segment ( name) ; 
382378
383379                let  new_path = match  best_path. take ( )  { 
384-                     Some ( best_path)  => { 
385-                         select_best_path ( best_path,  path,  ctx. prefer_no_std ,  ctx. prefer_prelude ) 
386-                     } 
380+                     Some ( best_path)  => select_best_path ( best_path,  path,  ctx. cfg ) , 
387381                    None  => path, 
388382                } ; 
389383                best_path_len = new_path. 0 . len ( ) ; 
@@ -425,12 +419,7 @@ fn calculate_best_path(
425419                ) ; 
426420
427421                let  new_path_with_stab = match  best_path. take ( )  { 
428-                     Some ( best_path)  => select_best_path ( 
429-                         best_path, 
430-                         path_with_stab, 
431-                         ctx. prefer_no_std , 
432-                         ctx. prefer_prelude , 
433-                     ) , 
422+                     Some ( best_path)  => select_best_path ( best_path,  path_with_stab,  ctx. cfg ) , 
434423                    None  => path_with_stab, 
435424                } ; 
436425                update_best_path ( & mut  best_path,  new_path_with_stab) ; 
@@ -446,8 +435,7 @@ fn calculate_best_path(
446435fn  select_best_path ( 
447436    old_path @ ( _,  old_stability) :  ( ModPath ,  Stability ) , 
448437    new_path @ ( _,  new_stability) :  ( ModPath ,  Stability ) , 
449-     prefer_no_std :  bool , 
450-     prefer_prelude :  bool , 
438+     cfg :  ImportPathConfig , 
451439)  -> ( ModPath ,  Stability )  { 
452440    match  ( old_stability,  new_stability)  { 
453441        ( Stable ,  Unstable )  => return  old_path, 
@@ -461,7 +449,7 @@ fn select_best_path(
461449        let  ( old_path,  _)  = & old; 
462450        let  new_has_prelude = new_path. segments ( ) . iter ( ) . any ( |seg| seg == & known:: prelude) ; 
463451        let  old_has_prelude = old_path. segments ( ) . iter ( ) . any ( |seg| seg == & known:: prelude) ; 
464-         match  ( new_has_prelude,  old_has_prelude,  prefer_prelude)  { 
452+         match  ( new_has_prelude,  old_has_prelude,  cfg . prefer_prelude )  { 
465453            ( true ,  false ,  true )  | ( false ,  true ,  false )  => new, 
466454            ( true ,  false ,  false )  | ( false ,  true ,  true )  => old, 
467455            // no prelude difference in the paths, so pick the shorter one 
@@ -482,7 +470,7 @@ fn select_best_path(
482470
483471    match  ( old_path. 0 . segments ( ) . first ( ) ,  new_path. 0 . segments ( ) . first ( ) )  { 
484472        ( Some ( old) ,  Some ( new) )  if  STD_CRATES . contains ( old)  && STD_CRATES . contains ( new)  => { 
485-             let  rank = match  prefer_no_std { 
473+             let  rank = match  cfg . prefer_no_std  { 
486474                false  => |name :  & Name | match  name { 
487475                    name if  name == & known:: core => 0 , 
488476                    name if  name == & known:: alloc => 1 , 
@@ -647,10 +635,9 @@ mod tests {
647635        { 
648636            let  found_path = find_path_inner ( 
649637                FindPathCtx  { 
650-                     prefer_no_std :  false , 
651638                    db :  & db, 
652639                    prefix, 
653-                     prefer_prelude, 
640+                     cfg :   ImportPathConfig   {   prefer_no_std :   false ,   prefer_prelude  } , 
654641                    ignore_local_imports, 
655642                } , 
656643                resolved, 
0 commit comments