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