@@ -38,40 +38,42 @@ impl Rustc {
38
38
/// If successful this function returns a description of the compiler along
39
39
/// with a list of its capabilities.
40
40
pub fn new (
41
- mut path : PathBuf ,
41
+ mut rustc : PathBuf ,
42
42
wrapper : Option < PathBuf > ,
43
43
workspace_wrapper : Option < PathBuf > ,
44
44
rustup_rustc : & Path ,
45
45
cache_location : Option < PathBuf > ,
46
46
) -> CargoResult < Rustc > {
47
47
let _p = profile:: start ( "Rustc::new" ) ;
48
48
49
+ let mut cache = Cache :: load (
50
+ wrapper. as_deref ( ) ,
51
+ workspace_wrapper. as_deref ( ) ,
52
+ & rustc,
53
+ rustup_rustc,
54
+ cache_location,
55
+ ) ;
56
+
49
57
// In order to avoid calling through rustup multiple times, we first ask
50
58
// rustc to give us the "resolved" rustc path, and use that instead. If
51
59
// this doesn't give us a path, then we just use the original path such
52
60
// that the following logic can handle any resulting errors normally.
53
- let mut cmd = ProcessBuilder :: new ( & path ) ;
61
+ let mut cmd = ProcessBuilder :: new ( & rustc ) ;
54
62
cmd. arg ( "--print=rustc-path" ) ;
55
- if let Ok ( output) = cmd. output ( ) {
56
- if output. status . success ( ) {
57
- if let Ok ( resolved) = String :: from_utf8 ( output. stdout ) {
58
- let resolved = PathBuf :: from ( resolved. trim ( ) ) ;
59
- if resolved. exists ( ) {
60
- path = resolved;
61
- }
62
- }
63
+ if let Ok ( ( stdout, _) ) = cache. cached_output ( & cmd, 0 ) {
64
+ let resolved = PathBuf :: from ( stdout. trim ( ) ) ;
65
+ if resolved. exists ( ) {
66
+ rustc = resolved;
67
+ cache. reset (
68
+ wrapper. as_deref ( ) ,
69
+ workspace_wrapper. as_deref ( ) ,
70
+ & rustc,
71
+ rustup_rustc,
72
+ ) ;
63
73
}
64
74
}
65
75
66
- let mut cache = Cache :: load (
67
- wrapper. as_deref ( ) ,
68
- workspace_wrapper. as_deref ( ) ,
69
- & path,
70
- rustup_rustc,
71
- cache_location,
72
- ) ;
73
-
74
- let mut cmd = ProcessBuilder :: new ( & path) ;
76
+ let mut cmd = ProcessBuilder :: new ( & rustc) ;
75
77
cmd. arg ( "-vV" ) ;
76
78
let verbose_version = cache. cached_output ( & cmd, 0 ) ?. 0 ;
77
79
@@ -98,7 +100,7 @@ impl Rustc {
98
100
} ) ?;
99
101
100
102
Ok ( Rustc {
101
- path,
103
+ path : rustc ,
102
104
wrapper,
103
105
workspace_wrapper,
104
106
verbose_version,
@@ -191,56 +193,14 @@ impl Cache {
191
193
rustup_rustc : & Path ,
192
194
cache_location : Option < PathBuf > ,
193
195
) -> Cache {
194
- match (
196
+ let mut this = Cache {
195
197
cache_location,
196
- rustc_fingerprint ( wrapper, workspace_wrapper, rustc, rustup_rustc) ,
197
- ) {
198
- ( Some ( cache_location) , Ok ( rustc_fingerprint) ) => {
199
- let empty = CacheData {
200
- rustc_fingerprint,
201
- outputs : HashMap :: new ( ) ,
202
- successes : HashMap :: new ( ) ,
203
- } ;
204
- let mut dirty = true ;
205
- let data = match read ( & cache_location) {
206
- Ok ( data) => {
207
- if data. rustc_fingerprint == rustc_fingerprint {
208
- debug ! ( "reusing existing rustc info cache" ) ;
209
- dirty = false ;
210
- data
211
- } else {
212
- debug ! ( "different compiler, creating new rustc info cache" ) ;
213
- empty
214
- }
215
- }
216
- Err ( e) => {
217
- debug ! ( "failed to read rustc info cache: {}" , e) ;
218
- empty
219
- }
220
- } ;
221
- return Cache {
222
- cache_location : Some ( cache_location) ,
223
- dirty,
224
- data,
225
- } ;
198
+ dirty : false ,
199
+ data : CacheData :: default ( ) ,
200
+ } ;
226
201
227
- fn read ( path : & Path ) -> CargoResult < CacheData > {
228
- let json = paths:: read ( path) ?;
229
- Ok ( serde_json:: from_str ( & json) ?)
230
- }
231
- }
232
- ( _, fingerprint) => {
233
- if let Err ( e) = fingerprint {
234
- warn ! ( "failed to calculate rustc fingerprint: {}" , e) ;
235
- }
236
- debug ! ( "rustc info cache disabled" ) ;
237
- Cache {
238
- cache_location : None ,
239
- dirty : false ,
240
- data : CacheData :: default ( ) ,
241
- }
242
- }
243
- }
202
+ this. reset ( wrapper, workspace_wrapper, rustc, rustup_rustc) ;
203
+ this
244
204
}
245
205
246
206
fn cached_output (
@@ -291,10 +251,63 @@ impl Cache {
291
251
. into ( ) )
292
252
}
293
253
}
294
- }
295
254
296
- impl Drop for Cache {
297
- fn drop ( & mut self ) {
255
+ fn reset (
256
+ & mut self ,
257
+ wrapper : Option < & Path > ,
258
+ workspace_wrapper : Option < & Path > ,
259
+ rustc : & Path ,
260
+ rustup_rustc : & Path ,
261
+ ) {
262
+ self . flush ( ) ;
263
+ match (
264
+ & self . cache_location ,
265
+ rustc_fingerprint ( wrapper, workspace_wrapper, rustc, rustup_rustc) ,
266
+ ) {
267
+ ( Some ( cache_location) , Ok ( rustc_fingerprint) ) => {
268
+ let empty = CacheData {
269
+ rustc_fingerprint,
270
+ outputs : HashMap :: new ( ) ,
271
+ successes : HashMap :: new ( ) ,
272
+ } ;
273
+ self . dirty = true ;
274
+ self . data = match read ( & cache_location) {
275
+ Ok ( data) => {
276
+ if data. rustc_fingerprint == rustc_fingerprint {
277
+ debug ! ( "reusing existing rustc info cache" ) ;
278
+ self . dirty = false ;
279
+ data
280
+ } else {
281
+ debug ! ( "different compiler, creating new rustc info cache" ) ;
282
+ empty
283
+ }
284
+ }
285
+ Err ( e) => {
286
+ debug ! ( "failed to read rustc info cache: {}" , e) ;
287
+ empty
288
+ }
289
+ } ;
290
+
291
+ fn read ( path : & Path ) -> CargoResult < CacheData > {
292
+ let json = paths:: read ( path) ?;
293
+ Ok ( serde_json:: from_str ( & json) ?)
294
+ }
295
+ }
296
+ ( _, fingerprint) => {
297
+ if let Err ( e) = fingerprint {
298
+ warn ! ( "failed to calculate rustc fingerprint: {}" , e) ;
299
+ }
300
+ debug ! ( "rustc info cache disabled" ) ;
301
+ * self = Cache {
302
+ cache_location : None ,
303
+ dirty : false ,
304
+ data : CacheData :: default ( ) ,
305
+ }
306
+ }
307
+ }
308
+ }
309
+
310
+ fn flush ( & mut self ) {
298
311
if !self . dirty {
299
312
return ;
300
313
}
@@ -305,6 +318,13 @@ impl Drop for Cache {
305
318
Err ( e) => warn ! ( "failed to update rustc info cache: {}" , e) ,
306
319
}
307
320
}
321
+ self . dirty = false ;
322
+ }
323
+ }
324
+
325
+ impl Drop for Cache {
326
+ fn drop ( & mut self ) {
327
+ self . flush ( ) ;
308
328
}
309
329
}
310
330
0 commit comments