diff options
Diffstat (limited to 'compiler/rustc_incremental/src')
| -rw-r--r-- | compiler/rustc_incremental/src/assert_dep_graph.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/errors.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/lib.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/dirty_clean.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/file_format.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/fs.rs | 88 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/load.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/save.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/work_product.rs | 1 |
9 files changed, 73 insertions, 54 deletions
diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index aa6f184a2d7..41caa5d4765 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -46,12 +46,13 @@ use rustc_middle::dep_graph::{ }; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; - use std::env; use std::fs::{self, File}; use std::io::{BufWriter, Write}; +use tracing::debug; #[allow(missing_docs)] pub fn assert_dep_graph(tcx: TyCtxt<'_>) { diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs index 61bb0353a9f..e94a7fb876b 100644 --- a/compiler/rustc_incremental/src/errors.rs +++ b/compiler/rustc_incremental/src/errors.rs @@ -306,3 +306,9 @@ pub struct DeleteWorkProduct<'a> { pub path: &'a Path, pub err: std::io::Error, } + +#[derive(Diagnostic)] +#[diag(incremental_corrupt_file)] +pub struct CorruptFile<'a> { + pub path: &'a Path, +} diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 0729986f32f..960a2d012e0 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -6,11 +6,6 @@ #![feature(rustdoc_internals)] #![allow(internal_features)] -#[macro_use] -extern crate rustc_middle; -#[macro_use] -extern crate tracing; - mod assert_dep_graph; mod errors; mod persist; diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index e901ca36dad..2a0d681fa37 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -33,6 +33,7 @@ use rustc_middle::ty::TyCtxt; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use thin_vec::ThinVec; +use tracing::debug; const LOADED_FROM_DISK: Symbol = sym::loaded_from_disk; const EXCEPT: Symbol = sym::except; diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs index b459f82f23e..303785bdb22 100644 --- a/compiler/rustc_incremental/src/persist/file_format.rs +++ b/compiler/rustc_incremental/src/persist/file_format.rs @@ -19,6 +19,7 @@ use std::env; use std::fs; use std::io::{self, Read}; use std::path::{Path, PathBuf}; +use tracing::debug; /// The first few bytes of files generated by incremental compilation. const FILE_MAGIC: &[u8] = b"RSIC"; diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 1462037c8c8..9afea3d66b0 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -104,12 +104,17 @@ //! implemented. use crate::errors; +use rustc_data_structures::base_n; +use rustc_data_structures::base_n::BaseNString; +use rustc_data_structures::base_n::ToBaseN; +use rustc_data_structures::base_n::CASE_INSENSITIVE; +use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::svh::Svh; use rustc_data_structures::unord::{UnordMap, UnordSet}; -use rustc_data_structures::{base_n, flock}; use rustc_errors::ErrorGuaranteed; use rustc_fs_util::{link_or_copy, try_canonicalize, LinkOrCopy}; +use rustc_middle::bug; use rustc_session::config::CrateType; use rustc_session::output::{collect_crate_types, find_crate_name}; use rustc_session::{Session, StableCrateId}; @@ -120,6 +125,7 @@ use std::path::{Path, PathBuf}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use rand::{thread_rng, RngCore}; +use tracing::debug; #[cfg(test)] mod tests; @@ -162,8 +168,11 @@ pub fn query_cache_path(sess: &Session) -> PathBuf { fn lock_file_path(session_dir: &Path) -> PathBuf { let crate_dir = session_dir.parent().unwrap(); - let directory_name = session_dir.file_name().unwrap().to_string_lossy(); - assert_no_characters_lost(&directory_name); + let directory_name = session_dir + .file_name() + .unwrap() + .to_str() + .expect("malformed session dir name: contains non-Unicode characters"); let dash_indices: Vec<_> = directory_name.match_indices('-').map(|(idx, _)| idx).collect(); if dash_indices.len() != 3 { @@ -329,28 +338,24 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) { debug!("finalize_session_directory() - session directory: {}", incr_comp_session_dir.display()); - let old_sub_dir_name = incr_comp_session_dir.file_name().unwrap().to_string_lossy(); - assert_no_characters_lost(&old_sub_dir_name); + let mut sub_dir_name = incr_comp_session_dir + .file_name() + .unwrap() + .to_str() + .expect("malformed session dir name: contains non-Unicode characters") + .to_string(); - // Keep the 's-{timestamp}-{random-number}' prefix, but replace the - // '-working' part with the SVH of the crate - let dash_indices: Vec<_> = old_sub_dir_name.match_indices('-').map(|(idx, _)| idx).collect(); - if dash_indices.len() != 3 { - bug!( - "Encountered incremental compilation session directory with \ - malformed name: {}", - incr_comp_session_dir.display() - ) - } + // Keep the 's-{timestamp}-{random-number}' prefix, but replace "working" with the SVH of the crate + sub_dir_name.truncate(sub_dir_name.len() - "working".len()); + // Double-check that we kept this: "s-{timestamp}-{random-number}-" + assert!(sub_dir_name.ends_with('-'), "{:?}", sub_dir_name); + assert!(sub_dir_name.as_bytes().iter().filter(|b| **b == b'-').count() == 3); - // State: "s-{timestamp}-{random-number}-" - let mut new_sub_dir_name = String::from(&old_sub_dir_name[..=dash_indices[2]]); - - // Append the svh - base_n::push_str(svh.as_u128(), INT_ENCODE_BASE, &mut new_sub_dir_name); + // Append the SVH + sub_dir_name.push_str(&svh.as_u128().to_base_fixed_len(CASE_INSENSITIVE)); // Create the full path - let new_path = incr_comp_session_dir.parent().unwrap().join(new_sub_dir_name); + let new_path = incr_comp_session_dir.parent().unwrap().join(&*sub_dir_name); debug!("finalize_session_directory() - new path: {}", new_path.display()); match rename_path_with_retry(&*incr_comp_session_dir, &new_path, 3) { @@ -446,11 +451,11 @@ fn generate_session_dir_path(crate_dir: &Path) -> PathBuf { let random_number = thread_rng().next_u32(); debug!("generate_session_dir_path: random_number = {}", random_number); - let directory_name = format!( - "s-{}-{}-working", - timestamp, - base_n::encode(random_number as u128, INT_ENCODE_BASE) - ); + // Chop the first 3 characters off the timestamp. Those 3 bytes will be zero for a while. + let (zeroes, timestamp) = timestamp.split_at(3); + assert_eq!(zeroes, "000"); + let directory_name = + format!("s-{}-{}-working", timestamp, random_number.to_base_fixed_len(CASE_INSENSITIVE)); debug!("generate_session_dir_path: directory_name = {}", directory_name); let directory_path = crate_dir.join(directory_name); debug!("generate_session_dir_path: directory_path = {}", directory_path.display()); @@ -527,8 +532,10 @@ where for session_dir in iter { debug!("find_source_directory_in_iter - inspecting `{}`", session_dir.display()); - let directory_name = session_dir.file_name().unwrap().to_string_lossy(); - assert_no_characters_lost(&directory_name); + let Some(directory_name) = session_dir.file_name().unwrap().to_str() else { + debug!("find_source_directory_in_iter - ignoring"); + continue; + }; if source_directories_already_tried.contains(&session_dir) || !is_session_directory(&directory_name) @@ -579,10 +586,10 @@ fn extract_timestamp_from_session_dir(directory_name: &str) -> Result<SystemTime string_to_timestamp(&directory_name[dash_indices[0] + 1..dash_indices[1]]) } -fn timestamp_to_string(timestamp: SystemTime) -> String { +fn timestamp_to_string(timestamp: SystemTime) -> BaseNString { let duration = timestamp.duration_since(UNIX_EPOCH).unwrap(); let micros = duration.as_secs() * 1_000_000 + (duration.subsec_nanos() as u64) / 1000; - base_n::encode(micros as u128, INT_ENCODE_BASE) + micros.to_base_fixed_len(CASE_INSENSITIVE) } fn string_to_timestamp(s: &str) -> Result<SystemTime, &'static str> { @@ -613,18 +620,11 @@ fn crate_path(sess: &Session) -> PathBuf { sess.cfg_version, ); - let stable_crate_id = base_n::encode(stable_crate_id.as_u64() as u128, INT_ENCODE_BASE); - - let crate_name = format!("{crate_name}-{stable_crate_id}"); + let crate_name = + format!("{crate_name}-{}", stable_crate_id.as_u64().to_base_fixed_len(CASE_INSENSITIVE)); incr_dir.join(crate_name) } -fn assert_no_characters_lost(s: &str) { - if s.contains('\u{FFFD}') { - bug!("Could not losslessly convert '{}'.", s) - } -} - fn is_old_enough_to_be_collected(timestamp: SystemTime) -> bool { timestamp < SystemTime::now() - Duration::from_secs(10) } @@ -657,14 +657,14 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result< }; let entry_name = dir_entry.file_name(); - let entry_name = entry_name.to_string_lossy(); + let Some(entry_name) = entry_name.to_str() else { + continue; + }; if is_session_directory_lock_file(&entry_name) { - assert_no_characters_lost(&entry_name); - lock_files.insert(entry_name.into_owned()); + lock_files.insert(entry_name.to_string()); } else if is_session_directory(&entry_name) { - assert_no_characters_lost(&entry_name); - session_directories.insert(entry_name.into_owned()); + session_directories.insert(entry_name.to_string()); } else { // This is something we don't know, leave it alone } diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 26aaa24771f..af667a57ce1 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -12,6 +12,7 @@ use rustc_session::Session; use rustc_span::ErrorGuaranteed; use std::path::{Path, PathBuf}; use std::sync::Arc; +use tracing::{debug, warn}; use super::data::*; use super::file_format; @@ -115,7 +116,11 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkPr if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result { // Decode the list of work_products - let mut work_product_decoder = MemDecoder::new(&work_products_data[..], start_pos); + let Ok(mut work_product_decoder) = MemDecoder::new(&work_products_data[..], start_pos) + else { + sess.dcx().emit_warn(errors::CorruptFile { path: &work_products_path }); + return LoadResult::DataOutOfDate; + }; let work_products: Vec<SerializedWorkProduct> = Decodable::decode(&mut work_product_decoder); @@ -145,7 +150,10 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkPr LoadResult::DataOutOfDate => LoadResult::DataOutOfDate, LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err), LoadResult::Ok { data: (bytes, start_pos) } => { - let mut decoder = MemDecoder::new(&bytes, start_pos); + let Ok(mut decoder) = MemDecoder::new(&bytes, start_pos) else { + sess.dcx().emit_warn(errors::CorruptFile { path: &path }); + return LoadResult::DataOutOfDate; + }; let prev_commandline_args_hash = u64::decode(&mut decoder); if prev_commandline_args_hash != expected_hash { @@ -181,9 +189,14 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache<'_>> { let _prof_timer = sess.prof.generic_activity("incr_comp_load_query_result_cache"); - match load_data(&query_cache_path(sess), sess) { + let path = query_cache_path(sess); + match load_data(&path, sess) { LoadResult::Ok { data: (bytes, start_pos) } => { - Some(OnDiskCache::new(sess, bytes, start_pos)) + let cache = OnDiskCache::new(sess, bytes, start_pos).unwrap_or_else(|()| { + sess.dcx().emit_warn(errors::CorruptFile { path: &path }); + OnDiskCache::new_empty(sess.source_map()) + }); + Some(cache) } _ => Some(OnDiskCache::new_empty(sess.source_map())), } diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 9777f769280..3bf582bd26c 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -11,6 +11,7 @@ use rustc_serialize::Encodable as RustcEncodable; use rustc_session::Session; use std::fs; use std::sync::Arc; +use tracing::debug; use super::data::*; use super::dirty_clean; diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs index 906233ef53e..e230da9dfb1 100644 --- a/compiler/rustc_incremental/src/persist/work_product.rs +++ b/compiler/rustc_incremental/src/persist/work_product.rs @@ -10,6 +10,7 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; use std::fs as std_fs; use std::path::Path; +use tracing::debug; /// Copies a CGU work product to the incremental compilation directory, so next compilation can /// find and reuse it. |
