From f9679fa4df238fff9060178ccca9adcb6a795a7d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 8 Jul 2026 19:07:34 +0000 Subject: [PATCH] Split IncrCompSession out of Session This will allow introducing a separate incr comp session dir for the post LTO artifacts in the future. In addition it statically encodes the lifetime of the incr comp session rather than requiring an enum behind a mutex stored in the Session. --- compiler/rustc_codegen_cranelift/src/lib.rs | 5 +- compiler/rustc_codegen_gcc/src/lib.rs | 5 +- compiler/rustc_codegen_llvm/src/lib.rs | 5 +- compiler/rustc_codegen_ssa/src/back/write.rs | 25 ++++- .../rustc_codegen_ssa/src/traits/backend.rs | 3 +- compiler/rustc_driver_impl/src/lib.rs | 4 +- compiler/rustc_incremental/src/persist/fs.rs | 48 ++++---- .../rustc_incremental/src/persist/load.rs | 105 ++++++++++-------- .../rustc_incremental/src/persist/save.rs | 24 ++-- .../src/persist/work_product.rs | 13 ++- compiler/rustc_interface/src/passes.rs | 16 ++- compiler/rustc_interface/src/queries.rs | 20 +++- compiler/rustc_interface/src/util.rs | 3 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 5 +- compiler/rustc_session/src/session.rs | 65 ++--------- src/librustdoc/doctest.rs | 55 ++++----- src/librustdoc/lib.rs | 33 +++--- .../codegen-backend/auxiliary/the_backend.rs | 3 +- tests/ui-fulldeps/run-compiler-twice.rs | 11 +- 20 files changed, 235 insertions(+), 215 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index ba586f83ba30d..8ee0e71d82dec 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -41,8 +41,8 @@ use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig, back}; use rustc_log::tracing::info; use rustc_middle::dep_graph::WorkProductMap; -use rustc_session::Session; use rustc_session::config::{NATIVE_CPU, OutputFilenames}; +use rustc_session::{IncrCompSession, Session}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{Arch, CfgAbi, Env, Os}; @@ -233,13 +233,14 @@ impl CodegenBackend for CraneliftCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, + incr_comp_session: Option<&IncrCompSession>, _outputs: &OutputFilenames, crate_info: &CrateInfo, ) -> (CompiledModules, WorkProductMap) { ongoing_codegen .downcast::>() .unwrap() - .join(sess, crate_info) + .join(sess, incr_comp_session, crate_info) } fn fallback_intrinsics(&self) -> Vec { diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 4cc4a2d258d14..c570f4e2165b2 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -94,8 +94,8 @@ use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; -use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames}; +use rustc_session::{IncrCompSession, Session}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{Arch, RelocModel}; use tempfile::TempDir; @@ -297,13 +297,14 @@ impl CodegenBackend for GccCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, + incr_comp_session: Option<&IncrCompSession>, _outputs: &OutputFilenames, crate_info: &CrateInfo, ) -> (CompiledModules, WorkProductMap) { ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") - .join(sess, crate_info) + .join(sess, incr_comp_session, crate_info) } fn target_config(&self, sess: &Session) -> TargetConfig { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 1dd460c409737..3c095d9e07ad0 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -38,8 +38,8 @@ use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; -use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest}; +use rustc_session::{IncrCompSession, Session}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{RelocModel, TlsModel}; @@ -379,13 +379,14 @@ impl CodegenBackend for LlvmCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, + incr_comp_session: Option<&IncrCompSession>, outputs: &OutputFilenames, crate_info: &CrateInfo, ) -> (CompiledModules, WorkProductMap) { let (compiled_modules, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") - .join(sess, crate_info); + .join(sess, incr_comp_session, crate_info); if sess.opts.unstable_opts.llvm_time_trace { sess.time("llvm_dump_timing_file", || { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 1db2321f7b249..750a4e8c3bde6 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -21,11 +21,11 @@ use rustc_metadata::fs::copy_to_stdout; use rustc_middle::bug; use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; -use rustc_session::Session; use rustc_session::config::{ self, CrateType, Lto, OptLevel, OutFileName, OutputFilenames, OutputType, Passes, SwitchWithOptPath, }; +use rustc_session::{IncrCompSession, Session}; use rustc_span::source_map::SourceMap; use rustc_span::{FileName, InnerSpan, Span, SpanData}; use rustc_target::spec::{MergeFunctions, SanitizerSet}; @@ -461,6 +461,7 @@ pub(crate) fn start_async_codegen( fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( sess: &Session, + incr_comp_session: Option<&IncrCompSession>, compiled_modules: &CompiledModules, ) -> WorkProductMap { let mut work_products = WorkProductMap::default(); @@ -494,6 +495,7 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( } let (id, product) = copy_cgu_workproduct_to_incr_comp_cache_dir( sess, + incr_comp_session.unwrap(), &module.name, files.as_slice(), &module.links_from_incr_cache, @@ -1286,7 +1288,10 @@ fn start_executing_work( time_trace: sess.opts.unstable_opts.llvm_time_trace, remark: sess.opts.cg.remark.clone(), remark_dir, - incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()), + incr_comp_session_dir: tcx + .incr_comp_session + .as_ref() + .map(|incr_comp_session| incr_comp_session.session_directory.clone()), output_filenames: Arc::clone(tcx.output_filenames(())), module_config: regular_config, opt_level, @@ -2118,7 +2123,12 @@ pub struct OngoingCodegen { } impl OngoingCodegen { - pub fn join(self, sess: &Session, crate_info: &CrateInfo) -> (CompiledModules, WorkProductMap) { + pub fn join( + self, + sess: &Session, + incr_comp_session: Option<&IncrCompSession>, + crate_info: &CrateInfo, + ) -> (CompiledModules, WorkProductMap) { self.shared_emitter_main.check(sess, true); let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() { @@ -2196,8 +2206,11 @@ impl OngoingCodegen { // out deterministic results. compiled_modules.modules.sort_by(|a, b| a.name.cmp(&b.name)); - let work_products = - copy_all_cgu_workproducts_to_incr_comp_cache_dir(sess, &compiled_modules); + let work_products = copy_all_cgu_workproducts_to_incr_comp_cache_dir( + sess, + incr_comp_session, + &compiled_modules, + ); produce_final_output_artifacts(sess, &compiled_modules, &self.output_filenames); (compiled_modules, work_products) @@ -2249,7 +2262,7 @@ pub(crate) fn submit_pre_lto_module_to_llvm( module: CachedModuleCodegen, ) { let filename = pre_lto_bitcode_filename(&module.name); - let bitcode_path = in_incr_comp_dir_sess(tcx.sess, &filename); + let bitcode_path = in_incr_comp_dir_sess(tcx.incr_comp_session.unwrap(), &filename); // Schedule the module to be loaded drop( coordinator diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 6014f1af4bfc3..85882af9e7cd0 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -8,8 +8,8 @@ use rustc_metadata::creader::MetadataLoaderDyn; use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; -use rustc_session::Session; use rustc_session::config::{CrateType, OutputFilenames, PrintRequest}; +use rustc_session::{IncrCompSession, Session}; use rustc_span::Symbol; use super::CodegenObject; @@ -127,6 +127,7 @@ pub trait CodegenBackend { &self, ongoing_codegen: Box, sess: &Session, + incr_comp_session: Option<&IncrCompSession>, outputs: &OutputFilenames, crate_info: &CrateInfo, ) -> (CompiledModules, WorkProductMap); diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 4411ecb4f128b..6274397fe2b6a 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -336,8 +336,8 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) // Linking is done outside the `compiler.enter()` so that the // `GlobalCtxt` within `Queries` can be freed as early as possible. - if let Some(linker) = linker { - linker.link(sess, codegen_backend); + if let (Some(linker), incr_comp_session) = linker { + linker.link(sess, incr_comp_session, codegen_backend); } }) } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index c40aa49c29d11..de543ef0c53bc 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -116,7 +116,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_data_structures::{base_n, flock}; use rustc_fs_util::{LinkOrCopy, link_or_copy, try_canonicalize}; use rustc_middle::bug; -use rustc_session::{Session, StableCrateId}; +use rustc_session::{IncrCompSession, Session, StableCrateId}; use rustc_span::Symbol; use tracing::debug; @@ -138,25 +138,25 @@ const QUERY_CACHE_FILENAME: &str = "query-cache.bin"; const INT_ENCODE_BASE: usize = base_n::CASE_INSENSITIVE; /// Returns the path to a session's dependency graph. -pub(crate) fn dep_graph_path(sess: &Session) -> PathBuf { - in_incr_comp_dir_sess(sess, DEP_GRAPH_FILENAME) +pub(crate) fn dep_graph_path(incr_comp_session: &IncrCompSession) -> PathBuf { + in_incr_comp_dir_sess(incr_comp_session, DEP_GRAPH_FILENAME) } /// Returns the path to a session's staging dependency graph. /// /// On the difference between dep-graph and staging dep-graph, /// see `build_dep_graph`. -pub(crate) fn staging_dep_graph_path(sess: &Session) -> PathBuf { - in_incr_comp_dir_sess(sess, STAGING_DEP_GRAPH_FILENAME) +pub(crate) fn staging_dep_graph_path(incr_comp_session: &IncrCompSession) -> PathBuf { + in_incr_comp_dir_sess(incr_comp_session, STAGING_DEP_GRAPH_FILENAME) } -pub(crate) fn work_products_path(sess: &Session) -> PathBuf { - in_incr_comp_dir_sess(sess, WORK_PRODUCTS_FILENAME) +pub(crate) fn work_products_path(incr_comp_session: &IncrCompSession) -> PathBuf { + in_incr_comp_dir_sess(incr_comp_session, WORK_PRODUCTS_FILENAME) } /// Returns the path to a session's query cache. -pub(crate) fn query_cache_path(sess: &Session) -> PathBuf { - in_incr_comp_dir_sess(sess, QUERY_CACHE_FILENAME) +pub(crate) fn query_cache_path(incr_comp_session: &IncrCompSession) -> PathBuf { + in_incr_comp_dir_sess(incr_comp_session, QUERY_CACHE_FILENAME) } /// Locks a given session directory. @@ -183,8 +183,8 @@ fn lock_file_path(session_dir: &Path) -> PathBuf { /// Returns the path for a given filename within the incremental compilation directory /// in the current session. -pub fn in_incr_comp_dir_sess(sess: &Session, file_name: &str) -> PathBuf { - sess.incr_comp_session_dir().join(file_name) +pub fn in_incr_comp_dir_sess(incr_comp_session: &IncrCompSession, file_name: &str) -> PathBuf { + incr_comp_session.session_directory.join(file_name) } /// Allocates the private session directory. @@ -206,7 +206,7 @@ pub(crate) fn prepare_session_directory( sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId, -) { +) -> IncrCompSession { assert!(sess.opts.incremental.is_some()); let _timer = sess.timer("incr_comp_prepare_session_directory"); @@ -257,8 +257,7 @@ pub(crate) fn prepare_session_directory( directory." ); - sess.init_incr_comp_session(session_dir, directory_lock); - return; + return IncrCompSession { session_directory: session_dir, _lock_file: directory_lock }; }; debug!("attempting to copy data from source: {}", source_directory.display()); @@ -271,8 +270,7 @@ pub(crate) fn prepare_session_directory( sess.dcx().emit_warn(diagnostics::HardLinkFailed { path: &session_dir }); } - sess.init_incr_comp_session(session_dir, directory_lock); - return; + return IncrCompSession { session_directory: session_dir, _lock_file: directory_lock }; } else { debug!("copying failed - trying next directory"); @@ -295,18 +293,23 @@ pub(crate) fn prepare_session_directory( /// This function finalizes and thus 'publishes' the session directory by /// renaming it to `s-{timestamp}-{svh}` and releasing the file lock. /// This must not be called if there have been any compilation errors. -pub fn finalize_session_directory(sess: &Session, svh: Option) { +pub fn finalize_session_directory( + sess: &Session, + incr_comp_session: Option, + svh: Option, +) { assert!(sess.dcx().has_errors_or_delayed_bugs().is_none()); if sess.opts.incremental.is_none() { return; } + let incr_comp_session = incr_comp_session.unwrap(); // The svh is always produced when incr. comp. is enabled. let svh = svh.unwrap(); let _timer = sess.timer("incr_comp_finalize_session_directory"); - let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone(); + let incr_comp_session_dir = incr_comp_session.session_directory.clone(); debug!("finalize_session_directory() - session directory: {}", incr_comp_session_dir.display()); @@ -342,14 +345,15 @@ pub fn finalize_session_directory(sess: &Session, svh: Option) { } } - // This unlocks the directory - sess.finalize_incr_comp_session(); + drop(incr_comp_session); // Unlock incr comp session dir let _ = garbage_collect_session_directories(sess, &new_path); } -pub(crate) fn delete_all_session_dir_contents(sess: &Session) -> io::Result<()> { - let sess_dir_iterator = sess.incr_comp_session_dir().read_dir()?; +pub(crate) fn delete_all_session_dir_contents( + incr_comp_session: &IncrCompSession, +) -> io::Result<()> { + let sess_dir_iterator = incr_comp_session.session_directory.read_dir()?; for entry in sess_dir_iterator { let entry = entry?; safe_remove_file(&entry.path())? diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 352ee59aaa0d4..3cf08961ed7b3 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -11,7 +11,7 @@ use rustc_middle::query::on_disk_cache::OnDiskCache; use rustc_serialize::opaque::{FileEncoder, MemDecoder}; use rustc_serialize::{Decodable, Encodable}; use rustc_session::config::IncrementalStateAssertion; -use rustc_session::{Session, StableCrateId}; +use rustc_session::{IncrCompSession, Session, StableCrateId}; use rustc_span::Symbol; use tracing::{debug, warn}; @@ -32,56 +32,55 @@ enum LoadResult { IoError { path: PathBuf, err: io::Error }, } -fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) { +fn delete_dirty_work_product( + sess: &Session, + incr_comp_session: &IncrCompSession, + swp: SerializedWorkProduct, +) { debug!("delete_dirty_work_product({:?})", swp); - work_product::delete_workproduct_files(sess, &swp.work_product); + work_product::delete_workproduct_files(sess, incr_comp_session, &swp.work_product); } -fn load_dep_graph(sess: &Session) -> LoadResult { +fn load_dep_graph(sess: &Session, incr_comp_session: &IncrCompSession) -> LoadResult { assert!(sess.opts.incremental.is_some()); let _timer = sess.prof.generic_activity("incr_comp_prepare_load_dep_graph"); // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`. // Fortunately, we just checked that this isn't the case. - let path = dep_graph_path(sess); + let path = dep_graph_path(incr_comp_session); let expected_hash = sess.opts.dep_tracking_hash(false); let mut prev_work_products = UnordMap::default(); - // If we are only building with -Zquery-dep-graph but without an actual - // incr. comp. session directory, we skip this. Otherwise we'd fail - // when trying to load work products. - if sess.incr_comp_session_dir_opt().is_some() { - let work_products_path = work_products_path(sess); - - if let Ok(OpenFile { mmap, start_pos }) = - file_format::open_incremental_file(sess, &work_products_path) - { - // Decode the list of work_products - let Ok(mut work_product_decoder) = MemDecoder::new(&mmap[..], start_pos) else { - sess.dcx().emit_warn(diagnostics::CorruptFile { path: &work_products_path }); - return LoadResult::DataOutOfDate; - }; - let work_products: Vec = - Decodable::decode(&mut work_product_decoder); - - for swp in work_products { - let all_files_exist = swp.work_product.saved_files.items().all(|(_, path)| { - let exists = in_incr_comp_dir_sess(sess, path).exists(); - if !exists && sess.opts.unstable_opts.incremental_info { - eprintln!("incremental: could not find file for work product: {path}",); - } - exists - }); - - if all_files_exist { - debug!("reconcile_work_products: all files for {:?} exist", swp); - prev_work_products.insert(swp.id, swp.work_product); - } else { - debug!("reconcile_work_products: some file for {:?} does not exist", swp); - delete_dirty_work_product(sess, swp); + let work_products_path = work_products_path(incr_comp_session); + + if let Ok(OpenFile { mmap, start_pos }) = + file_format::open_incremental_file(sess, &work_products_path) + { + // Decode the list of work_products + let Ok(mut work_product_decoder) = MemDecoder::new(&mmap[..], start_pos) else { + sess.dcx().emit_warn(diagnostics::CorruptFile { path: &work_products_path }); + return LoadResult::DataOutOfDate; + }; + let work_products: Vec = + Decodable::decode(&mut work_product_decoder); + + for swp in work_products { + let all_files_exist = swp.work_product.saved_files.items().all(|(_, path)| { + let exists = in_incr_comp_dir_sess(incr_comp_session, path).exists(); + if !exists && sess.opts.unstable_opts.incremental_info { + eprintln!("incremental: could not find file for work product: {path}",); } + exists + }); + + if all_files_exist { + debug!("reconcile_work_products: all files for {:?} exist", swp); + prev_work_products.insert(swp.id, swp.work_product); + } else { + debug!("reconcile_work_products: some file for {:?} does not exist", swp); + delete_dirty_work_product(sess, incr_comp_session, swp); } } } @@ -124,14 +123,18 @@ fn load_dep_graph(sess: &Session) -> LoadResult { /// If we are not in incremental compilation mode, returns `None`. /// Otherwise, tries to load the query result cache from disk, /// creating an empty cache if it could not be loaded. -pub fn load_query_result_cache(sess: &Session) -> Option { +pub fn load_query_result_cache( + sess: &Session, + incr_comp_session: Option<&IncrCompSession>, +) -> Option { if sess.opts.incremental.is_none() { return None; } + let incr_comp_session = incr_comp_session.unwrap(); let _prof_timer = sess.prof.generic_activity("incr_comp_load_query_result_cache"); - let path = query_cache_path(sess); + let path = query_cache_path(incr_comp_session); match file_format::open_incremental_file(sess, &path) { Ok(OpenFile { mmap, start_pos }) => { let cache = OnDiskCache::new(sess, mmap, start_pos).unwrap_or_else(|()| { @@ -181,18 +184,20 @@ pub fn setup_dep_graph( sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId, -) -> DepGraph { +) -> (DepGraph, Option) { if sess.opts.incremental.is_none() { - return DepGraph::new_disabled(); + return (DepGraph::new_disabled(), None); } // `load_dep_graph` can only be called after `prepare_session_directory`. - prepare_session_directory(sess, crate_name, stable_crate_id); + let incr_comp_session = prepare_session_directory(sess, crate_name, stable_crate_id); // Try to load the previous session's dep graph and work products. - let load_result = load_dep_graph(sess); + let load_result = load_dep_graph(sess, &incr_comp_session); sess.time("incr_comp_garbage_collect_session_directories", || { - if let Err(e) = garbage_collect_session_directories(sess, &sess.incr_comp_session_dir()) { + if let Err(e) = + garbage_collect_session_directories(sess, &incr_comp_session.session_directory) + { warn!( "Error while trying to garbage collect incremental compilation \ cache directory: {e}", @@ -209,9 +214,11 @@ pub fn setup_dep_graph( Default::default() } LoadResult::DataOutOfDate => { - if let Err(err) = delete_all_session_dir_contents(sess) { - sess.dcx() - .emit_err(diagnostics::DeleteIncompatible { path: dep_graph_path(sess), err }); + if let Err(err) = delete_all_session_dir_contents(&incr_comp_session) { + sess.dcx().emit_err(diagnostics::DeleteIncompatible { + path: dep_graph_path(&incr_comp_session), + err, + }); } Default::default() } @@ -219,7 +226,7 @@ pub fn setup_dep_graph( }; // Stream the dep-graph to an alternate file, to avoid overwriting anything in case of errors. - let path_buf = staging_dep_graph_path(sess); + let path_buf = staging_dep_graph_path(&incr_comp_session); let mut encoder = FileEncoder::new(&path_buf).unwrap_or_else(|err| { // We're in incremental mode but couldn't set up streaming output of the dep graph. @@ -232,5 +239,5 @@ pub fn setup_dep_graph( // First encode the commandline arguments hash sess.opts.dep_tracking_hash(false).encode(&mut encoder); - DepGraph::new(sess, prev_graph, prev_work_products, encoder) + (DepGraph::new(sess, prev_graph, prev_work_products, encoder), Some(incr_comp_session)) } diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 544ab66766f39..12f674fe2a859 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -6,7 +6,7 @@ use rustc_middle::query::on_disk_cache; use rustc_middle::ty::TyCtxt; use rustc_serialize::Encodable as RustcEncodable; use rustc_serialize::opaque::FileEncoder; -use rustc_session::Session; +use rustc_session::{IncrCompSession, Session}; use tracing::debug; use super::data::*; @@ -34,9 +34,10 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { return; } - let query_cache_path = query_cache_path(sess); - let dep_graph_path = dep_graph_path(sess); - let staging_dep_graph_path = staging_dep_graph_path(sess); + let incr_comp_session = tcx.incr_comp_session.unwrap(); + let query_cache_path = query_cache_path(incr_comp_session); + let dep_graph_path = dep_graph_path(incr_comp_session); + let staging_dep_graph_path = staging_dep_graph_path(incr_comp_session); sess.time("assert_dep_graph", || assert_dep_graph(tcx)); sess.time("check_clean", || clean::check_clean_annotations(tcx)); @@ -91,6 +92,7 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { /// Saves the work product index. pub fn save_work_product_index( sess: &Session, + incr_comp_session: Option<&IncrCompSession>, dep_graph: &DepGraph, new_work_products: WorkProductMap, ) { @@ -104,7 +106,7 @@ pub fn save_work_product_index( debug!("save_work_product_index()"); dep_graph.assert_ignored(); - let path = work_products_path(sess); + let path = work_products_path(incr_comp_session.unwrap()); file_format::save_in(sess, path, "work product index", |mut e| { encode_work_product_index(&new_work_products, &mut e); e.finish() @@ -116,9 +118,13 @@ pub fn save_work_product_index( let previous_work_products = dep_graph.previous_work_products(); for (id, wp) in previous_work_products.to_sorted_stable_ord() { if !new_work_products.contains_key(id) { - work_product::delete_workproduct_files(sess, wp); + work_product::delete_workproduct_files(sess, incr_comp_session.unwrap(), wp); debug_assert!( - !wp.saved_files.items().all(|(_, path)| in_incr_comp_dir_sess(sess, path).exists()) + !wp.saved_files.items().all(|(_, path)| in_incr_comp_dir_sess( + incr_comp_session.unwrap(), + path + ) + .exists()) ); } } @@ -126,7 +132,9 @@ pub fn save_work_product_index( // Check that we did not delete one of the current work-products: debug_assert!({ new_work_products.items().all(|(_, wp)| { - wp.saved_files.items().all(|(_, path)| in_incr_comp_dir_sess(sess, path).exists()) + wp.saved_files + .items() + .all(|(_, path)| in_incr_comp_dir_sess(incr_comp_session.unwrap(), path).exists()) }) }); } diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs index 910860bfafd6e..7bb66fee4d1a3 100644 --- a/compiler/rustc_incremental/src/persist/work_product.rs +++ b/compiler/rustc_incremental/src/persist/work_product.rs @@ -8,7 +8,7 @@ use std::path::{Path, PathBuf}; use rustc_data_structures::unord::UnordMap; use rustc_fs_util::link_or_copy; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; -use rustc_session::Session; +use rustc_session::{IncrCompSession, Session}; use tracing::debug; use crate::diagnostics; @@ -20,6 +20,7 @@ use crate::persist::fs::*; /// Panics when incr comp is disabled. pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( sess: &Session, + incr_comp_session: &IncrCompSession, cgu_name: &str, files: &[(&'static str, &Path)], known_links: &[PathBuf], @@ -30,7 +31,7 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( let mut saved_files = UnordMap::default(); for (ext, path) in files { let file_name = format!("{cgu_name}.{ext}"); - let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name); + let path_in_incr_dir = in_incr_comp_dir_sess(incr_comp_session, &file_name); if known_links.contains(&path_in_incr_dir) { let _ = saved_files.insert(ext.to_string(), file_name); continue; @@ -56,9 +57,13 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( } /// Removes files for a given work product. -pub(crate) fn delete_workproduct_files(sess: &Session, work_product: &WorkProduct) { +pub(crate) fn delete_workproduct_files( + sess: &Session, + incr_comp_session: &IncrCompSession, + work_product: &WorkProduct, +) { for (_, path) in work_product.saved_files.items().into_sorted_stable_ord() { - let path = in_incr_comp_dir_sess(sess, path); + let path = in_incr_comp_dir_sess(incr_comp_session, path); if let Err(err) = std_fs::remove_file(&path) { sess.dcx().emit_warn(diagnostics::DeleteWorkProduct { path: &path, err }); } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 2f32a6b208b6c..498b59cf5be9f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -35,12 +35,12 @@ use rustc_parse::lexer::StripTokens; use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_passes::{abi_test, input_stats, layout_test}; use rustc_resolve::{Resolver, ResolverOutputs}; -use rustc_session::Session; use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; use rustc_session::cstore::Untracked; use rustc_session::diagnostics::feature_err; use rustc_session::output::{filename_for_input, invalid_output_for_target}; use rustc_session::search_paths::PathKind; +use rustc_session::{IncrCompSession, Session}; use rustc_span::{ DUMMY_SP, ErrorGuaranteed, ExpnKind, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym, }; @@ -929,7 +929,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( compiler: &Compiler, krate: rustc_ast::Crate, f: F, -) -> T { +) -> (T, Option) { let sess = &compiler.sess; let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs); @@ -951,7 +951,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let outputs = util::build_output_filenames(&pre_configured_attrs, sess); - let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id); + let (dep_graph, incr_comp_session) = setup_dep_graph(sess, crate_name, stable_crate_id); let cstore = FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _); @@ -966,7 +966,8 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( // incr. comp. yet. dep_graph.assert_ignored(); - let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); + let query_result_on_disk_cache = + rustc_incremental::load_query_result_cache(sess, incr_comp_session.as_ref()); let codegen_backend = &compiler.codegen_backend; let mut providers = *DEFAULT_QUERY_PROVIDERS; @@ -993,7 +994,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let arena = WorkerLocal::new(|_| Arena::default()); let hir_arena = WorkerLocal::new(|_| rustc_hir::Arena::default()); - TyCtxt::create_global_ctxt( + let res = TyCtxt::create_global_ctxt( &gcx_cell, &compiler.sess, crate_types, @@ -1001,6 +1002,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( &arena, &hir_arena, untracked, + incr_comp_session.as_ref(), dep_graph, rustc_query_impl::make_dep_kind_vtables(&arena), rustc_query_impl::query_system( @@ -1046,7 +1048,9 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( tcx.finish(); res }, - ) + ); + + (res, incr_comp_session) } struct DiagCallback<'tcx> { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 24e033bdee088..490888f87b38e 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -9,8 +9,8 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{DepGraph, WorkProductMap}; use rustc_middle::ty::TyCtxt; -use rustc_session::Session; use rustc_session::config::{self, OutputFilenames, OutputType}; +use rustc_session::{IncrCompSession, Session}; use crate::diagnostics::FailedWritingFile; use crate::passes; @@ -46,7 +46,12 @@ impl Linker { } } - pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) { + pub fn link( + self, + sess: &Session, + incr_comp_session: Option, + codegen_backend: &dyn CodegenBackend, + ) { let (compiled_modules, mut work_products) = sess.time("finish_ongoing_codegen", || { match self.ongoing_codegen.downcast::() { // This was a check only build @@ -55,6 +60,7 @@ impl Linker { Err(ongoing_codegen) => codegen_backend.join_codegen( ongoing_codegen, sess, + incr_comp_session.as_ref(), &self.output_filenames, &self.crate_info, ), @@ -92,6 +98,7 @@ impl Linker { { let (id, product) = rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( sess, + incr_comp_session.as_ref().unwrap(), "metadata", &[("rmeta", path)], &[], @@ -106,7 +113,12 @@ impl Linker { let _timer = sess.timer("link"); sess.time("serialize_work_products", || { - rustc_incremental::save_work_product_index(sess, &self.dep_graph, work_products) + rustc_incremental::save_work_product_index( + sess, + incr_comp_session.as_ref(), + &self.dep_graph, + work_products, + ) }); let prof = sess.prof.clone(); @@ -114,7 +126,7 @@ impl Linker { // Now that we won't touch anything in the incremental compilation directory // any more, we can finalize it (which involves renaming it) - rustc_incremental::finalize_session_directory(sess, self.crate_hash); + rustc_incremental::finalize_session_directory(sess, incr_comp_session, self.crate_hash); if !sess .opts diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 39c5ee8193256..7b6166c8ac9c6 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -23,7 +23,7 @@ use rustc_query_impl::{CollectActiveJobsKind, collect_active_query_jobs}; use rustc_session::config::{ Cfg, CrateType, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple, }; -use rustc_session::{EarlyDiagCtxt, Session, filesearch}; +use rustc_session::{EarlyDiagCtxt, IncrCompSession, Session, filesearch}; use rustc_span::edition::Edition; use rustc_span::source_map::SourceMapInputs; use rustc_span::{SessionGlobals, Symbol, sym}; @@ -413,6 +413,7 @@ impl CodegenBackend for DummyCodegenBackend { &self, ongoing_codegen: Box, _sess: &Session, + _incr_comp_session: Option<&IncrCompSession>, _outputs: &OutputFilenames, _crate_info: &CrateInfo, ) -> (CompiledModules, WorkProductMap) { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 8fa0c1b2dcdd8..c1dd65370d278 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2471,7 +2471,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { && tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() { let saved_path = &work_product.saved_files["rmeta"]; - let incr_comp_session_dir = tcx.sess.incr_comp_session_dir(); + let incr_comp_session_dir = &tcx.incr_comp_session.unwrap().session_directory; let source_file_in_incr_dir = &incr_comp_session_dir.join(saved_path); debug!("copying preexisting metadata from {source_file_in_incr_dir:?} to {path:?}"); match rustc_fs_util::link_or_copy(&source_file_in_incr_dir, path) { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4ae165cb015bd..92596787097a3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -36,10 +36,10 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr}; use rustc_index::IndexVec; use rustc_macros::Diagnostic; -use rustc_session::Session; use rustc_session::config::CrateType; use rustc_session::cstore::{CrateStoreDyn, Untracked}; use rustc_session::lint::Lint; +use rustc_session::{IncrCompSession, Session}; use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use rustc_type_ir::TyKind::*; @@ -712,6 +712,7 @@ pub struct GlobalCtxt<'tcx> { /// `rustc_symbol_mangling` crate for more information. stable_crate_id: StableCrateId, + pub incr_comp_session: Option<&'tcx IncrCompSession>, pub dep_graph: DepGraph, pub prof: SelfProfilerRef, @@ -935,6 +936,7 @@ impl<'tcx> TyCtxt<'tcx> { arena: &'tcx WorkerLocal>, hir_arena: &'tcx WorkerLocal>, untracked: Untracked, + incr_comp_session: Option<&'tcx IncrCompSession>, dep_graph: DepGraph, dep_kind_vtables: &'tcx [DepKindVTable<'tcx>], query_system: QuerySystem<'tcx>, @@ -957,6 +959,7 @@ impl<'tcx> TyCtxt<'tcx> { arena, hir_arena, interners, + incr_comp_session, dep_graph, hooks, prof: sess.prof.clone(), diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index eebead6fc1f47..975b09f84cb0d 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -7,9 +7,7 @@ use std::{env, io}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; -use rustc_data_structures::sync::{ - AppendOnlyVec, DynSend, DynSync, Lock, MappedReadGuard, ReadGuard, RwLock, -}; +use rustc_data_structures::sync::{AppendOnlyVec, DynSend, DynSync, Lock}; use rustc_data_structures::{Limit, flock}; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; @@ -341,8 +339,6 @@ pub struct Session { /// Input, input file path and output file path to this compilation process. pub io: CompilerIO, - incr_comp_session: RwLock, - /// Used by `-Z self-profile`. pub prof: SelfProfilerRef, @@ -688,45 +684,6 @@ impl Session { } } - pub fn init_incr_comp_session(&self, session_dir: PathBuf, lock_file: flock::Lock) { - let mut incr_comp_session = self.incr_comp_session.borrow_mut(); - - if let IncrCompSession::NotInitialized = *incr_comp_session { - } else { - panic!("Trying to initialize IncrCompSession `{:?}`", *incr_comp_session) - } - - *incr_comp_session = - IncrCompSession::Active { session_directory: session_dir, _lock_file: lock_file }; - } - - pub fn finalize_incr_comp_session(&self) { - let mut incr_comp_session = self.incr_comp_session.borrow_mut(); - - if let IncrCompSession::Active { .. } = *incr_comp_session { - } else { - panic!("trying to finalize `IncrCompSession` `{:?}`", *incr_comp_session); - } - - // Note: this will also drop the lock file, thus unlocking the directory. - *incr_comp_session = IncrCompSession::FinalizedOrRemoved; - } - - pub fn incr_comp_session_dir(&self) -> MappedReadGuard<'_, PathBuf> { - let incr_comp_session = self.incr_comp_session.borrow(); - ReadGuard::map(incr_comp_session, |incr_comp_session| match incr_comp_session { - IncrCompSession::NotInitialized | IncrCompSession::FinalizedOrRemoved => panic!( - "trying to get session directory from `IncrCompSession`: {:?}", - incr_comp_session, - ), - IncrCompSession::Active { session_directory, .. } => session_directory, - }) - } - - pub fn incr_comp_session_dir_opt(&self) -> Option> { - self.opts.incremental.as_ref().map(|_| self.incr_comp_session_dir()) - } - /// Is this edition 2015? pub fn is_rust_2015(&self) -> bool { self.edition().is_rust_2015() @@ -1355,7 +1312,6 @@ pub fn build_session( check_config: CheckCfg::default(), proc_macro_quoted_spans: Default::default(), io, - incr_comp_session: RwLock::new(IncrCompSession::NotInitialized), prof, timings, code_stats: Default::default(), @@ -1689,20 +1645,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } /// Holds data on the current incremental compilation session, if there is one. -#[derive(Debug)] -enum IncrCompSession { - /// This is the state the session will be in until the incr. comp. dir is - /// needed. - NotInitialized, - /// This is the state during which the session directory is private and can - /// be modified. `_lock_file` is never directly used, but its presence +pub struct IncrCompSession { + /// The directory containing all cached data. Cached data from a previous + /// session can be read out of it and new data for the current session will + /// be written into it. + pub session_directory: PathBuf, + /// `_lock_file` is never directly used, but its presence /// alone has an effect, because the file will unlock when the session is /// dropped. - Active { session_directory: PathBuf, _lock_file: flock::Lock }, - /// This is the state after the session directory has been finalized or - /// removed after errors. In this state, the contents of the directory must - /// not be modified any more. - FinalizedOrRemoved, + pub _lock_file: flock::Lock, } /// A wrapper around an [`DiagCtxt`] that is used for early error emissions. diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 2b7f9c4dbb7fa..7ba409626ea89 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -217,34 +217,37 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let result = interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); - let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { - let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); - let opts = scrape_test_config(tcx, crate_name, args_path); - - let hir_collector = HirCollector::new( - ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), - tcx, - ); - let tests = hir_collector.collect_crate(); - if extract_doctests { - let mut collector = extracted::ExtractedDocTests::new(); - tests.into_iter().for_each(|t| collector.add_test(t, &opts, &options)); - - let stdout = std::io::stdout(); - let mut stdout = stdout.lock(); - if let Err(error) = serde_json::ser::to_writer(&mut stdout, &collector) { - eprintln!(); - Err(format!("Failed to generate JSON output for doctests: {error:?}")) + let (collector, _incr_comp_session) = + rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { + let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); + let opts = scrape_test_config(tcx, crate_name, args_path); + + let hir_collector = HirCollector::new( + ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), + tcx, + ); + let tests = hir_collector.collect_crate(); + if extract_doctests { + let mut collector = extracted::ExtractedDocTests::new(); + tests.into_iter().for_each(|t| collector.add_test(t, &opts, &options)); + + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + if let Err(error) = serde_json::ser::to_writer(&mut stdout, &collector) { + eprintln!(); + Err(format!("Failed to generate JSON output for doctests: {error:?}")) + } else { + Ok(None) + } } else { - Ok(None) - } - } else { - let mut collector = CreateRunnableDocTests::new(options, opts); - tests.into_iter().for_each(|t| collector.add_test(t, Some(compiler.sess.dcx()))); + let mut collector = CreateRunnableDocTests::new(options, opts); + tests + .into_iter() + .for_each(|t| collector.add_test(t, Some(compiler.sess.dcx()))); - Ok(Some(collector)) - } - }); + Ok(Some(collector)) + } + }); compiler.sess.dcx().abort_if_errors(); collector diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index be830cad6c735..5fddb432edcd1 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -882,21 +882,24 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { id: ast::DUMMY_NODE_ID, is_placeholder: false, }; - rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { - let has_dep_info = render_options.dep_info().is_some(); - if render_options.emit.contains(&EmitType::HtmlNonStaticFiles) { - markdown::render_and_write(file, render_options, edition)?; - } - if has_dep_info { - // Register the loaded external files in the source map so they show up in depinfo. - // We can't load them via the source map because it gets created after we process the options. - for external_path in &loaded_paths { - let _ = compiler.sess.source_map().load_binary_file(external_path); + let (res, _incr_comp_session) = + rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { + let has_dep_info = render_options.dep_info().is_some(); + if render_options.emit.contains(&EmitType::HtmlNonStaticFiles) { + markdown::render_and_write(file, render_options, edition)?; } - rustc_interface::passes::write_dep_info(tcx); - } - Ok(()) - }) + if has_dep_info { + // Register the loaded external files in the source map so they show up in depinfo. + // We can't load them via the source map because it gets created after we process the options. + for external_path in &loaded_paths { + let _ = + compiler.sess.source_map().load_binary_file(external_path); + } + rustc_interface::passes::write_dep_info(tcx); + } + Ok(()) + }); + res }), ); } @@ -1005,7 +1008,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { unreachable!() } } - }) + }); }) } diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index 610a4990a5a4b..5ddaed75aa323 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -16,8 +16,8 @@ use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::TyCtxt; -use rustc_session::Session; use rustc_session::config::OutputFilenames; +use rustc_session::{IncrCompSession, Session}; struct TheBackend; @@ -38,6 +38,7 @@ impl CodegenBackend for TheBackend { &self, ongoing_codegen: Box, _sess: &Session, + _incr_comp_session: Option<&IncrCompSession>, _outputs: &OutputFilenames, _crate_info: &CrateInfo, ) -> (CompiledModules, WorkProductMap) { diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs index d99d9c42d547f..ae0f41a205bf4 100644 --- a/tests/ui-fulldeps/run-compiler-twice.rs +++ b/tests/ui-fulldeps/run-compiler-twice.rs @@ -76,10 +76,11 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); - let linker = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { - let _ = tcx.analysis(()); - Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend) - }); - linker.link(&compiler.sess, &*compiler.codegen_backend); + let (linker, incr_comp_session) = + rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let _ = tcx.analysis(()); + Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend) + }); + linker.link(&compiler.sess, incr_comp_session, &*compiler.codegen_backend); }); }