@@ -10,7 +10,6 @@ use hir_expand::name::Name;
10
10
11
11
// TODO don't import from super imports? or at least deprioritize
12
12
// TODO use super?
13
- // TODO use shortest path
14
13
// TODO performance / memoize
15
14
16
15
pub fn find_path ( db : & impl DefDatabase , item : ItemInNs , from : ModuleId ) -> Option < ModPath > {
@@ -61,17 +60,17 @@ pub fn find_path(db: &impl DefDatabase, item: ItemInNs, from: ModuleId) -> Optio
61
60
62
61
// - otherwise, look for modules containing (reexporting) it and import it from one of those
63
62
let importable_locations = find_importable_locations ( db, item, from) ;
64
- // XXX going in order for now
63
+ let mut candidate_paths = Vec :: new ( ) ;
65
64
for ( module_id, name) in importable_locations {
66
65
// TODO prevent infinite loops
67
66
let mut path = match find_path ( db, ItemInNs :: Types ( ModuleDefId :: ModuleId ( module_id) ) , from) {
68
67
None => continue ,
69
68
Some ( path) => path,
70
69
} ;
71
70
path. segments . push ( name) ;
72
- return Some ( path) ;
71
+ candidate_paths . push ( path) ;
73
72
}
74
- None
73
+ candidate_paths . into_iter ( ) . min_by_key ( |path| path . segments . len ( ) )
75
74
}
76
75
77
76
fn find_importable_locations ( db : & impl DefDatabase , item : ItemInNs , from : ModuleId ) -> Vec < ( ModuleId , Name ) > {
@@ -275,4 +274,20 @@ mod tests {
275
274
check_found_path ( code, "None" ) ;
276
275
check_found_path ( code, "Some" ) ;
277
276
}
277
+
278
+ #[ test]
279
+ fn shortest_path ( ) {
280
+ let code = r#"
281
+ //- /main.rs
282
+ pub mod foo;
283
+ pub mod baz;
284
+ struct S;
285
+ <|>
286
+ //- /foo.rs
287
+ pub mod bar { pub struct S; }
288
+ //- /baz.rs
289
+ pub use crate::foo::bar::S;
290
+ "# ;
291
+ check_found_path ( code, "baz::S" ) ;
292
+ }
278
293
}
0 commit comments