Skip to main content

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::{IncrCompSession, Session};
12use tracing::debug;
13
14use crate::diagnostics;
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.
19///
20/// Panics when incr comp is disabled.
21pub fn copy_cgu_workproduct_to_incr_comp_cache_dir(
22    sess: &Session,
23    incr_comp_session: &IncrCompSession,
24    cgu_name: &str,
25    files: &[(&'static str, &Path)],
26    known_links: &[PathBuf],
27) -> (WorkProductId, WorkProduct) {
28    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_incremental/src/persist/work_product.rs:28",
                        "rustc_incremental::persist::work_product",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_incremental/src/persist/work_product.rs"),
                        ::tracing_core::__macro_support::Option::Some(28u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_incremental::persist::work_product"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("cgu_name")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("cgu_name");
                                            NAME.as_str()
                                        },
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("files")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("files");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cgu_name)
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&files)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(?cgu_name, ?files);
29    if !sess.opts.incremental.is_some() {
    ::core::panicking::panic("assertion failed: sess.opts.incremental.is_some()")
};assert!(sess.opts.incremental.is_some());
30
31    let mut saved_files = UnordMap::default();
32    for (ext, path) in files {
33        let file_name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}.{1}", cgu_name, ext))
    })format!("{cgu_name}.{ext}");
34        let path_in_incr_dir = in_incr_comp_dir_sess(incr_comp_session, &file_name);
35        if known_links.contains(&path_in_incr_dir) {
36            let _ = saved_files.insert(ext.to_string(), file_name);
37            continue;
38        }
39        match link_or_copy(path, &path_in_incr_dir) {
40            Ok(_) => {
41                let _ = saved_files.insert(ext.to_string(), file_name);
42            }
43            Err(err) => {
44                sess.dcx().emit_warn(diagnostics::CopyWorkProductToCache {
45                    from: path,
46                    to: &path_in_incr_dir,
47                    err,
48                });
49            }
50        }
51    }
52
53    let work_product = WorkProduct { cgu_name: cgu_name.to_string(), saved_files };
54    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_incremental/src/persist/work_product.rs:54",
                        "rustc_incremental::persist::work_product",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_incremental/src/persist/work_product.rs"),
                        ::tracing_core::__macro_support::Option::Some(54u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_incremental::persist::work_product"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("work_product")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("work_product");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&work_product)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(?work_product);
55    let work_product_id = WorkProductId::from_cgu_name(cgu_name);
56    (work_product_id, work_product)
57}
58
59/// Removes files for a given work product.
60pub(crate) fn delete_workproduct_files(
61    sess: &Session,
62    incr_comp_session: &IncrCompSession,
63    work_product: &WorkProduct,
64) {
65    for (_, path) in work_product.saved_files.items().into_sorted_stable_ord() {
66        let path = in_incr_comp_dir_sess(incr_comp_session, path);
67        if let Err(err) = std_fs::remove_file(&path) {
68            sess.dcx().emit_warn(diagnostics::DeleteWorkProduct { path: &path, err });
69        }
70    }
71}