@@ -19,7 +19,7 @@ impl ModPath {
19
19
20
20
// When std library is present, paths starting with `std::`
21
21
// should be preferred over paths starting with `core::` and `alloc::`
22
- fn should_start_with_std ( & self ) -> bool {
22
+ fn can_start_with_std ( & self ) -> bool {
23
23
self . segments
24
24
. first ( )
25
25
. filter ( |& first_segment| {
@@ -132,6 +132,9 @@ fn find_path_inner(
132
132
}
133
133
134
134
// - otherwise, look for modules containing (reexporting) it and import it from one of those
135
+ let crate_root = ModuleId { local_id : def_map. root , krate : from. krate } ;
136
+ let crate_attrs = db. attrs ( crate_root. into ( ) ) ;
137
+ let prefer_no_std = crate_attrs. by_key ( "no_std" ) . exists ( ) ;
135
138
let importable_locations = find_importable_locations ( db, item, from) ;
136
139
let mut best_path = None ;
137
140
let mut best_path_len = max_len;
@@ -147,21 +150,32 @@ fn find_path_inner(
147
150
} ;
148
151
path. segments . push ( name) ;
149
152
150
- let new_path =
151
- if let Some ( best_path) = best_path { select_best_path ( best_path, path) } else { path } ;
153
+ let new_path = if let Some ( best_path) = best_path {
154
+ select_best_path ( best_path, path, prefer_no_std)
155
+ } else {
156
+ path
157
+ } ;
152
158
best_path_len = new_path. len ( ) ;
153
159
best_path = Some ( new_path) ;
154
160
}
155
161
best_path
156
162
}
157
163
158
- fn select_best_path ( old_path : ModPath , new_path : ModPath ) -> ModPath {
159
- if old_path. starts_with_std ( ) && new_path. should_start_with_std ( ) {
164
+ fn select_best_path ( old_path : ModPath , new_path : ModPath , prefer_no_std : bool ) -> ModPath {
165
+ if old_path. starts_with_std ( ) && new_path. can_start_with_std ( ) {
160
166
tested_by ! ( prefer_std_paths) ;
161
- old_path
162
- } else if new_path. starts_with_std ( ) && old_path. should_start_with_std ( ) {
167
+ if prefer_no_std {
168
+ new_path
169
+ } else {
170
+ old_path
171
+ }
172
+ } else if new_path. starts_with_std ( ) && old_path. can_start_with_std ( ) {
163
173
tested_by ! ( prefer_std_paths) ;
164
- new_path
174
+ if prefer_no_std {
175
+ old_path
176
+ } else {
177
+ new_path
178
+ }
165
179
} else if new_path. len ( ) < old_path. len ( ) {
166
180
new_path
167
181
} else {
@@ -512,6 +526,54 @@ mod tests {
512
526
check_found_path ( code, "std::sync::Arc" ) ;
513
527
}
514
528
529
+ #[ test]
530
+ fn prefer_alloc_paths_over_std ( ) {
531
+ covers ! ( prefer_std_paths) ;
532
+ let code = r#"
533
+ //- /main.rs crate:main deps:alloc,std
534
+ #![no_std]
535
+
536
+ <|>
537
+
538
+ //- /std.rs crate:std deps:alloc
539
+
540
+ pub mod sync {
541
+ pub use alloc::sync::Arc;
542
+ }
543
+
544
+ //- /zzz.rs crate:alloc
545
+
546
+ pub mod sync {
547
+ pub struct Arc;
548
+ }
549
+ "# ;
550
+ check_found_path ( code, "alloc::sync::Arc" ) ;
551
+ }
552
+
553
+ #[ test]
554
+ fn prefer_core_paths_over_std ( ) {
555
+ covers ! ( prefer_std_paths) ;
556
+ let code = r#"
557
+ //- /main.rs crate:main deps:core,std
558
+ #![no_std]
559
+
560
+ <|>
561
+
562
+ //- /std.rs crate:std deps:core
563
+
564
+ pub mod fmt {
565
+ pub use core::fmt::Error;
566
+ }
567
+
568
+ //- /zzz.rs crate:core
569
+
570
+ pub mod fmt {
571
+ pub struct Error;
572
+ }
573
+ "# ;
574
+ check_found_path ( code, "core::fmt::Error" ) ;
575
+ }
576
+
515
577
#[ test]
516
578
fn prefer_shorter_paths_if_not_alloc ( ) {
517
579
let code = r#"
0 commit comments