@@ -15,12 +15,13 @@ use hir::def_id::{CrateNum, DefIndex, DefId, RESERVED_FOR_INCR_COMP_CACHE,
15
15
LOCAL_CRATE } ;
16
16
use hir:: map:: definitions:: { Definitions , DefPathTable } ;
17
17
use middle:: const_val:: ByteArray ;
18
+ use middle:: cstore:: CrateStore ;
18
19
use rustc_data_structures:: fx:: FxHashMap ;
19
20
use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
20
21
use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder , opaque,
21
22
SpecializedDecoder , SpecializedEncoder ,
22
23
UseSpecializedDecodable } ;
23
- use session:: Session ;
24
+ use session:: { CrateDisambiguator , Session } ;
24
25
use std:: borrow:: Cow ;
25
26
use std:: cell:: RefCell ;
26
27
use std:: collections:: BTreeMap ;
@@ -45,8 +46,10 @@ pub struct OnDiskCache<'sess> {
45
46
// compilation session.
46
47
current_diagnostics : RefCell < FxHashMap < DepNodeIndex , Vec < Diagnostic > > > ,
47
48
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
+
50
53
_prev_filemap_starts : BTreeMap < BytePos , StableFilemapId > ,
51
54
codemap : & ' sess CodeMap ,
52
55
}
@@ -55,6 +58,7 @@ pub struct OnDiskCache<'sess> {
55
58
#[ derive( RustcEncodable , RustcDecodable ) ]
56
59
struct Header {
57
60
prev_filemap_starts : BTreeMap < BytePos , StableFilemapId > ,
61
+ prev_cnums : Vec < ( u32 , String , CrateDisambiguator ) > ,
58
62
}
59
63
60
64
type EncodedPrevDiagnostics = Vec < ( SerializedDepNodeIndex , Vec < Diagnostic > ) > ;
@@ -94,6 +98,8 @@ impl<'sess> OnDiskCache<'sess> {
94
98
OnDiskCache {
95
99
prev_diagnostics,
96
100
_prev_filemap_starts : header. prev_filemap_starts ,
101
+ prev_cnums : header. prev_cnums ,
102
+ cnum_map : RefCell :: new ( None ) ,
97
103
codemap : sess. codemap ( ) ,
98
104
current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
99
105
}
@@ -103,13 +109,16 @@ impl<'sess> OnDiskCache<'sess> {
103
109
OnDiskCache {
104
110
prev_diagnostics : FxHashMap ( ) ,
105
111
_prev_filemap_starts : BTreeMap :: new ( ) ,
112
+ prev_cnums : vec ! [ ] ,
113
+ cnum_map : RefCell :: new ( None ) ,
106
114
codemap,
107
115
current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
108
116
}
109
117
}
110
118
111
119
pub fn serialize < ' a , ' gcx , ' lcx , E > ( & self ,
112
120
tcx : TyCtxt < ' a , ' gcx , ' lcx > ,
121
+ cstore : & CrateStore ,
113
122
encoder : & mut E )
114
123
-> Result < ( ) , E :: Error >
115
124
where E : ty_codec:: TyEncoder
@@ -124,15 +133,30 @@ impl<'sess> OnDiskCache<'sess> {
124
133
definitions : tcx. hir . definitions ( ) ,
125
134
} ;
126
135
136
+
137
+ // Encode the file header
127
138
let prev_filemap_starts: BTreeMap < _ , _ > = self
128
139
. codemap
129
140
. files ( )
130
141
. iter ( )
131
142
. map ( |fm| ( fm. start_pos , StableFilemapId :: new ( fm) ) )
132
143
. collect ( ) ;
133
144
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 ( ) ;
135
152
153
+ Header {
154
+ prev_filemap_starts,
155
+ prev_cnums,
156
+ } . encode ( & mut encoder) ?;
157
+
158
+
159
+ // Encode Diagnostics
136
160
let diagnostics: EncodedPrevDiagnostics =
137
161
self . current_diagnostics
138
162
. borrow ( )
@@ -142,7 +166,16 @@ impl<'sess> OnDiskCache<'sess> {
142
166
143
167
diagnostics. encode ( & mut encoder) ?;
144
168
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
+ }
146
179
}
147
180
148
181
/// Load a diagnostic emitted during the previous compilation session.
@@ -178,6 +211,40 @@ impl<'sess> OnDiskCache<'sess> {
178
211
179
212
x. extend ( diagnostics. into_iter ( ) ) ;
180
213
}
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
+ }
181
248
}
182
249
183
250
0 commit comments