@@ -38,40 +38,42 @@ impl Rustc {
3838 /// If successful this function returns a description of the compiler along
3939 /// with a list of its capabilities.
4040 pub fn new (
41- mut path : PathBuf ,
41+ mut rustc : PathBuf ,
4242 wrapper : Option < PathBuf > ,
4343 workspace_wrapper : Option < PathBuf > ,
4444 rustup_rustc : & Path ,
4545 cache_location : Option < PathBuf > ,
4646 ) -> CargoResult < Rustc > {
4747 let _p = profile:: start ( "Rustc::new" ) ;
4848
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+
4957 // In order to avoid calling through rustup multiple times, we first ask
5058 // rustc to give us the "resolved" rustc path, and use that instead. If
5159 // this doesn't give us a path, then we just use the original path such
5260 // that the following logic can handle any resulting errors normally.
53- let mut cmd = ProcessBuilder :: new ( & path ) ;
61+ let mut cmd = ProcessBuilder :: new ( & rustc ) ;
5462 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+ ) ;
6373 }
6474 }
6575
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) ;
7577 cmd. arg ( "-vV" ) ;
7678 let verbose_version = cache. cached_output ( & cmd, 0 ) ?. 0 ;
7779
@@ -98,7 +100,7 @@ impl Rustc {
98100 } ) ?;
99101
100102 Ok ( Rustc {
101- path,
103+ path : rustc ,
102104 wrapper,
103105 workspace_wrapper,
104106 verbose_version,
@@ -191,56 +193,14 @@ impl Cache {
191193 rustup_rustc : & Path ,
192194 cache_location : Option < PathBuf > ,
193195 ) -> Cache {
194- match (
196+ let mut this = Cache {
195197 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+ } ;
226201
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
244204 }
245205
246206 fn cached_output (
@@ -291,10 +251,63 @@ impl Cache {
291251 . into ( ) )
292252 }
293253 }
294- }
295254
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 ) {
298311 if !self . dirty {
299312 return ;
300313 }
@@ -305,6 +318,13 @@ impl Drop for Cache {
305318 Err ( e) => warn ! ( "failed to update rustc info cache: {}" , e) ,
306319 }
307320 }
321+ self . dirty = false ;
322+ }
323+ }
324+
325+ impl Drop for Cache {
326+ fn drop ( & mut self ) {
327+ self . flush ( ) ;
308328 }
309329}
310330
0 commit comments