@@ -13,17 +13,17 @@ use decoder;
13
13
use encoder;
14
14
use loader;
15
15
16
- use middle:: cstore:: { CrateStore , CrateSource , ChildItem , ExternCrate , FoundAst } ;
16
+ use middle:: cstore:: { CrateStore , CrateSource , ChildItem , ExternCrate , FoundAst , DefLike } ;
17
17
use middle:: cstore:: { NativeLibraryKind , LinkMeta , LinkagePreference } ;
18
18
use middle:: def;
19
19
use middle:: lang_items;
20
20
use rustc:: ty:: { self , Ty , TyCtxt , VariantKind } ;
21
- use middle:: def_id:: { DefId , DefIndex } ;
21
+ use middle:: def_id:: { DefId , DefIndex , CRATE_DEF_INDEX } ;
22
22
23
23
use rustc:: front:: map as hir_map;
24
24
use rustc:: mir:: repr:: Mir ;
25
25
use rustc:: mir:: mir_map:: MirMap ;
26
- use rustc:: util:: nodemap:: { FnvHashMap , NodeMap , NodeSet } ;
26
+ use rustc:: util:: nodemap:: { FnvHashMap , NodeMap , NodeSet , DefIdMap } ;
27
27
28
28
use std:: cell:: RefCell ;
29
29
use std:: rc:: Rc ;
@@ -544,4 +544,60 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
544
544
{
545
545
encoder:: metadata_encoding_version
546
546
}
547
+
548
+ /// Returns a map from a sufficiently visible external item (i.e. an external item that is
549
+ /// visible from at least one local module) to a sufficiently visible parent (considering
550
+ /// modules that re-export the external item to be parents).
551
+ fn visible_parent_map < ' a > ( & ' a self ) -> :: std:: cell:: RefMut < ' a , DefIdMap < DefId > > {
552
+ let mut visible_parent_map = self . visible_parent_map . borrow_mut ( ) ;
553
+ if !visible_parent_map. is_empty ( ) { return visible_parent_map; }
554
+
555
+ use rustc_front:: hir;
556
+ use rustc:: middle:: cstore:: { CrateStore , ChildItem } ;
557
+ use std:: collections:: vec_deque:: VecDeque ;
558
+ use std:: collections:: hash_map:: Entry ;
559
+ for cnum in 1 .. self . next_crate_num ( ) {
560
+ let cdata = self . get_crate_data ( cnum) ;
561
+
562
+ match cdata. extern_crate . get ( ) {
563
+ // Ignore crates without a corresponding local `extern crate` item.
564
+ Some ( extern_crate) if !extern_crate. direct => continue ,
565
+ _ => { } ,
566
+ }
567
+
568
+ let mut bfs_queue = & mut VecDeque :: new ( ) ;
569
+ let mut add_child = |bfs_queue : & mut VecDeque < _ > , child : ChildItem , parent : DefId | {
570
+ let child = match child. def {
571
+ DefLike :: DlDef ( def) if child. vis == hir:: Public => def. def_id ( ) ,
572
+ _ => return ,
573
+ } ;
574
+
575
+ match visible_parent_map. entry ( child) {
576
+ Entry :: Occupied ( mut entry) => {
577
+ // If `child` is defined in crate `cnum`, ensure
578
+ // that it is mapped to a parent in `cnum`.
579
+ if child. krate == cnum && entry. get ( ) . krate != cnum {
580
+ entry. insert ( parent) ;
581
+ }
582
+ }
583
+ Entry :: Vacant ( entry) => {
584
+ entry. insert ( parent) ;
585
+ bfs_queue. push_back ( child) ;
586
+ }
587
+ }
588
+ } ;
589
+
590
+ let croot = DefId { krate : cnum, index : CRATE_DEF_INDEX } ;
591
+ for child in self . crate_top_level_items ( cnum) {
592
+ add_child ( bfs_queue, child, croot) ;
593
+ }
594
+ while let Some ( def) = bfs_queue. pop_front ( ) {
595
+ for child in self . item_children ( def) {
596
+ add_child ( bfs_queue, child, def) ;
597
+ }
598
+ }
599
+ }
600
+
601
+ visible_parent_map
602
+ }
547
603
}
0 commit comments