@@ -50,13 +50,13 @@ pub fn find_path(
50
50
prefix : prefix_kind,
51
51
cfg,
52
52
ignore_local_imports,
53
+ is_std_item : db. crate_graph ( ) [ item_module. krate ( ) ] . origin . is_lang ( ) ,
53
54
from,
54
55
from_def_map : & from. def_map ( db) ,
55
56
fuel : Cell :: new ( FIND_PATH_FUEL ) ,
56
57
} ,
57
58
item,
58
59
MAX_PATH_LEN ,
59
- db. crate_graph ( ) [ item_module. krate ( ) ] . origin . is_lang ( ) ,
60
60
)
61
61
}
62
62
@@ -98,20 +98,16 @@ struct FindPathCtx<'db> {
98
98
prefix : PrefixKind ,
99
99
cfg : ImportPathConfig ,
100
100
ignore_local_imports : bool ,
101
+ is_std_item : bool ,
101
102
from : ModuleId ,
102
103
from_def_map : & ' db DefMap ,
103
104
fuel : Cell < usize > ,
104
105
}
105
106
106
107
/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId
107
- fn find_path_inner (
108
- ctx : & FindPathCtx < ' _ > ,
109
- item : ItemInNs ,
110
- max_len : usize ,
111
- is_std_item : bool ,
112
- ) -> Option < ModPath > {
108
+ fn find_path_inner ( ctx : & FindPathCtx < ' _ > , item : ItemInNs , max_len : usize ) -> Option < ModPath > {
113
109
// - if the item is a module, jump straight to module search
114
- if !is_std_item {
110
+ if !ctx . is_std_item {
115
111
if let ItemInNs :: Types ( ModuleDefId :: ModuleId ( module_id) ) = item {
116
112
return find_path_for_module ( ctx, & mut FxHashSet :: default ( ) , module_id, true , max_len)
117
113
. map ( |choice| choice. path ) ;
@@ -138,12 +134,9 @@ fn find_path_inner(
138
134
139
135
if let Some ( ModuleDefId :: EnumVariantId ( variant) ) = item. as_module_def_id ( ) {
140
136
// - if the item is an enum variant, refer to it via the enum
141
- if let Some ( mut path) = find_path_inner (
142
- ctx,
143
- ItemInNs :: Types ( variant. lookup ( ctx. db ) . parent . into ( ) ) ,
144
- max_len,
145
- is_std_item,
146
- ) {
137
+ if let Some ( mut path) =
138
+ find_path_inner ( ctx, ItemInNs :: Types ( variant. lookup ( ctx. db ) . parent . into ( ) ) , max_len)
139
+ {
147
140
path. push_segment ( ctx. db . enum_variant_data ( variant) . name . clone ( ) ) ;
148
141
return Some ( path) ;
149
142
}
@@ -152,16 +145,6 @@ fn find_path_inner(
152
145
// variant somewhere
153
146
}
154
147
155
- if is_std_item {
156
- // The item we are searching for comes from the sysroot libraries, so skip prefer looking in
157
- // the sysroot libraries directly.
158
- // We do need to fallback as the item in question could be re-exported by another crate
159
- // while not being a transitive dependency of the current crate.
160
- if let Some ( choice) = find_in_sysroot ( ctx, & mut FxHashSet :: default ( ) , item, max_len) {
161
- return Some ( choice. path ) ;
162
- }
163
- }
164
-
165
148
let mut best_choice = None ;
166
149
calculate_best_path ( ctx, & mut FxHashSet :: default ( ) , item, max_len, & mut best_choice) ;
167
150
best_choice. map ( |choice| choice. path )
@@ -366,6 +349,12 @@ fn calculate_best_path(
366
349
// Item was defined in the same crate that wants to import it. It cannot be found in any
367
350
// dependency in this case.
368
351
calculate_best_path_local ( ctx, visited_modules, item, max_len, best_choice)
352
+ } else if ctx. is_std_item {
353
+ // The item we are searching for comes from the sysroot libraries, so skip prefer looking in
354
+ // the sysroot libraries directly.
355
+ // We do need to fallback as the item in question could be re-exported by another crate
356
+ // while not being a transitive dependency of the current crate.
357
+ find_in_sysroot ( ctx, visited_modules, item, max_len, best_choice)
369
358
} else {
370
359
// Item was defined in some upstream crate. This means that it must be exported from one,
371
360
// too (unless we can't name it at all). It could *also* be (re)exported by the same crate
@@ -382,10 +371,10 @@ fn find_in_sysroot(
382
371
visited_modules : & mut FxHashSet < ( ItemInNs , ModuleId ) > ,
383
372
item : ItemInNs ,
384
373
max_len : usize ,
385
- ) -> Option < Choice > {
374
+ best_choice : & mut Option < Choice > ,
375
+ ) {
386
376
let crate_graph = ctx. db . crate_graph ( ) ;
387
377
let dependencies = & crate_graph[ ctx. from . krate ] . dependencies ;
388
- let mut best_choice = None ;
389
378
let mut search = |lang, best_choice : & mut _ | {
390
379
if let Some ( dep) = dependencies. iter ( ) . filter ( |it| it. is_sysroot ( ) ) . find ( |dep| {
391
380
match crate_graph[ dep. crate_id ] . origin {
@@ -397,29 +386,31 @@ fn find_in_sysroot(
397
386
}
398
387
} ;
399
388
if ctx. cfg . prefer_no_std {
400
- search ( LangCrateOrigin :: Core , & mut best_choice) ;
389
+ search ( LangCrateOrigin :: Core , best_choice) ;
401
390
if matches ! ( best_choice, Some ( Choice { stability: Stable , .. } ) ) {
402
- return best_choice ;
391
+ return ;
403
392
}
404
- search ( LangCrateOrigin :: Std , & mut best_choice) ;
393
+ search ( LangCrateOrigin :: Std , best_choice) ;
405
394
if matches ! ( best_choice, Some ( Choice { stability: Stable , .. } ) ) {
406
- return best_choice ;
395
+ return ;
407
396
}
408
397
} else {
409
- search ( LangCrateOrigin :: Std , & mut best_choice) ;
398
+ search ( LangCrateOrigin :: Std , best_choice) ;
410
399
if matches ! ( best_choice, Some ( Choice { stability: Stable , .. } ) ) {
411
- return best_choice ;
400
+ return ;
412
401
}
413
- search ( LangCrateOrigin :: Core , & mut best_choice) ;
402
+ search ( LangCrateOrigin :: Core , best_choice) ;
414
403
if matches ! ( best_choice, Some ( Choice { stability: Stable , .. } ) ) {
415
- return best_choice ;
404
+ return ;
416
405
}
417
406
}
418
- let mut best_choice = None ;
419
- dependencies. iter ( ) . filter ( |it| it. is_sysroot ( ) ) . for_each ( |dep| {
420
- find_in_dep ( ctx, visited_modules, item, max_len, & mut best_choice, dep. crate_id ) ;
421
- } ) ;
422
- best_choice
407
+ dependencies
408
+ . iter ( )
409
+ . filter ( |it| it. is_sysroot ( ) )
410
+ . chain ( dependencies. iter ( ) . filter ( |it| !it. is_sysroot ( ) ) )
411
+ . for_each ( |dep| {
412
+ find_in_dep ( ctx, visited_modules, item, max_len, best_choice, dep. crate_id ) ;
413
+ } ) ;
423
414
}
424
415
425
416
fn find_in_dep (
@@ -491,6 +482,7 @@ fn calculate_best_path_local(
491
482
) ;
492
483
}
493
484
485
+ #[ derive( Debug ) ]
494
486
struct Choice {
495
487
path : ModPath ,
496
488
/// The length in characters of the path
@@ -676,6 +668,7 @@ mod tests {
676
668
path : & str ,
677
669
prefer_prelude : bool ,
678
670
prefer_absolute : bool ,
671
+ prefer_no_std : bool ,
679
672
expect : Expect ,
680
673
) {
681
674
let ( db, pos) = TestDB :: with_position ( ra_fixture) ;
@@ -717,7 +710,7 @@ mod tests {
717
710
module,
718
711
prefix,
719
712
ignore_local_imports,
720
- ImportPathConfig { prefer_no_std : false , prefer_prelude, prefer_absolute } ,
713
+ ImportPathConfig { prefer_no_std, prefer_prelude, prefer_absolute } ,
721
714
) ;
722
715
format_to ! (
723
716
res,
@@ -732,15 +725,19 @@ mod tests {
732
725
}
733
726
734
727
fn check_found_path ( ra_fixture : & str , path : & str , expect : Expect ) {
735
- check_found_path_ ( ra_fixture, path, false , false , expect) ;
728
+ check_found_path_ ( ra_fixture, path, false , false , false , expect) ;
736
729
}
737
730
738
731
fn check_found_path_prelude ( ra_fixture : & str , path : & str , expect : Expect ) {
739
- check_found_path_ ( ra_fixture, path, true , false , expect) ;
732
+ check_found_path_ ( ra_fixture, path, true , false , false , expect) ;
740
733
}
741
734
742
735
fn check_found_path_absolute ( ra_fixture : & str , path : & str , expect : Expect ) {
743
- check_found_path_ ( ra_fixture, path, false , true , expect) ;
736
+ check_found_path_ ( ra_fixture, path, false , true , false , expect) ;
737
+ }
738
+
739
+ fn check_found_path_prefer_no_std ( ra_fixture : & str , path : & str , expect : Expect ) {
740
+ check_found_path_ ( ra_fixture, path, false , false , true , expect) ;
744
741
}
745
742
746
743
#[ test]
@@ -1361,9 +1358,66 @@ pub mod sync {
1361
1358
"# ] ] ,
1362
1359
) ;
1363
1360
}
1361
+ #[ test]
1362
+ fn prefer_core_paths_over_std_for_mod_reexport ( ) {
1363
+ check_found_path_prefer_no_std (
1364
+ r#"
1365
+ //- /main.rs crate:main deps:core,std
1366
+
1367
+ $0
1368
+
1369
+ //- /stdlib.rs crate:std deps:core
1370
+
1371
+ pub use core::pin;
1372
+
1373
+ //- /corelib.rs crate:core
1374
+
1375
+ pub mod pin {
1376
+ pub struct Pin;
1377
+ }
1378
+ "# ,
1379
+ "std::pin::Pin" ,
1380
+ expect ! [ [ r#"
1381
+ Plain (imports ✔): core::pin::Pin
1382
+ Plain (imports ✖): core::pin::Pin
1383
+ ByCrate(imports ✔): core::pin::Pin
1384
+ ByCrate(imports ✖): core::pin::Pin
1385
+ BySelf (imports ✔): core::pin::Pin
1386
+ BySelf (imports ✖): core::pin::Pin
1387
+ "# ] ] ,
1388
+ ) ;
1389
+ }
1364
1390
1365
1391
#[ test]
1366
1392
fn prefer_core_paths_over_std ( ) {
1393
+ check_found_path_prefer_no_std (
1394
+ r#"
1395
+ //- /main.rs crate:main deps:core,std
1396
+
1397
+ $0
1398
+
1399
+ //- /std.rs crate:std deps:core
1400
+
1401
+ pub mod fmt {
1402
+ pub use core::fmt::Error;
1403
+ }
1404
+
1405
+ //- /zzz.rs crate:core
1406
+
1407
+ pub mod fmt {
1408
+ pub struct Error;
1409
+ }
1410
+ "# ,
1411
+ "core::fmt::Error" ,
1412
+ expect ! [ [ r#"
1413
+ Plain (imports ✔): core::fmt::Error
1414
+ Plain (imports ✖): core::fmt::Error
1415
+ ByCrate(imports ✔): core::fmt::Error
1416
+ ByCrate(imports ✖): core::fmt::Error
1417
+ BySelf (imports ✔): core::fmt::Error
1418
+ BySelf (imports ✖): core::fmt::Error
1419
+ "# ] ] ,
1420
+ ) ;
1367
1421
check_found_path (
1368
1422
r#"
1369
1423
//- /main.rs crate:main deps:core,std
@@ -1878,10 +1932,9 @@ pub mod ops {
1878
1932
1879
1933
#[ test]
1880
1934
fn respect_unstable_modules ( ) {
1881
- check_found_path (
1935
+ check_found_path_prefer_no_std (
1882
1936
r#"
1883
1937
//- /main.rs crate:main deps:std,core
1884
- #![no_std]
1885
1938
extern crate std;
1886
1939
$0
1887
1940
//- /longer.rs crate:std deps:core
0 commit comments