Skip to content

Commit e76de76

Browse files
committed
Rust rustc --print=rust-path through the cache
1 parent e6bd7a6 commit e76de76

File tree

1 file changed

+91
-71
lines changed

1 file changed

+91
-71
lines changed

src/cargo/util/rustc.rs

Lines changed: 91 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)