@@ -50,13 +50,13 @@ pub fn find_path(
5050 prefix : prefix_kind,
5151 cfg,
5252 ignore_local_imports,
53+ is_std_item : db. crate_graph ( ) [ item_module. krate ( ) ] . origin . is_lang ( ) ,
5354 from,
5455 from_def_map : & from. def_map ( db) ,
5556 fuel : Cell :: new ( FIND_PATH_FUEL ) ,
5657 } ,
5758 item,
5859 MAX_PATH_LEN ,
59- db. crate_graph ( ) [ item_module. krate ( ) ] . origin . is_lang ( ) ,
6060 )
6161}
6262
@@ -98,20 +98,16 @@ struct FindPathCtx<'db> {
9898 prefix : PrefixKind ,
9999 cfg : ImportPathConfig ,
100100 ignore_local_imports : bool ,
101+ is_std_item : bool ,
101102 from : ModuleId ,
102103 from_def_map : & ' db DefMap ,
103104 fuel : Cell < usize > ,
104105}
105106
106107/// 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 > {
113109 // - if the item is a module, jump straight to module search
114- if !is_std_item {
110+ if !ctx . is_std_item {
115111 if let ItemInNs :: Types ( ModuleDefId :: ModuleId ( module_id) ) = item {
116112 return find_path_for_module ( ctx, & mut FxHashSet :: default ( ) , module_id, true , max_len)
117113 . map ( |choice| choice. path ) ;
@@ -138,12 +134,9 @@ fn find_path_inner(
138134
139135 if let Some ( ModuleDefId :: EnumVariantId ( variant) ) = item. as_module_def_id ( ) {
140136 // - 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+ {
147140 path. push_segment ( ctx. db . enum_variant_data ( variant) . name . clone ( ) ) ;
148141 return Some ( path) ;
149142 }
@@ -152,16 +145,6 @@ fn find_path_inner(
152145 // variant somewhere
153146 }
154147
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-
165148 let mut best_choice = None ;
166149 calculate_best_path ( ctx, & mut FxHashSet :: default ( ) , item, max_len, & mut best_choice) ;
167150 best_choice. map ( |choice| choice. path )
@@ -366,6 +349,12 @@ fn calculate_best_path(
366349 // Item was defined in the same crate that wants to import it. It cannot be found in any
367350 // dependency in this case.
368351 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)
369358 } else {
370359 // Item was defined in some upstream crate. This means that it must be exported from one,
371360 // 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(
382371 visited_modules : & mut FxHashSet < ( ItemInNs , ModuleId ) > ,
383372 item : ItemInNs ,
384373 max_len : usize ,
385- ) -> Option < Choice > {
374+ best_choice : & mut Option < Choice > ,
375+ ) {
386376 let crate_graph = ctx. db . crate_graph ( ) ;
387377 let dependencies = & crate_graph[ ctx. from . krate ] . dependencies ;
388- let mut best_choice = None ;
389378 let mut search = |lang, best_choice : & mut _ | {
390379 if let Some ( dep) = dependencies. iter ( ) . filter ( |it| it. is_sysroot ( ) ) . find ( |dep| {
391380 match crate_graph[ dep. crate_id ] . origin {
@@ -397,29 +386,31 @@ fn find_in_sysroot(
397386 }
398387 } ;
399388 if ctx. cfg . prefer_no_std {
400- search ( LangCrateOrigin :: Core , & mut best_choice) ;
389+ search ( LangCrateOrigin :: Core , best_choice) ;
401390 if matches ! ( best_choice, Some ( Choice { stability: Stable , .. } ) ) {
402- return best_choice ;
391+ return ;
403392 }
404- search ( LangCrateOrigin :: Std , & mut best_choice) ;
393+ search ( LangCrateOrigin :: Std , best_choice) ;
405394 if matches ! ( best_choice, Some ( Choice { stability: Stable , .. } ) ) {
406- return best_choice ;
395+ return ;
407396 }
408397 } else {
409- search ( LangCrateOrigin :: Std , & mut best_choice) ;
398+ search ( LangCrateOrigin :: Std , best_choice) ;
410399 if matches ! ( best_choice, Some ( Choice { stability: Stable , .. } ) ) {
411- return best_choice ;
400+ return ;
412401 }
413- search ( LangCrateOrigin :: Core , & mut best_choice) ;
402+ search ( LangCrateOrigin :: Core , best_choice) ;
414403 if matches ! ( best_choice, Some ( Choice { stability: Stable , .. } ) ) {
415- return best_choice ;
404+ return ;
416405 }
417406 }
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+ } ) ;
423414}
424415
425416fn find_in_dep (
@@ -491,6 +482,7 @@ fn calculate_best_path_local(
491482 ) ;
492483}
493484
485+ #[ derive( Debug ) ]
494486struct Choice {
495487 path : ModPath ,
496488 /// The length in characters of the path
@@ -676,6 +668,7 @@ mod tests {
676668 path : & str ,
677669 prefer_prelude : bool ,
678670 prefer_absolute : bool ,
671+ prefer_no_std : bool ,
679672 expect : Expect ,
680673 ) {
681674 let ( db, pos) = TestDB :: with_position ( ra_fixture) ;
@@ -717,7 +710,7 @@ mod tests {
717710 module,
718711 prefix,
719712 ignore_local_imports,
720- ImportPathConfig { prefer_no_std : false , prefer_prelude, prefer_absolute } ,
713+ ImportPathConfig { prefer_no_std, prefer_prelude, prefer_absolute } ,
721714 ) ;
722715 format_to ! (
723716 res,
@@ -732,15 +725,19 @@ mod tests {
732725 }
733726
734727 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) ;
736729 }
737730
738731 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) ;
740733 }
741734
742735 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) ;
744741 }
745742
746743 #[ test]
@@ -1361,9 +1358,66 @@ pub mod sync {
13611358 "# ] ] ,
13621359 ) ;
13631360 }
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+ }
13641390
13651391 #[ test]
13661392 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+ ) ;
13671421 check_found_path (
13681422 r#"
13691423//- /main.rs crate:main deps:core,std
@@ -1878,10 +1932,9 @@ pub mod ops {
18781932
18791933 #[ test]
18801934 fn respect_unstable_modules ( ) {
1881- check_found_path (
1935+ check_found_path_prefer_no_std (
18821936 r#"
18831937//- /main.rs crate:main deps:std,core
1884- #![no_std]
18851938extern crate std;
18861939$0
18871940//- /longer.rs crate:std deps:core
0 commit comments