From 99f652ff2247f21e3842f312ec0e8112774ebef0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 19 Jun 2021 19:22:14 -0500 Subject: [PATCH] Only hash OutputTypes keys in non-crate-hash mode This effectively turns OutputTypes into a hybrid where keys (OutputType) are TRACKED and the values (optional paths) are TRACKED_NO_CRATE_HASH. --- compiler/rustc_interface/src/tests.rs | 6 +- compiler/rustc_session/src/config.rs | 91 ++++++++++++++++++--------- compiler/rustc_session/src/options.rs | 17 +++-- 3 files changed, 77 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 26a7dd0745ce1..52b3076a44396 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -160,9 +160,9 @@ fn test_output_types_tracking_hash_different_paths() { v2.output_types = OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("/some/thing")))]); v3.output_types = OutputTypes::new(&[(OutputType::Exe, None)]); - assert_same_hash(&v1, &v2); - assert_same_hash(&v1, &v3); - assert_same_hash(&v2, &v3); + assert_non_crate_hash_different(&v1, &v2); + assert_non_crate_hash_different(&v1, &v3); + assert_non_crate_hash_different(&v2, &v3); } #[test] diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 331817ad2d0a7..88eaa7fe32924 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -31,7 +31,7 @@ use std::collections::btree_map::{ }; use std::collections::{BTreeMap, BTreeSet}; use std::fmt; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; use std::iter::{self, FromIterator}; use std::path::{Path, PathBuf}; use std::str::{self, FromStr}; @@ -328,19 +328,9 @@ impl Default for TrimmedDefPaths { /// *Do not* switch `BTreeMap` out for an unsorted container type! That would break /// dependency tracking for command-line arguments. Also only hash keys, since tracking /// should only depend on the output types, not the paths they're written to. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Hash)] pub struct OutputTypes(BTreeMap>); -impl Hash for OutputTypes { - fn hash(&self, hasher: &mut H) { - for k in self.keys() { - k.hash(hasher); - } - } -} - -impl_stable_hash_via_hash!(OutputTypes); - impl OutputTypes { pub fn new(entries: &[(OutputType, Option)]) -> OutputTypes { OutputTypes(BTreeMap::from_iter(entries.iter().map(|&(k, ref v)| (k, v.clone())))) @@ -2436,8 +2426,8 @@ crate mod dep_tracking { use super::LdImpl; use super::{ CFGuard, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, LinkerPluginLto, - LtoCli, OptLevel, OutputTypes, Passes, SourceFileHashAlgorithm, SwitchWithOptPath, - SymbolManglingVersion, TrimmedDefPaths, + LtoCli, OptLevel, OutputType, OutputTypes, Passes, SourceFileHashAlgorithm, + SwitchWithOptPath, SymbolManglingVersion, TrimmedDefPaths, }; use crate::lint; use crate::options::WasiExecModel; @@ -2453,13 +2443,18 @@ crate mod dep_tracking { use std::path::PathBuf; pub trait DepTrackingHash { - fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType); + fn hash( + &self, + hasher: &mut DefaultHasher, + error_format: ErrorOutputType, + for_crate_hash: bool, + ); } macro_rules! impl_dep_tracking_hash_via_hash { ($($t:ty),+ $(,)?) => {$( impl DepTrackingHash for $t { - fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) { + fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType, _for_crate_hash: bool) { Hash::hash(self, hasher); } } @@ -2467,11 +2462,16 @@ crate mod dep_tracking { } impl DepTrackingHash for Option { - fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { + fn hash( + &self, + hasher: &mut DefaultHasher, + error_format: ErrorOutputType, + for_crate_hash: bool, + ) { match self { Some(x) => { Hash::hash(&1, hasher); - DepTrackingHash::hash(x, hasher, error_format); + DepTrackingHash::hash(x, hasher, error_format, for_crate_hash); } None => Hash::hash(&0, hasher), } @@ -2501,7 +2501,6 @@ crate mod dep_tracking { LtoCli, DebugInfo, UnstableFeatures, - OutputTypes, NativeLib, NativeLibKind, SanitizerSet, @@ -2515,6 +2514,7 @@ crate mod dep_tracking { SourceFileHashAlgorithm, TrimmedDefPaths, Option, + OutputType, ); impl DepTrackingHash for (T1, T2) @@ -2522,11 +2522,16 @@ crate mod dep_tracking { T1: DepTrackingHash, T2: DepTrackingHash, { - fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { + fn hash( + &self, + hasher: &mut DefaultHasher, + error_format: ErrorOutputType, + for_crate_hash: bool, + ) { Hash::hash(&0, hasher); - DepTrackingHash::hash(&self.0, hasher, error_format); + DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash); Hash::hash(&1, hasher); - DepTrackingHash::hash(&self.1, hasher, error_format); + DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash); } } @@ -2536,22 +2541,49 @@ crate mod dep_tracking { T2: DepTrackingHash, T3: DepTrackingHash, { - fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { + fn hash( + &self, + hasher: &mut DefaultHasher, + error_format: ErrorOutputType, + for_crate_hash: bool, + ) { Hash::hash(&0, hasher); - DepTrackingHash::hash(&self.0, hasher, error_format); + DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash); Hash::hash(&1, hasher); - DepTrackingHash::hash(&self.1, hasher, error_format); + DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash); Hash::hash(&2, hasher); - DepTrackingHash::hash(&self.2, hasher, error_format); + DepTrackingHash::hash(&self.2, hasher, error_format, for_crate_hash); } } impl DepTrackingHash for Vec { - fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { + fn hash( + &self, + hasher: &mut DefaultHasher, + error_format: ErrorOutputType, + for_crate_hash: bool, + ) { Hash::hash(&self.len(), hasher); for (index, elem) in self.iter().enumerate() { Hash::hash(&index, hasher); - DepTrackingHash::hash(elem, hasher, error_format); + DepTrackingHash::hash(elem, hasher, error_format, for_crate_hash); + } + } + } + + impl DepTrackingHash for OutputTypes { + fn hash( + &self, + hasher: &mut DefaultHasher, + error_format: ErrorOutputType, + for_crate_hash: bool, + ) { + Hash::hash(&self.0.len(), hasher); + for (key, val) in &self.0 { + DepTrackingHash::hash(key, hasher, error_format, for_crate_hash); + if !for_crate_hash { + DepTrackingHash::hash(val, hasher, error_format, for_crate_hash); + } } } } @@ -2561,13 +2593,14 @@ crate mod dep_tracking { sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>, hasher: &mut DefaultHasher, error_format: ErrorOutputType, + for_crate_hash: bool, ) { for (key, sub_hash) in sub_hashes { // Using Hash::hash() instead of DepTrackingHash::hash() is fine for // the keys, as they are just plain strings Hash::hash(&key.len(), hasher); Hash::hash(key, hasher); - sub_hash.hash(hasher, error_format); + sub_hash.hash(hasher, error_format, for_crate_hash); } } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 51bf1710db0aa..f5dd8992c29f9 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -48,7 +48,11 @@ macro_rules! hash_substruct { ($opt_name:ident, $opt_expr:expr, $error_format:expr, $for_crate_hash:expr, $hasher:expr, [TRACKED_NO_CRATE_HASH]) => {{}}; ($opt_name:ident, $opt_expr:expr, $error_format:expr, $for_crate_hash:expr, $hasher:expr, [SUBSTRUCT]) => { use crate::config::dep_tracking::DepTrackingHash; - $opt_expr.dep_tracking_hash($for_crate_hash, $error_format).hash($hasher, $error_format); + $opt_expr.dep_tracking_hash($for_crate_hash, $error_format).hash( + $hasher, + $error_format, + $for_crate_hash, + ); }; } @@ -79,7 +83,8 @@ macro_rules! top_level_options { let mut hasher = DefaultHasher::new(); dep_tracking::stable_hash(sub_hashes, &mut hasher, - self.error_format); + self.error_format, + for_crate_hash); $({ hash_substruct!($opt, &self.$opt, @@ -236,19 +241,21 @@ macro_rules! options { build_options(matches, $stat, $prefix, $outputname, error_format) } - fn dep_tracking_hash(&self, _for_crate_hash: bool, error_format: ErrorOutputType) -> u64 { + fn dep_tracking_hash(&self, for_crate_hash: bool, error_format: ErrorOutputType) -> u64 { let mut sub_hashes = BTreeMap::new(); $({ hash_opt!($opt, &self.$opt, &mut sub_hashes, - _for_crate_hash, + for_crate_hash, [$dep_tracking_marker]); })* let mut hasher = DefaultHasher::new(); dep_tracking::stable_hash(sub_hashes, &mut hasher, - error_format); + error_format, + for_crate_hash + ); hasher.finish() } }