@@ -15,12 +15,13 @@ use hir::def_id::{CrateNum, DefIndex, DefId, RESERVED_FOR_INCR_COMP_CACHE,
1515 LOCAL_CRATE } ;
1616use hir:: map:: definitions:: { Definitions , DefPathTable } ;
1717use middle:: const_val:: ByteArray ;
18+ use middle:: cstore:: CrateStore ;
1819use rustc_data_structures:: fx:: FxHashMap ;
1920use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
2021use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder , opaque,
2122 SpecializedDecoder , SpecializedEncoder ,
2223 UseSpecializedDecodable } ;
23- use session:: Session ;
24+ use session:: { CrateDisambiguator , Session } ;
2425use std:: borrow:: Cow ;
2526use std:: cell:: RefCell ;
2627use std:: collections:: BTreeMap ;
@@ -45,8 +46,10 @@ pub struct OnDiskCache<'sess> {
4546 // compilation session.
4647 current_diagnostics : RefCell < FxHashMap < DepNodeIndex , Vec < Diagnostic > > > ,
4748
48- // This will eventually be needed for creating Decoders that can rebase
49- // spans.
49+
50+ prev_cnums : Vec < ( u32 , String , CrateDisambiguator ) > ,
51+ cnum_map : RefCell < Option < IndexVec < CrateNum , Option < CrateNum > > > > ,
52+
5053 _prev_filemap_starts : BTreeMap < BytePos , StableFilemapId > ,
5154 codemap : & ' sess CodeMap ,
5255}
@@ -55,6 +58,7 @@ pub struct OnDiskCache<'sess> {
5558#[ derive( RustcEncodable , RustcDecodable ) ]
5659struct Header {
5760 prev_filemap_starts : BTreeMap < BytePos , StableFilemapId > ,
61+ prev_cnums : Vec < ( u32 , String , CrateDisambiguator ) > ,
5862}
5963
6064type EncodedPrevDiagnostics = Vec < ( SerializedDepNodeIndex , Vec < Diagnostic > ) > ;
@@ -94,6 +98,8 @@ impl<'sess> OnDiskCache<'sess> {
9498 OnDiskCache {
9599 prev_diagnostics,
96100 _prev_filemap_starts : header. prev_filemap_starts ,
101+ prev_cnums : header. prev_cnums ,
102+ cnum_map : RefCell :: new ( None ) ,
97103 codemap : sess. codemap ( ) ,
98104 current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
99105 }
@@ -103,13 +109,16 @@ impl<'sess> OnDiskCache<'sess> {
103109 OnDiskCache {
104110 prev_diagnostics : FxHashMap ( ) ,
105111 _prev_filemap_starts : BTreeMap :: new ( ) ,
112+ prev_cnums : vec ! [ ] ,
113+ cnum_map : RefCell :: new ( None ) ,
106114 codemap,
107115 current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
108116 }
109117 }
110118
111119 pub fn serialize < ' a , ' gcx , ' lcx , E > ( & self ,
112120 tcx : TyCtxt < ' a , ' gcx , ' lcx > ,
121+ cstore : & CrateStore ,
113122 encoder : & mut E )
114123 -> Result < ( ) , E :: Error >
115124 where E : ty_codec:: TyEncoder
@@ -124,15 +133,30 @@ impl<'sess> OnDiskCache<'sess> {
124133 definitions : tcx. hir . definitions ( ) ,
125134 } ;
126135
136+
137+ // Encode the file header
127138 let prev_filemap_starts: BTreeMap < _ , _ > = self
128139 . codemap
129140 . files ( )
130141 . iter ( )
131142 . map ( |fm| ( fm. start_pos , StableFilemapId :: new ( fm) ) )
132143 . collect ( ) ;
133144
134- Header { prev_filemap_starts } . encode ( & mut encoder) ?;
145+ let sorted_cnums = sorted_cnums_including_local_crate ( cstore) ;
146+
147+ let prev_cnums: Vec < _ > = sorted_cnums. iter ( ) . map ( |& cnum| {
148+ let crate_name = tcx. original_crate_name ( cnum) . as_str ( ) . to_string ( ) ;
149+ let crate_disambiguator = tcx. crate_disambiguator ( cnum) ;
150+ ( cnum. as_u32 ( ) , crate_name, crate_disambiguator)
151+ } ) . collect ( ) ;
135152
153+ Header {
154+ prev_filemap_starts,
155+ prev_cnums,
156+ } . encode ( & mut encoder) ?;
157+
158+
159+ // Encode Diagnostics
136160 let diagnostics: EncodedPrevDiagnostics =
137161 self . current_diagnostics
138162 . borrow ( )
@@ -142,7 +166,16 @@ impl<'sess> OnDiskCache<'sess> {
142166
143167 diagnostics. encode ( & mut encoder) ?;
144168
145- Ok ( ( ) )
169+ return Ok ( ( ) ) ;
170+
171+ fn sorted_cnums_including_local_crate ( cstore : & CrateStore ) -> Vec < CrateNum > {
172+ let mut cnums = vec ! [ LOCAL_CRATE ] ;
173+ cnums. extend_from_slice ( & cstore. crates_untracked ( ) [ ..] ) ;
174+ cnums. sort_unstable ( ) ;
175+ // Just to be sure...
176+ cnums. dedup ( ) ;
177+ cnums
178+ }
146179 }
147180
148181 /// Load a diagnostic emitted during the previous compilation session.
@@ -178,6 +211,40 @@ impl<'sess> OnDiskCache<'sess> {
178211
179212 x. extend ( diagnostics. into_iter ( ) ) ;
180213 }
214+
215+ // This function builds mapping from previous-session-CrateNum to
216+ // current-session-CrateNum. There might be CrateNums from the previous
217+ // Session that don't occur in the current one. For these, the mapping
218+ // maps to None.
219+ fn compute_cnum_map ( tcx : TyCtxt ,
220+ prev_cnums : & [ ( u32 , String , CrateDisambiguator ) ] )
221+ -> IndexVec < CrateNum , Option < CrateNum > >
222+ {
223+ let _in_ignore = tcx. dep_graph . in_ignore ( ) ;
224+
225+ let current_cnums = tcx. all_crate_nums ( LOCAL_CRATE ) . iter ( ) . map ( |& cnum| {
226+ let crate_name = tcx. original_crate_name ( cnum)
227+ . as_str ( )
228+ . to_string ( ) ;
229+ let crate_disambiguator = tcx. crate_disambiguator ( cnum) ;
230+ ( ( crate_name, crate_disambiguator) , cnum)
231+ } ) . collect :: < FxHashMap < _ , _ > > ( ) ;
232+
233+ let map_size = prev_cnums. iter ( )
234+ . map ( |& ( cnum, ..) | cnum)
235+ . max ( )
236+ . unwrap_or ( 0 ) + 1 ;
237+ let mut map = IndexVec :: new ( ) ;
238+ map. resize ( map_size as usize , None ) ;
239+
240+ for & ( prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
241+ let key = ( crate_name. clone ( ) , crate_disambiguator) ;
242+ map[ CrateNum :: from_u32 ( prev_cnum) ] = current_cnums. get ( & key) . cloned ( ) ;
243+ }
244+
245+ map[ LOCAL_CRATE ] = Some ( LOCAL_CRATE ) ;
246+ map
247+ }
181248}
182249
183250
0 commit comments