Store hashes in special types so they aren't accidentally encoded as numbers

This commit is contained in:
Ben Kimock 2023-04-07 23:11:20 -04:00
parent de96f3d873
commit 0445fbdd83
38 changed files with 274 additions and 138 deletions

View File

@ -79,7 +79,8 @@ pub trait LayoutCalculator {
{
// `ReprOptions.layout_seed` is a deterministic seed that we can use to
// randomize field ordering with
let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);
let mut rng =
Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed.as_u64());
// Shuffle the ordering of the fields
optimizing.shuffle(&mut rng);

View File

@ -9,6 +9,7 @@ use std::str::FromStr;
use bitflags::bitflags;
use rustc_data_structures::intern::Interned;
use rustc_data_structures::stable_hasher::Hash64;
#[cfg(feature = "nightly")]
use rustc_data_structures::stable_hasher::StableOrd;
use rustc_index::vec::{IndexSlice, IndexVec};
@ -77,12 +78,12 @@ pub struct ReprOptions {
pub flags: ReprFlags,
/// The seed to be used for randomizing a type's layout
///
/// Note: This could technically be a `[u8; 16]` (a `u128`) which would
/// Note: This could technically be a `Hash128` which would
/// be the "most accurate" hash as it'd encompass the item and crate
/// hash without loss, but it does pay the price of being larger.
/// Everything's a tradeoff, a `u64` seed should be sufficient for our
/// Everything's a tradeoff, a 64-bit seed should be sufficient for our
/// purposes (primarily `-Z randomize-layout`)
pub field_shuffle_seed: u64,
pub field_shuffle_seed: Hash64,
}
impl ReprOptions {

View File

@ -10,7 +10,7 @@ use crate::value::Value;
use rustc_ast::Mutability;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
@ -261,7 +261,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let hash = self.tcx.with_stable_hashing_context(|mut hcx| {
let mut hasher = StableHasher::new();
alloc.hash_stable(&mut hcx, &mut hasher);
hasher.finish::<u128>()
hasher.finish::<Hash128>()
});
llvm::set_value_name(value, format!("alloc_{hash:032x}").as_bytes());
}

View File

@ -21,6 +21,7 @@ use rustc_codegen_ssa::debuginfo::type_names;
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind};
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::Hash128;
use rustc_data_structures::sync::Lrc;
use rustc_hir::def_id::{DefId, DefIdMap};
use rustc_index::vec::IndexVec;
@ -61,7 +62,7 @@ pub struct CodegenUnitDebugContext<'ll, 'tcx> {
llcontext: &'ll llvm::Context,
llmod: &'ll llvm::Module,
builder: &'ll mut DIBuilder<'ll>,
created_files: RefCell<FxHashMap<Option<(u128, SourceFileHash)>, &'ll DIFile>>,
created_files: RefCell<FxHashMap<Option<(Hash128, SourceFileHash)>, &'ll DIFile>>,
type_map: metadata::TypeMap<'ll, 'tcx>,
namespace_map: RefCell<DefIdMap<&'ll DIScope>>,

View File

@ -12,7 +12,7 @@
// * `"` is treated as the start of a string.
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_hir::def_id::DefId;
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
@ -675,8 +675,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
hcx.while_hashing_spans(false, |hcx| {
ct.to_valtree().hash_stable(hcx, &mut hasher)
});
let hash: u64 = hasher.finish();
hash
hasher.finish::<Hash64>()
});
if cpp_like_debuginfo(tcx) {

View File

@ -75,7 +75,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
}
sym::type_id => {
ensure_monomorphic_enough(tcx, tp_ty)?;
ConstValue::from_u64(tcx.type_id_hash(tp_ty))
ConstValue::from_u64(tcx.type_id_hash(tp_ty).as_u64())
}
sym::variant_count => match tp_ty.kind() {
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.

View File

@ -1,4 +1,4 @@
use crate::stable_hasher;
use crate::stable_hasher::{Hash64, StableHasher, StableHasherResult};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::hash::{Hash, Hasher};
@ -9,32 +9,47 @@ mod tests;
#[repr(C)]
pub struct Fingerprint(u64, u64);
pub trait FingerprintComponent {
fn as_u64(&self) -> u64;
}
impl FingerprintComponent for Hash64 {
fn as_u64(&self) -> u64 {
Hash64::as_u64(*self)
}
}
impl FingerprintComponent for u64 {
fn as_u64(&self) -> u64 {
*self
}
}
impl Fingerprint {
pub const ZERO: Fingerprint = Fingerprint(0, 0);
#[inline]
pub fn new(_0: u64, _1: u64) -> Fingerprint {
Fingerprint(_0, _1)
pub fn new<A, B>(_0: A, _1: B) -> Fingerprint
where
A: FingerprintComponent,
B: FingerprintComponent,
{
Fingerprint(_0.as_u64(), _1.as_u64())
}
#[inline]
pub fn from_smaller_hash(hash: u64) -> Fingerprint {
Fingerprint(hash, hash)
}
#[inline]
pub fn to_smaller_hash(&self) -> u64 {
pub fn to_smaller_hash(&self) -> Hash64 {
// Even though both halves of the fingerprint are expected to be good
// quality hash values, let's still combine the two values because the
// Fingerprints in DefPathHash have the StableCrateId portion which is
// the same for all DefPathHashes from the same crate. Combining the
// two halves makes sure we get a good quality hash in such cases too.
self.0.wrapping_mul(3).wrapping_add(self.1)
Hash64::new(self.0.wrapping_mul(3).wrapping_add(self.1))
}
#[inline]
pub fn as_value(&self) -> (u64, u64) {
(self.0, self.1)
pub fn split(&self) -> (Hash64, Hash64) {
(Hash64::new(self.0), Hash64::new(self.1))
}
#[inline]
@ -131,9 +146,9 @@ impl FingerprintHasher for crate::unhash::Unhasher {
}
}
impl stable_hasher::StableHasherResult for Fingerprint {
impl StableHasherResult for Fingerprint {
#[inline]
fn finish(hasher: stable_hasher::StableHasher) -> Self {
fn finish(hasher: StableHasher) -> Self {
let (_0, _1) = hasher.finalize();
Fingerprint(_0, _1)
}

View File

@ -1,11 +1,12 @@
use super::*;
use crate::stable_hasher::Hash64;
// Check that `combine_commutative` is order independent.
#[test]
fn combine_commutative_is_order_independent() {
let a = Fingerprint::new(0xf6622fb349898b06, 0x70be9377b2f9c610);
let b = Fingerprint::new(0xa9562bf5a2a5303c, 0x67d9b6c82034f13d);
let c = Fingerprint::new(0x0d013a27811dbbc3, 0x9a3f7b3d9142ec43);
let a = Fingerprint::new(Hash64::new(0xf6622fb349898b06), Hash64::new(0x70be9377b2f9c610));
let b = Fingerprint::new(Hash64::new(0xa9562bf5a2a5303c), Hash64::new(0x67d9b6c82034f13d));
let c = Fingerprint::new(Hash64::new(0x0d013a27811dbbc3), Hash64::new(0x9a3f7b3d9142ec43));
let permutations = [(a, b, c), (a, c, b), (b, a, c), (b, c, a), (c, a, b), (c, b, a)];
let f = a.combine_commutative(b).combine_commutative(c);
for p in &permutations {

View File

@ -0,0 +1,120 @@
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::fmt;
use std::ops::BitXorAssign;
use crate::stable_hasher::{StableHasher, StableHasherResult};
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
pub struct Hash64 {
inner: u64,
}
impl Hash64 {
pub const ZERO: Hash64 = Hash64 { inner: 0 };
#[inline]
pub(crate) fn new(n: u64) -> Self {
Self { inner: n }
}
#[inline]
pub fn as_u64(self) -> u64 {
self.inner
}
}
impl BitXorAssign<u64> for Hash64 {
fn bitxor_assign(&mut self, rhs: u64) {
self.inner ^= rhs;
}
}
impl<S: Encoder> Encodable<S> for Hash64 {
#[inline]
fn encode(&self, s: &mut S) {
s.emit_raw_bytes(&self.inner.to_le_bytes());
}
}
impl<D: Decoder> Decodable<D> for Hash64 {
#[inline]
fn decode(d: &mut D) -> Self {
Self { inner: u64::from_le_bytes(d.read_raw_bytes(8).try_into().unwrap()) }
}
}
impl StableHasherResult for Hash64 {
#[inline]
fn finish(hasher: StableHasher) -> Self {
Self { inner: hasher.finalize().0 }
}
}
impl fmt::Debug for Hash64 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl fmt::LowerHex for Hash64 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::LowerHex::fmt(&self.inner, f)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
pub struct Hash128 {
inner: u128,
}
impl Hash128 {
#[inline]
pub fn truncate(self) -> Hash64 {
Hash64 { inner: self.inner as u64 }
}
#[inline]
pub fn wrapping_add(self, other: Self) -> Self {
Self {
inner: self.inner.wrapping_add(other.inner),
}
}
#[inline]
pub fn as_u128(self) -> u128 {
self.inner
}
}
impl<S: Encoder> Encodable<S> for Hash128 {
#[inline]
fn encode(&self, s: &mut S) {
s.emit_raw_bytes(&self.inner.to_le_bytes());
}
}
impl<D: Decoder> Decodable<D> for Hash128 {
#[inline]
fn decode(d: &mut D) -> Self {
Self { inner: u128::from_le_bytes(d.read_raw_bytes(16).try_into().unwrap()) }
}
}
impl StableHasherResult for Hash128 {
#[inline]
fn finish(hasher: StableHasher) -> Self {
let (_0, _1) = hasher.finalize();
Self { inner: u128::from(_0) | (u128::from(_1) << 64) }
}
}
impl fmt::Debug for Hash128 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl fmt::LowerHex for Hash128 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::LowerHex::fmt(&self.inner, f)
}
}

View File

@ -86,6 +86,7 @@ pub mod work_queue;
pub use atomic_ref::AtomicRef;
pub mod aligned;
pub mod frozen;
mod hashes;
pub mod owned_slice;
pub mod sso;
pub mod steal;

View File

@ -2,6 +2,7 @@ use crate::sip128::SipHasher128;
use rustc_index::bit_set;
use rustc_index::vec;
use smallvec::SmallVec;
use std::fmt;
use std::hash::{BuildHasher, Hash, Hasher};
use std::marker::PhantomData;
use std::mem;
@ -9,6 +10,8 @@ use std::mem;
#[cfg(test)]
mod tests;
pub use crate::hashes::{Hash128, Hash64};
/// When hashing something that ends up affecting properties like symbol names,
/// we want these symbol names to be calculated independently of other factors
/// like what architecture you're compiling *from*.
@ -20,8 +23,8 @@ pub struct StableHasher {
state: SipHasher128,
}
impl ::std::fmt::Debug for StableHasher {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl fmt::Debug for StableHasher {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.state)
}
}
@ -42,21 +45,6 @@ impl StableHasher {
}
}
impl StableHasherResult for u128 {
#[inline]
fn finish(hasher: StableHasher) -> Self {
let (_0, _1) = hasher.finalize();
u128::from(_0) | (u128::from(_1) << 64)
}
}
impl StableHasherResult for u64 {
#[inline]
fn finish(hasher: StableHasher) -> Self {
hasher.finalize().0
}
}
impl StableHasher {
#[inline]
pub fn finalize(self) -> (u64, u64) {
@ -287,6 +275,9 @@ impl_stable_traits_for_trivial_type!(i128);
impl_stable_traits_for_trivial_type!(char);
impl_stable_traits_for_trivial_type!(());
impl_stable_traits_for_trivial_type!(Hash64);
impl_stable_traits_for_trivial_type!(Hash128);
impl<CTX> HashStable<CTX> for ! {
fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {
unreachable!()
@ -669,7 +660,7 @@ fn stable_hash_reduce<HCX, I, C, F>(
.map(|value| {
let mut hasher = StableHasher::new();
hash_function(&mut hasher, hcx, value);
hasher.finish::<u128>()
hasher.finish::<Hash128>()
})
.reduce(|accum, value| accum.wrapping_add(value));
hash.hash_stable(hcx, hasher);

View File

@ -72,7 +72,7 @@ fn test_hash_isize() {
assert_eq!(h.finalize(), expected);
}
fn hash<T: HashStable<()>>(t: &T) -> u128 {
fn hash<T: HashStable<()>>(t: &T) -> Hash128 {
let mut h = StableHasher::new();
let ctx = &mut ();
t.hash_stable(ctx, &mut h);

View File

@ -24,7 +24,7 @@ impl Svh {
}
pub fn as_u64(&self) -> u64 {
self.hash.to_smaller_hash()
self.hash.to_smaller_hash().as_u64()
}
pub fn to_string(&self) -> String {

View File

@ -31,7 +31,7 @@ use Level::*;
use emitter::{is_case_difference, Emitter, EmitterWriter};
use registry::Registry;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
use rustc_data_structures::sync::{self, Lock, Lrc};
use rustc_data_structures::AtomicRef;
pub use rustc_error_messages::{
@ -427,7 +427,7 @@ struct HandlerInner {
/// This set contains a hash of every diagnostic that has been emitted by
/// this handler. These hashes is used to avoid emitting the same error
/// twice.
emitted_diagnostics: FxHashSet<u128>,
emitted_diagnostics: FxHashSet<Hash128>,
/// Stashed diagnostics emitted in one stage of the compiler that may be
/// stolen by other stages (e.g. to improve them and add more information).

View File

@ -9,7 +9,7 @@ use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_IND
use crate::def_path_hash_map::DefPathHashMap;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::stable_hasher::{Hash64, StableHasher};
use rustc_index::vec::IndexVec;
use rustc_span::symbol::{kw, sym, Symbol};
@ -130,7 +130,7 @@ impl DefKey {
disambiguator.hash(&mut hasher);
let local_hash: u64 = hasher.finish();
let local_hash = hasher.finish();
// Construct the new DefPathHash, making sure that the `crate_id`
// portion of the hash is properly copied from the parent. This way the
@ -325,7 +325,7 @@ impl Definitions {
},
};
let parent_hash = DefPathHash::new(stable_crate_id, 0);
let parent_hash = DefPathHash::new(stable_crate_id, Hash64::ZERO);
let def_path_hash = key.compute_stable_hash(parent_hash);
// Create the root definition.

View File

@ -1,4 +1,5 @@
use crate::definitions::{DefKey, DefPathData, DisambiguatedDefPathData};
use rustc_data_structures::stable_hasher::Hash64;
use rustc_span::def_id::{DefPathHash, StableCrateId};
use rustc_span::edition::Edition;
use rustc_span::{create_session_if_not_set_then, Symbol};
@ -24,7 +25,7 @@ fn def_path_hash_depends_on_crate_id() {
assert_ne!(h0.local_hash(), h1.local_hash());
fn mk_test_hash(stable_crate_id: StableCrateId) -> DefPathHash {
let parent_hash = DefPathHash::new(stable_crate_id, 0);
let parent_hash = DefPathHash::new(stable_crate_id, Hash64::ZERO);
let key = DefKey {
parent: None,

View File

@ -601,7 +601,7 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> {
fn crate_path(sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId) -> PathBuf {
let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();
let stable_crate_id = base_n::encode(stable_crate_id.to_u64() as u128, INT_ENCODE_BASE);
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);
incr_dir.join(crate_name)

View File

@ -7,7 +7,7 @@ use rustc_ast::Attribute;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::memmap::{Mmap, MmapMut};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_hir as hir;
@ -531,7 +531,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
adapted.name_hash = {
let mut hasher: StableHasher = StableHasher::new();
adapted.name.hash(&mut hasher);
hasher.finish::<u128>()
hasher.finish::<Hash128>()
};
Lrc::new(adapted)
} else {

View File

@ -357,7 +357,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
Fingerprint::new(
// `owner` is local, so is completely defined by the local hash
def_path_hash.local_hash(),
local_id.as_u32().into(),
local_id.as_u32() as u64,
)
}
@ -370,7 +370,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).as_value();
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
let def_path_hash = DefPathHash::new(tcx.sess.local_stable_crate_id(), local_hash);
let def_id = tcx
.def_path_hash_to_def_id(def_path_hash, &mut || {
@ -378,6 +378,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
})
.expect_local();
let local_id = local_id
.as_u64()
.try_into()
.unwrap_or_else(|_| panic!("local id should be u32, found {:?}", local_id));
Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) })

View File

@ -72,6 +72,6 @@ pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String {
format!(
"rust_metadata_{}_{:08x}",
tcx.crate_name(LOCAL_CRATE),
tcx.sess.local_stable_crate_id().to_u64(),
tcx.sess.local_stable_crate_id(),
)
}

View File

@ -4,7 +4,7 @@ use rustc_attr::InlineAttr;
use rustc_data_structures::base_n;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_hir::ItemId;
use rustc_index::vec::Idx;
@ -313,8 +313,8 @@ impl<'tcx> CodegenUnit<'tcx> {
// avoid collisions and is still reasonably short for filenames.
let mut hasher = StableHasher::new();
human_readable_name.hash(&mut hasher);
let hash: u128 = hasher.finish();
let hash = hash & ((1u128 << 80) - 1);
let hash: Hash128 = hasher.finish();
let hash = hash.as_u128() & ((1u128 << 80) - 1);
base_n::encode(hash, base_n::CASE_INSENSITIVE)
}
@ -505,22 +505,13 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> {
// instantiating stuff for upstream crates.
let local_crate_id = if cnum != LOCAL_CRATE {
let local_stable_crate_id = tcx.sess.local_stable_crate_id();
format!(
"-in-{}.{:08x}",
tcx.crate_name(LOCAL_CRATE),
local_stable_crate_id.to_u64() as u32,
)
format!("-in-{}.{:08x}", tcx.crate_name(LOCAL_CRATE), local_stable_crate_id)
} else {
String::new()
};
let stable_crate_id = tcx.sess.local_stable_crate_id();
format!(
"{}.{:08x}{}",
tcx.crate_name(cnum),
stable_crate_id.to_u64() as u32,
local_crate_id,
)
format!("{}.{:08x}{}", tcx.crate_name(cnum), stable_crate_id, local_crate_id)
});
write!(cgu_name, "{}", crate_prefix).unwrap();

View File

@ -141,14 +141,18 @@ impl<CTX> crate::ty::HashStable<CTX> for ScalarInt {
impl<S: Encoder> Encodable<S> for ScalarInt {
fn encode(&self, s: &mut S) {
s.emit_u128(self.data);
s.emit_u8(self.size.get());
let size = self.size.get();
s.emit_u8(size);
s.emit_raw_bytes(&self.data.to_le_bytes()[..size as usize]);
}
}
impl<D: Decoder> Decodable<D> for ScalarInt {
fn decode(d: &mut D) -> ScalarInt {
ScalarInt { data: d.read_u128(), size: NonZeroU8::new(d.read_u8()).unwrap() }
let mut data = [0u8; 16];
let size = d.read_u8();
data[..size as usize].copy_from_slice(d.read_raw_bytes(size as usize));
ScalarInt { data: u128::from_le_bytes(data), size: NonZeroU8::new(size).unwrap() }
}
}

View File

@ -925,7 +925,7 @@ impl<'tcx> TyCtxt<'tcx> {
crate_name,
// Don't print the whole stable crate id. That's just
// annoying in debug output.
stable_crate_id.to_u64() >> (8 * 6),
stable_crate_id.as_u64() >> (8 * 6),
self.def_path(def_id).to_string_no_crate_verbose()
)
}

View File

@ -11,7 +11,7 @@ use crate::ty::{
use crate::ty::{GenericArgKind, SubstsRef};
use rustc_apfloat::Float as _;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
@ -124,7 +124,7 @@ impl IntTypeExt for IntegerType {
impl<'tcx> TyCtxt<'tcx> {
/// Creates a hash of the type `Ty` which will be the same no matter what crate
/// context it's calculated within. This is used by the `type_id` intrinsic.
pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 {
pub fn type_id_hash(self, ty: Ty<'tcx>) -> Hash64 {
// We want the type_id be independent of the types free regions, so we
// erase them. The erase_regions() call will also anonymize bound
// regions, which is desirable too.

View File

@ -577,5 +577,10 @@ fn get_body_span<'tcx>(
fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 {
// FIXME(cjgillot) Stop hashing HIR manually here.
let owner = hir_body.id().hir_id.owner;
tcx.hir_owner_nodes(owner).unwrap().opt_hash_including_bodies.unwrap().to_smaller_hash()
tcx.hir_owner_nodes(owner)
.unwrap()
.opt_hash_including_bodies
.unwrap()
.to_smaller_hash()
.as_u64()
}

View File

@ -1,6 +1,7 @@
use crate::QueryCtxt;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::stable_hasher::Hash64;
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock};
use rustc_data_structures::unhash::UnhashMap;
use rustc_data_structures::unord::UnordSet;
@ -138,7 +139,7 @@ impl AbsoluteBytePos {
/// is the only thing available when decoding the cache's [Footer].
#[derive(Encodable, Decodable, Clone, Debug)]
struct EncodedSourceFileId {
file_name_hash: u64,
file_name_hash: Hash64,
stable_crate_id: StableCrateId,
}
@ -667,7 +668,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
#[cfg(debug_assertions)]
{
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
let local_hash: u64 = decoder.tcx.with_stable_hashing_context(|mut hcx| {
let local_hash = decoder.tcx.with_stable_hashing_context(|mut hcx| {
let mut hasher = StableHasher::new();
expn_id.expn_data().hash_stable(&mut hcx, &mut hasher);
hasher.finish()

View File

@ -5,7 +5,7 @@
use crate::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex};
use crate::profiling_support::QueryKeyStringCache;
use crate::{on_disk_cache, Queries};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_data_structures::sync::{AtomicU64, Lock};
use rustc_errors::{Diagnostic, Handler};
use rustc_middle::dep_graph::{
@ -342,7 +342,7 @@ pub(crate) fn create_query_frame<
let mut hasher = StableHasher::new();
std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher);
key.hash_stable(&mut hcx, &mut hasher);
hasher.finish::<u64>()
hasher.finish::<Hash64>()
})
};
let ty_adt_id = key.ty_adt_id();

View File

@ -16,6 +16,7 @@ pub use self::config::{HashResult, QueryConfig, TryLoadFromDisk};
use crate::dep_graph::DepKind;
use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
use rustc_data_structures::stable_hasher::Hash64;
use rustc_data_structures::sync::Lock;
use rustc_errors::Diagnostic;
use rustc_hir::def::DefKind;
@ -37,7 +38,7 @@ pub struct QueryStackFrame<D: DepKind> {
/// This hash is used to deterministically pick
/// a query to remove cycles in the parallel compiler.
#[cfg(parallel_compiler)]
hash: u64,
hash: Hash64,
}
impl<D: DepKind> QueryStackFrame<D> {
@ -49,7 +50,7 @@ impl<D: DepKind> QueryStackFrame<D> {
def_kind: Option<DefKind>,
dep_kind: D,
ty_adt_id: Option<DefId>,
_hash: impl FnOnce() -> u64,
_hash: impl FnOnce() -> Hash64,
) -> Self {
Self {
description,

View File

@ -573,7 +573,7 @@ where
// from disk. Re-hashing results is fairly expensive, so we can't
// currently afford to verify every hash. This subset should still
// give us some coverage of potential bugs though.
let try_verify = prev_fingerprint.as_value().1 % 32 == 0;
let try_verify = prev_fingerprint.split().1.as_u64() % 32 == 0;
if std::intrinsics::unlikely(
try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich,
) {

View File

@ -811,7 +811,7 @@ impl Session {
}
pub fn generate_proc_macro_decls_symbol(&self, stable_crate_id: StableCrateId) -> String {
format!("__rustc_proc_macro_decls_{:08x}__", stable_crate_id.to_u64())
format!("__rustc_proc_macro_decls_{:08x}__", stable_crate_id.as_u64())
}
pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {

View File

@ -1,12 +1,11 @@
use crate::{HashStableContext, Symbol};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher, ToStableHashKey};
use rustc_data_structures::unhash::Unhasher;
use rustc_data_structures::AtomicRef;
use rustc_index::vec::Idx;
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::borrow::Borrow;
use std::fmt;
use std::hash::{BuildHasherDefault, Hash, Hasher};
@ -105,20 +104,20 @@ impl DefPathHash {
/// originates from.
#[inline]
pub fn stable_crate_id(&self) -> StableCrateId {
StableCrateId(self.0.as_value().0)
StableCrateId(self.0.split().0)
}
/// Returns the crate-local part of the [DefPathHash].
///
/// Used for tests.
#[inline]
pub fn local_hash(&self) -> u64 {
self.0.as_value().1
pub fn local_hash(&self) -> Hash64 {
self.0.split().1
}
/// Builds a new [DefPathHash] with the given [StableCrateId] and
/// `local_hash`, where `local_hash` must be unique within its crate.
pub fn new(stable_crate_id: StableCrateId, local_hash: u64) -> DefPathHash {
pub fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> DefPathHash {
DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash))
}
}
@ -129,13 +128,6 @@ impl Default for DefPathHash {
}
}
impl Borrow<Fingerprint> for DefPathHash {
#[inline]
fn borrow(&self) -> &Fingerprint {
&self.0
}
}
/// A [`StableCrateId`] is a 64-bit hash of a crate name, together with all
/// `-Cmetadata` arguments, and some other data. It is to [`CrateNum`] what [`DefPathHash`] is to
/// [`DefId`]. It is stable across compilation sessions.
@ -147,15 +139,11 @@ impl Borrow<Fingerprint> for DefPathHash {
///
/// For more information on the possibility of hash collisions in rustc,
/// see the discussion in [`DefId`].
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
#[derive(HashStable_Generic, Encodable, Decodable)]
pub struct StableCrateId(pub(crate) u64);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
#[derive(Hash, HashStable_Generic, Encodable, Decodable)]
pub struct StableCrateId(pub(crate) Hash64);
impl StableCrateId {
pub fn to_u64(self) -> u64 {
self.0
}
/// Computes the stable ID for a crate with the given name and
/// `-Cmetadata` arguments.
pub fn new(crate_name: Symbol, is_exe: bool, mut metadata: Vec<String>) -> StableCrateId {
@ -197,6 +185,16 @@ impl StableCrateId {
StableCrateId(hasher.finish())
}
pub fn as_u64(self) -> u64 {
self.0.as_u64()
}
}
impl fmt::LowerHex for StableCrateId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::LowerHex::fmt(&self.0, f)
}
}
rustc_index::newtype_index! {

View File

@ -33,7 +33,7 @@ use crate::def_id::{CrateNum, DefId, StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::HashingControls;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_data_structures::unhash::UnhashMap;
use rustc_index::vec::IndexVec;
@ -123,15 +123,15 @@ impl ExpnHash {
/// originates from.
#[inline]
pub fn stable_crate_id(self) -> StableCrateId {
StableCrateId(self.0.as_value().0)
StableCrateId(self.0.split().0)
}
/// Returns the crate-local part of the [ExpnHash].
///
/// Used for tests.
#[inline]
pub fn local_hash(self) -> u64 {
self.0.as_value().1
pub fn local_hash(self) -> Hash64 {
self.0.split().1
}
#[inline]
@ -141,7 +141,7 @@ impl ExpnHash {
/// Builds a new [ExpnHash] with the given [StableCrateId] and
/// `local_hash`, where `local_hash` must be unique within its crate.
fn new(stable_crate_id: StableCrateId, local_hash: u64) -> ExpnHash {
fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> ExpnHash {
ExpnHash(Fingerprint::new(stable_crate_id.0, local_hash))
}
}
@ -350,7 +350,7 @@ pub struct HygieneData {
/// would have collisions without a disambiguator.
/// The keys of this map are always computed with `ExpnData.disambiguator`
/// set to 0.
expn_data_disambiguators: FxHashMap<u64, u32>,
expn_data_disambiguators: FxHashMap<Hash64, u32>,
}
impl HygieneData {
@ -1040,7 +1040,7 @@ impl ExpnData {
}
#[inline]
fn hash_expn(&self, ctx: &mut impl HashStableContext) -> u64 {
fn hash_expn(&self, ctx: &mut impl HashStableContext) -> Hash64 {
let mut hasher = StableHasher::new();
self.hash_stable(ctx, &mut hasher);
hasher.finish()

View File

@ -59,7 +59,7 @@ pub mod fatal_error;
pub mod profiling;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{Hash128, Hash64, HashStable, StableHasher};
use rustc_data_structures::sync::{Lock, Lrc};
use std::borrow::Cow;
@ -282,22 +282,22 @@ impl RealFileName {
pub enum FileName {
Real(RealFileName),
/// Call to `quote!`.
QuoteExpansion(u64),
QuoteExpansion(Hash64),
/// Command line.
Anon(u64),
Anon(Hash64),
/// Hack in `src/librustc_ast/parse.rs`.
// FIXME(jseyfried)
MacroExpansion(u64),
ProcMacroSourceCode(u64),
MacroExpansion(Hash64),
ProcMacroSourceCode(Hash64),
/// Strings provided as `--cfg [cfgspec]` stored in a `crate_cfg`.
CfgSpec(u64),
CfgSpec(Hash64),
/// Strings provided as crate attributes in the CLI.
CliCrateAttr(u64),
CliCrateAttr(Hash64),
/// Custom sources for explicit parser calls from plugins and drivers.
Custom(String),
DocTest(PathBuf, isize),
/// Post-substitution inline assembly from LLVM.
InlineAsm(u64),
InlineAsm(Hash64),
}
impl From<PathBuf> for FileName {
@ -1343,7 +1343,7 @@ pub struct SourceFile {
/// Locations of characters removed during normalization.
pub normalized_pos: Vec<NormalizedPos>,
/// A hash of the filename, used for speeding up hashing in incremental compilation.
pub name_hash: u128,
pub name_hash: Hash128,
/// Indicates which crate this `SourceFile` was imported from.
pub cnum: CrateNum,
}
@ -1472,7 +1472,7 @@ impl<D: Decoder> Decodable<D> for SourceFile {
};
let multibyte_chars: Vec<MultiByteChar> = Decodable::decode(d);
let non_narrow_chars: Vec<NonNarrowChar> = Decodable::decode(d);
let name_hash: u128 = Decodable::decode(d);
let name_hash = Decodable::decode(d);
let normalized_pos: Vec<NormalizedPos> = Decodable::decode(d);
let cnum: CrateNum = Decodable::decode(d);
SourceFile {
@ -1514,7 +1514,7 @@ impl SourceFile {
let name_hash = {
let mut hasher: StableHasher = StableHasher::new();
name.hash(&mut hasher);
hasher.finish::<u128>()
hasher.finish()
};
let end_pos = start_pos.to_usize() + src.len();
assert!(end_pos <= u32::MAX as usize);

View File

@ -13,7 +13,7 @@ pub use crate::hygiene::{ExpnData, ExpnKind};
pub use crate::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::stable_hasher::{Hash128, Hash64, StableHasher};
use rustc_data_structures::sync::{AtomicU32, Lrc, MappedReadGuard, ReadGuard, RwLock};
use std::cmp;
use std::hash::Hash;
@ -138,7 +138,7 @@ impl FileLoader for RealFileLoader {
pub struct StableSourceFileId {
/// A hash of the source file's [`FileName`]. This is hash so that it's size
/// is more predictable than if we included the actual [`FileName`] value.
pub file_name_hash: u64,
pub file_name_hash: Hash64,
/// The [`CrateNum`] of the crate this source file was originally parsed for.
/// We cannot include this information in the hash because at the time
@ -331,7 +331,7 @@ impl SourceMap {
&self,
filename: FileName,
src_hash: SourceFileHash,
name_hash: u128,
name_hash: Hash128,
source_len: usize,
cnum: CrateNum,
file_local_lines: Lock<SourceFileLines>,

View File

@ -3,8 +3,12 @@ use super::*;
#[test]
fn test_lookup_line() {
let source = "abcdefghijklm\nabcdefghij\n...".to_owned();
let sf =
SourceFile::new(FileName::Anon(0), source, BytePos(3), SourceFileHashAlgorithm::Sha256);
let sf = SourceFile::new(
FileName::Anon(Hash64::ZERO),
source,
BytePos(3),
SourceFileHashAlgorithm::Sha256,
);
sf.lines(|lines| assert_eq!(lines, &[BytePos(3), BytePos(17), BytePos(28)]));
assert_eq!(sf.lookup_line(BytePos(0)), None);

View File

@ -1,4 +1,4 @@
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_hir::def_id::CrateNum;
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::ty::print::{PrettyPrinter, Print, Printer};
@ -93,7 +93,7 @@ fn get_symbol_hash<'tcx>(
item_type: Ty<'tcx>,
instantiating_crate: Option<CrateNum>,
) -> u64 {
) -> Hash64 {
let def_id = instance.def_id();
let substs = instance.substs;
debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs);
@ -138,7 +138,7 @@ fn get_symbol_hash<'tcx>(
});
// 64 bits should be enough to avoid collisions.
hasher.finish::<u64>()
hasher.finish::<Hash64>()
})
}
@ -176,7 +176,7 @@ impl SymbolPath {
}
}
fn finish(mut self, hash: u64) -> String {
fn finish(mut self, hash: Hash64) -> String {
self.finalize_pending_component();
// E = end name-sequence
let _ = write!(self.result, "17h{hash:016x}E");

View File

@ -406,7 +406,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
// Crate disambiguator and name
s.push('C');
s.push_str(&to_disambiguator(tcx.stable_crate_id(def_path.krate).to_u64()));
s.push_str(&to_disambiguator(tcx.stable_crate_id(def_path.krate).as_u64()));
let crate_name = tcx.crate_name(def_path.krate).to_string();
let _ = write!(s, "{}{}", crate_name.len(), &crate_name);

View File

@ -731,7 +731,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
self.push("C");
let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id();
self.push_disambiguator(stable_crate_id.to_u64());
self.push_disambiguator(stable_crate_id.as_u64());
let name = self.tcx.crate_name(cnum);
self.push_ident(name.as_str());
Ok(self)