rustc_incremental/persist/
save.rs1use std::fs;
2use std::sync::Arc;
3
4use rustc_data_structures::fx::FxIndexMap;
5use rustc_data_structures::sync::join;
6use rustc_middle::dep_graph::{
7 DepGraph, SerializedDepGraph, WorkProduct, WorkProductId, WorkProductMap,
8};
9use rustc_middle::ty::TyCtxt;
10use rustc_serialize::Encodable as RustcEncodable;
11use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
12use rustc_session::Session;
13use tracing::debug;
14
15use super::data::*;
16use super::fs::*;
17use super::{dirty_clean, file_format, work_product};
18use crate::assert_dep_graph::assert_dep_graph;
19use crate::errors;
20
21pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) {
29 {
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/save.rs:29",
"rustc_incremental::persist::save", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_incremental/src/persist/save.rs"),
::tracing_core::__macro_support::Option::Some(29u32),
::tracing_core::__macro_support::Option::Some("rustc_incremental::persist::save"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("save_dep_graph()")
as &dyn Value))])
});
} else { ; }
};debug!("save_dep_graph()");
30 tcx.dep_graph.with_ignore(|| {
31 let sess = tcx.sess;
32 if sess.opts.incremental.is_none() {
33 return;
34 }
35 if sess.dcx().has_errors_or_delayed_bugs().is_some() {
37 return;
38 }
39
40 let query_cache_path = query_cache_path(sess);
41 let dep_graph_path = dep_graph_path(sess);
42 let staging_dep_graph_path = staging_dep_graph_path(sess);
43
44 sess.time("assert_dep_graph", || assert_dep_graph(tcx));
45 sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx));
46
47 join(
48 move || {
49 sess.time("incr_comp_persist_dep_graph", || {
50 if let Err(err) = fs::rename(&staging_dep_graph_path, &dep_graph_path) {
51 sess.dcx().emit_err(errors::MoveDepGraph {
52 from: &staging_dep_graph_path,
53 to: &dep_graph_path,
54 err,
55 });
56 }
57 });
58 },
59 move || {
60 sess.time("incr_comp_persist_result_cache", || {
63 if let Some(odc) = &tcx.query_system.on_disk_cache {
65 odc.drop_serialized_data(tcx);
66 }
67
68 file_format::save_in(sess, query_cache_path, "query cache", |e| {
69 encode_query_cache(tcx, e)
70 });
71 });
72 },
73 );
74 })
75}
76
77pub fn save_work_product_index(
79 sess: &Session,
80 dep_graph: &DepGraph,
81 new_work_products: FxIndexMap<WorkProductId, WorkProduct>,
82) {
83 if sess.opts.incremental.is_none() {
84 return;
85 }
86 if sess.dcx().has_errors().is_some() {
88 return;
89 }
90
91 {
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/save.rs:91",
"rustc_incremental::persist::save", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_incremental/src/persist/save.rs"),
::tracing_core::__macro_support::Option::Some(91u32),
::tracing_core::__macro_support::Option::Some("rustc_incremental::persist::save"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("save_work_product_index()")
as &dyn Value))])
});
} else { ; }
};debug!("save_work_product_index()");
92 dep_graph.assert_ignored();
93 let path = work_products_path(sess);
94 file_format::save_in(sess, path, "work product index", |mut e| {
95 encode_work_product_index(&new_work_products, &mut e);
96 e.finish()
97 });
98
99 let previous_work_products = dep_graph.previous_work_products();
103 for (id, wp) in previous_work_products.to_sorted_stable_ord() {
104 if !new_work_products.contains_key(id) {
105 work_product::delete_workproduct_files(sess, wp);
106 if true {
if !!wp.saved_files.items().all(|(_, path)|
in_incr_comp_dir_sess(sess, path).exists()) {
::core::panicking::panic("assertion failed: !wp.saved_files.items().all(|(_, path)|\n in_incr_comp_dir_sess(sess, path).exists())")
};
};debug_assert!(
107 !wp.saved_files.items().all(|(_, path)| in_incr_comp_dir_sess(sess, path).exists())
108 );
109 }
110 }
111
112 if true {
if !{
new_work_products.iter().all(|(_, wp)|
{
wp.saved_files.items().all(|(_, path)|
in_incr_comp_dir_sess(sess, path).exists())
})
} {
::core::panicking::panic("assertion failed: {\n new_work_products.iter().all(|(_, wp)|\n {\n wp.saved_files.items().all(|(_, path)|\n in_incr_comp_dir_sess(sess, path).exists())\n })\n}")
};
};debug_assert!({
114 new_work_products.iter().all(|(_, wp)| {
115 wp.saved_files.items().all(|(_, path)| in_incr_comp_dir_sess(sess, path).exists())
116 })
117 });
118}
119
120fn encode_work_product_index(
121 work_products: &FxIndexMap<WorkProductId, WorkProduct>,
122 encoder: &mut FileEncoder,
123) {
124 let serialized_products: Vec<_> = work_products
125 .iter()
126 .map(|(id, work_product)| SerializedWorkProduct {
127 id: *id,
128 work_product: work_product.clone(),
129 })
130 .collect();
131
132 serialized_products.encode(encoder)
133}
134
135fn encode_query_cache(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult {
136 tcx.sess.time("incr_comp_serialize_result_cache", || tcx.serialize_query_result_cache(encoder))
137}
138
139pub(crate) fn build_dep_graph(
146 sess: &Session,
147 prev_graph: Arc<SerializedDepGraph>,
148 prev_work_products: WorkProductMap,
149) -> Option<DepGraph> {
150 if sess.opts.incremental.is_none() {
151 return None;
153 }
154
155 let path_buf = staging_dep_graph_path(sess);
157
158 let mut encoder = match FileEncoder::new(&path_buf) {
159 Ok(encoder) => encoder,
160 Err(err) => {
161 sess.dcx().emit_err(errors::CreateDepGraph { path: &path_buf, err });
162 return None;
163 }
164 };
165
166 file_format::write_file_header(&mut encoder, sess);
167
168 sess.opts.dep_tracking_hash(false).encode(&mut encoder);
170
171 Some(DepGraph::new(sess, prev_graph, prev_work_products, encoder))
172}