1616use rustc:: dep_graph:: DepNode ;
1717use rustc:: hir:: map:: DefPath ;
1818use rustc:: hir:: def_id:: DefId ;
19+ use rustc:: middle:: cstore:: LOCAL_CRATE ;
1920use rustc:: ty:: TyCtxt ;
2021use rustc:: util:: nodemap:: DefIdMap ;
2122use std:: fmt:: { self , Debug } ;
23+ use std:: iter:: once;
24+ use syntax:: ast;
2225
2326/// Index into the DefIdDirectory
2427#[ derive( Copy , Clone , Debug , PartialOrd , Ord , Hash , PartialEq , Eq ,
@@ -31,17 +34,66 @@ pub struct DefPathIndex {
3134pub struct DefIdDirectory {
3235 // N.B. don't use Removable here because these def-ids are loaded
3336 // directly without remapping, so loading them should not fail.
34- paths : Vec < DefPath >
37+ paths : Vec < DefPath > ,
38+
39+ // For each crate, saves the crate-name/disambiguator so that
40+ // later we can match crate-numbers up again.
41+ krates : Vec < KrateInfo > ,
42+ }
43+
44+ #[ derive( Debug , RustcEncodable , RustcDecodable ) ]
45+ pub struct KrateInfo {
46+ krate : ast:: CrateNum ,
47+ name : String ,
48+ disambiguator : String ,
3549}
3650
3751impl DefIdDirectory {
38- pub fn new ( ) -> DefIdDirectory {
39- DefIdDirectory { paths : vec ! [ ] }
52+ pub fn new ( krates : Vec < KrateInfo > ) -> DefIdDirectory {
53+ DefIdDirectory { paths : vec ! [ ] , krates : krates }
54+ }
55+
56+ pub fn krate_still_valid ( & self ,
57+ tcx : TyCtxt ,
58+ max_current_crate : ast:: CrateNum ,
59+ krate : ast:: CrateNum ) -> bool {
60+ // Check that the crate-number still matches. For now, if it
61+ // doesn't, just return None. We could do better, such as
62+ // finding the new number.
63+
64+ if krate > max_current_crate {
65+ false
66+ } else {
67+ let old_info = & self . krates [ krate as usize ] ;
68+ assert_eq ! ( old_info. krate, krate) ;
69+ let old_name: & str = & old_info. name ;
70+ let old_disambiguator: & str = & old_info. disambiguator ;
71+ let new_name: & str = & tcx. crate_name ( krate) ;
72+ let new_disambiguator: & str = & tcx. crate_disambiguator ( krate) ;
73+ old_name == new_name && old_disambiguator == new_disambiguator
74+ }
4075 }
4176
4277 pub fn retrace ( & self , tcx : TyCtxt ) -> RetracedDefIdDirectory {
78+ let max_current_crate =
79+ tcx. sess . cstore . crates ( )
80+ . into_iter ( )
81+ . max ( )
82+ . unwrap_or ( LOCAL_CRATE ) ;
83+
4384 let ids = self . paths . iter ( )
44- . map ( |path| tcx. retrace_path ( path) )
85+ . map ( |path| {
86+ if self . krate_still_valid ( tcx, max_current_crate, path. krate ) {
87+ tcx. retrace_path ( path)
88+ } else {
89+ debug ! ( "crate {} changed from {:?} to {:?}/{:?}" ,
90+ path. krate,
91+ self . krates[ path. krate as usize ] ,
92+ tcx. crate_name( path. krate) ,
93+ tcx. crate_disambiguator( path. krate) ) ;
94+ None
95+ }
96+ } )
4597 . collect ( ) ;
4698 RetracedDefIdDirectory { ids : ids }
4799 }
@@ -70,10 +122,26 @@ pub struct DefIdDirectoryBuilder<'a,'tcx:'a> {
70122
71123impl < ' a , ' tcx > DefIdDirectoryBuilder < ' a , ' tcx > {
72124 pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> DefIdDirectoryBuilder < ' a , ' tcx > {
125+ let mut krates: Vec < _ > =
126+ once ( LOCAL_CRATE )
127+ . chain ( tcx. sess . cstore . crates ( ) )
128+ . map ( |krate| {
129+ KrateInfo {
130+ krate : krate,
131+ name : tcx. crate_name ( krate) . to_string ( ) ,
132+ disambiguator : tcx. crate_disambiguator ( krate) . to_string ( )
133+ }
134+ } )
135+ . collect ( ) ;
136+
137+ // the result of crates() is not in order, so sort list of
138+ // crates so that we can just index it later
139+ krates. sort_by_key ( |k| k. krate ) ;
140+
73141 DefIdDirectoryBuilder {
74142 tcx : tcx,
75143 hash : DefIdMap ( ) ,
76- directory : DefIdDirectory :: new ( )
144+ directory : DefIdDirectory :: new ( krates ) ,
77145 }
78146 }
79147
0 commit comments