rustc_incremental/persist/
work_product.rs

1//! Functions for saving and removing intermediate [work products].
2//!
3//! [work products]: WorkProduct
4
5use std::fs as std_fs;
6use std::path::{Path, PathBuf};
7
8use rustc_data_structures::unord::UnordMap;
9use rustc_fs_util::link_or_copy;
10use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
11use rustc_session::Session;
12use tracing::debug;
13
14use crate::errors;
15use crate::persist::fs::*;
16
17/// Copies a CGU work product to the incremental compilation directory, so next compilation can
18/// find and reuse it.
19pub fn copy_cgu_workproduct_to_incr_comp_cache_dir(
20    sess: &Session,
21    cgu_name: &str,
22    files: &[(&'static str, &Path)],
23    known_links: &[PathBuf],
24) -> Option<(WorkProductId, WorkProduct)> {
25    debug!(?cgu_name, ?files);
26    sess.opts.incremental.as_ref()?;
27
28    let mut saved_files = UnordMap::default();
29    for (ext, path) in files {
30        let file_name = format!("{cgu_name}.{ext}");
31        let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
32        if known_links.contains(&path_in_incr_dir) {
33            let _ = saved_files.insert(ext.to_string(), file_name);
34            continue;
35        }
36        match link_or_copy(path, &path_in_incr_dir) {
37            Ok(_) => {
38                let _ = saved_files.insert(ext.to_string(), file_name);
39            }
40            Err(err) => {
41                sess.dcx().emit_warn(errors::CopyWorkProductToCache {
42                    from: path,
43                    to: &path_in_incr_dir,
44                    err,
45                });
46            }
47        }
48    }
49
50    let work_product = WorkProduct { cgu_name: cgu_name.to_string(), saved_files };
51    debug!(?work_product);
52    let work_product_id = WorkProductId::from_cgu_name(cgu_name);
53    Some((work_product_id, work_product))
54}
55
56/// Removes files for a given work product.
57pub(crate) fn delete_workproduct_files(sess: &Session, work_product: &WorkProduct) {
58    for (_, path) in work_product.saved_files.items().into_sorted_stable_ord() {
59        let path = in_incr_comp_dir_sess(sess, path);
60        if let Err(err) = std_fs::remove_file(&path) {
61            sess.dcx().emit_warn(errors::DeleteWorkProduct { path: &path, err });
62        }
63    }
64}