@@ -17,6 +17,15 @@ use crate::{
1717
1818type FxIndexMap < K , V > = IndexMap < K , V , BuildHasherDefault < FxHasher > > ;
1919
20+ /// Item import details stored in the `ImportMap`.
21+ #[ derive( Debug , Clone , Eq , PartialEq ) ]
22+ pub struct ImportInfo {
23+ /// A path that can be used to import the item, relative to the crate's root.
24+ pub path : ModPath ,
25+ /// The module containing this item.
26+ pub container : ModuleId ,
27+ }
28+
2029/// A map from publicly exported items to the path needed to import/name them from a downstream
2130/// crate.
2231///
@@ -26,7 +35,7 @@ type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
2635/// Note that all paths are relative to the containing crate's root, so the crate name still needs
2736/// to be prepended to the `ModPath` before the path is valid.
2837pub struct ImportMap {
29- map : FxIndexMap < ItemInNs , ModPath > ,
38+ map : FxIndexMap < ItemInNs , ImportInfo > ,
3039
3140 /// List of keys stored in `map`, sorted lexicographically by their `ModPath`. Indexed by the
3241 /// values returned by running `fst`.
@@ -78,12 +87,12 @@ impl ImportMap {
7887 let path = mk_path ( ) ;
7988 match import_map. entry ( item) {
8089 Entry :: Vacant ( entry) => {
81- entry. insert ( path) ;
90+ entry. insert ( ImportInfo { path, container : module } ) ;
8291 }
8392 Entry :: Occupied ( mut entry) => {
8493 // If the new path is shorter, prefer that one.
85- if path. len ( ) < entry. get ( ) . len ( ) {
86- * entry. get_mut ( ) = path;
94+ if path. len ( ) < entry. get ( ) . path . len ( ) {
95+ * entry. get_mut ( ) = ImportInfo { path, container : module } ;
8796 } else {
8897 continue ;
8998 }
@@ -119,7 +128,7 @@ impl ImportMap {
119128 let start = last_batch_start;
120129 last_batch_start = idx + 1 ;
121130
122- let key = fst_path ( & importables[ start] . 1 ) ;
131+ let key = fst_path ( & importables[ start] . 1 . path ) ;
123132
124133 builder. insert ( key, start as u64 ) . unwrap ( ) ;
125134 }
@@ -132,6 +141,10 @@ impl ImportMap {
132141
133142 /// Returns the `ModPath` needed to import/mention `item`, relative to this crate's root.
134143 pub fn path_of ( & self , item : ItemInNs ) -> Option < & ModPath > {
144+ Some ( & self . map . get ( & item) ?. path )
145+ }
146+
147+ pub fn import_info_for ( & self , item : ItemInNs ) -> Option < & ImportInfo > {
135148 self . map . get ( & item)
136149 }
137150}
@@ -150,13 +163,13 @@ impl fmt::Debug for ImportMap {
150163 let mut importable_paths: Vec < _ > = self
151164 . map
152165 . iter ( )
153- . map ( |( item, modpath ) | {
166+ . map ( |( item, info ) | {
154167 let ns = match item {
155168 ItemInNs :: Types ( _) => "t" ,
156169 ItemInNs :: Values ( _) => "v" ,
157170 ItemInNs :: Macros ( _) => "m" ,
158171 } ;
159- format ! ( "- {} ({})" , modpath , ns)
172+ format ! ( "- {} ({})" , info . path , ns)
160173 } )
161174 . collect ( ) ;
162175
@@ -171,9 +184,9 @@ fn fst_path(path: &ModPath) -> String {
171184 s
172185}
173186
174- fn cmp ( ( _, lhs) : & ( & ItemInNs , & ModPath ) , ( _, rhs) : & ( & ItemInNs , & ModPath ) ) -> Ordering {
175- let lhs_str = fst_path ( lhs) ;
176- let rhs_str = fst_path ( rhs) ;
187+ fn cmp ( ( _, lhs) : & ( & ItemInNs , & ImportInfo ) , ( _, rhs) : & ( & ItemInNs , & ImportInfo ) ) -> Ordering {
188+ let lhs_str = fst_path ( & lhs. path ) ;
189+ let rhs_str = fst_path ( & rhs. path ) ;
177190 lhs_str. cmp ( & rhs_str)
178191}
179192
@@ -243,7 +256,7 @@ pub fn search_dependencies<'a>(
243256 let importables = & import_map. importables [ indexed_value. value as usize ..] ;
244257
245258 // Path shared by the importable items in this group.
246- let path = & import_map. map [ & importables[ 0 ] ] ;
259+ let path = & import_map. map [ & importables[ 0 ] ] . path ;
247260
248261 if query. anchor_end {
249262 // Last segment must match query.
@@ -256,14 +269,14 @@ pub fn search_dependencies<'a>(
256269 // Add the items from this `ModPath` group. Those are all subsequent items in
257270 // `importables` whose paths match `path`.
258271 let iter = importables. iter ( ) . copied ( ) . take_while ( |item| {
259- let item_path = & import_map. map [ item] ;
272+ let item_path = & import_map. map [ item] . path ;
260273 fst_path ( item_path) == fst_path ( path)
261274 } ) ;
262275
263276 if query. case_sensitive {
264277 // FIXME: This does not do a subsequence match.
265278 res. extend ( iter. filter ( |item| {
266- let item_path = & import_map. map [ item] ;
279+ let item_path = & import_map. map [ item] . path ;
267280 item_path. to_string ( ) . contains ( & query. query )
268281 } ) ) ;
269282 } else {
0 commit comments