@@ -16,19 +16,25 @@ use crate::{
16
16
17
17
/// Find a path that can be used to refer to a certain item. This can depend on
18
18
/// *from where* you're referring to the item, hence the `from` parameter.
19
- pub fn find_path ( db : & dyn DefDatabase , item : ItemInNs , from : ModuleId ) -> Option < ModPath > {
19
+ pub fn find_path (
20
+ db : & dyn DefDatabase ,
21
+ item : ItemInNs ,
22
+ from : ModuleId ,
23
+ prefer_core : bool ,
24
+ ) -> Option < ModPath > {
20
25
let _p = profile:: span ( "find_path" ) ;
21
- find_path_inner ( db, item, from, None )
26
+ find_path_inner ( db, item, from, None , prefer_core )
22
27
}
23
28
24
29
pub fn find_path_prefixed (
25
30
db : & dyn DefDatabase ,
26
31
item : ItemInNs ,
27
32
from : ModuleId ,
28
33
prefix_kind : PrefixKind ,
34
+ prefer_core : bool ,
29
35
) -> Option < ModPath > {
30
36
let _p = profile:: span ( "find_path_prefixed" ) ;
31
- find_path_inner ( db, item, from, Some ( prefix_kind) )
37
+ find_path_inner ( db, item, from, Some ( prefix_kind) , prefer_core )
32
38
}
33
39
34
40
const MAX_PATH_LEN : usize = 15 ;
@@ -100,12 +106,22 @@ fn find_path_inner(
100
106
item : ItemInNs ,
101
107
from : ModuleId ,
102
108
prefixed : Option < PrefixKind > ,
109
+ prefer_core : bool ,
103
110
) -> Option < ModPath > {
104
111
// FIXME: Do fast path for std/core libs?
105
112
106
113
let mut visited_modules = FxHashSet :: default ( ) ;
107
114
let def_map = from. def_map ( db) ;
108
- find_path_inner_ ( db, & def_map, from, item, MAX_PATH_LEN , prefixed, & mut visited_modules)
115
+ find_path_inner_ (
116
+ db,
117
+ & def_map,
118
+ from,
119
+ item,
120
+ MAX_PATH_LEN ,
121
+ prefixed,
122
+ & mut visited_modules,
123
+ prefer_core,
124
+ )
109
125
}
110
126
111
127
fn find_path_inner_ (
@@ -116,6 +132,7 @@ fn find_path_inner_(
116
132
max_len : usize ,
117
133
mut prefixed : Option < PrefixKind > ,
118
134
visited_modules : & mut FxHashSet < ModuleId > ,
135
+ prefer_core : bool ,
119
136
) -> Option < ModPath > {
120
137
if max_len == 0 {
121
138
return None ;
@@ -191,7 +208,9 @@ fn find_path_inner_(
191
208
// Recursive case:
192
209
// - if the item is an enum variant, refer to it via the enum
193
210
if let Some ( ModuleDefId :: EnumVariantId ( variant) ) = item. as_module_def_id ( ) {
194
- if let Some ( mut path) = find_path ( db, ItemInNs :: Types ( variant. parent . into ( ) ) , from) {
211
+ if let Some ( mut path) =
212
+ find_path ( db, ItemInNs :: Types ( variant. parent . into ( ) ) , from, prefer_core)
213
+ {
195
214
let data = db. enum_data ( variant. parent ) ;
196
215
path. push_segment ( data. variants [ variant. local_id ] . name . clone ( ) ) ;
197
216
return Some ( path) ;
@@ -202,7 +221,7 @@ fn find_path_inner_(
202
221
}
203
222
204
223
// - otherwise, look for modules containing (reexporting) it and import it from one of those
205
- let prefer_no_std = db. crate_supports_no_std ( crate_root. krate ) ;
224
+ let prefer_no_std = prefer_core || db. crate_supports_no_std ( crate_root. krate ) ;
206
225
let mut best_path = None ;
207
226
let mut best_path_len = max_len;
208
227
@@ -223,6 +242,7 @@ fn find_path_inner_(
223
242
best_path_len - 1 ,
224
243
prefixed,
225
244
visited_modules,
245
+ prefer_core,
226
246
) {
227
247
path. push_segment ( name) ;
228
248
@@ -253,6 +273,7 @@ fn find_path_inner_(
253
273
best_path_len - 1 ,
254
274
prefixed,
255
275
visited_modules,
276
+ prefer_core,
256
277
) ?;
257
278
cov_mark:: hit!( partially_imported) ;
258
279
path. push_segment ( info. path . segments . last ( ) ?. clone ( ) ) ;
@@ -428,7 +449,8 @@ mod tests {
428
449
. take_types ( )
429
450
. unwrap ( ) ;
430
451
431
- let found_path = find_path_inner ( & db, ItemInNs :: Types ( resolved) , module, prefix_kind) ;
452
+ let found_path =
453
+ find_path_inner ( & db, ItemInNs :: Types ( resolved) , module, prefix_kind, false ) ;
432
454
assert_eq ! ( found_path, Some ( mod_path) , "{:?}" , prefix_kind) ;
433
455
}
434
456
0 commit comments