Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 05eac57

Browse files
committedJul 12, 2024
Auto merge of #127479 - Urgau:rustc-stable-hash, r=michaelwoerister
Use rustc-stable-hash in the compiler Following rust-lang/compiler-team#755 and the release of the crate on crates.io, let's now use it in the compiler and remove the old implementation. cc `@michaelwoerister` r? ghost
2 parents b286722 + 977439d commit 05eac57

File tree

11 files changed

+30
-1049
lines changed

11 files changed

+30
-1049
lines changed
 

‎Cargo.lock

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3514,6 +3514,12 @@ version = "1.1.0"
35143514
source = "registry+https://github.com/rust-lang/crates.io-index"
35153515
checksum = "5be1bdc7edf596692617627bbfeaba522131b18e06ca4df2b6b689e3c5d5ce84"
35163516

3517+
[[package]]
3518+
name = "rustc-stable-hash"
3519+
version = "0.1.0"
3520+
source = "registry+https://github.com/rust-lang/crates.io-index"
3521+
checksum = "e5c9f15eec8235d7cb775ee6f81891db79b98fd54ba1ad8fae565b88ef1ae4e2"
3522+
35173523
[[package]]
35183524
name = "rustc-std-workspace-alloc"
35193525
version = "1.99.0"
@@ -3852,6 +3858,7 @@ dependencies = [
38523858
"portable-atomic",
38533859
"rustc-hash",
38543860
"rustc-rayon",
3861+
"rustc-stable-hash",
38553862
"rustc_arena",
38563863
"rustc_graphviz",
38573864
"rustc_index",

‎compiler/rustc_data_structures/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ jobserver_crate = { version = "0.1.28", package = "jobserver" }
1515
measureme = "11"
1616
rustc-hash = "1.1.0"
1717
rustc-rayon = { version = "0.5.0", optional = true }
18+
rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
1819
rustc_arena = { path = "../rustc_arena" }
1920
rustc_graphviz = { path = "../rustc_graphviz" }
2021
rustc_index = { path = "../rustc_index", package = "rustc_index" }

‎compiler/rustc_data_structures/src/fingerprint.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::stable_hasher::impl_stable_traits_for_trivial_type;
2-
use crate::stable_hasher::{Hash64, StableHasher, StableHasherResult};
2+
use crate::stable_hasher::{FromStableHash, Hash64, StableHasherHash};
33
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
44
use std::hash::{Hash, Hasher};
55

@@ -154,10 +154,11 @@ impl FingerprintHasher for crate::unhash::Unhasher {
154154
}
155155
}
156156

157-
impl StableHasherResult for Fingerprint {
157+
impl FromStableHash for Fingerprint {
158+
type Hash = StableHasherHash;
159+
158160
#[inline]
159-
fn finish(hasher: StableHasher) -> Self {
160-
let (_0, _1) = hasher.finalize();
161+
fn from(StableHasherHash([_0, _1]): Self::Hash) -> Self {
161162
Fingerprint(_0, _1)
162163
}
163164
}

‎compiler/rustc_data_structures/src/hashes.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! connect the fact that they can only be produced by a `StableHasher` to their
1212
//! `Encode`/`Decode` impls.
1313
14-
use crate::stable_hasher::{StableHasher, StableHasherResult};
14+
use crate::stable_hasher::{FromStableHash, StableHasherHash};
1515
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
1616
use std::fmt;
1717
use std::ops::BitXorAssign;
@@ -56,10 +56,12 @@ impl<D: Decoder> Decodable<D> for Hash64 {
5656
}
5757
}
5858

59-
impl StableHasherResult for Hash64 {
59+
impl FromStableHash for Hash64 {
60+
type Hash = StableHasherHash;
61+
6062
#[inline]
61-
fn finish(hasher: StableHasher) -> Self {
62-
Self { inner: hasher.finalize().0 }
63+
fn from(StableHasherHash([_0, __1]): Self::Hash) -> Self {
64+
Self { inner: _0 }
6365
}
6466
}
6567

@@ -121,10 +123,11 @@ impl<D: Decoder> Decodable<D> for Hash128 {
121123
}
122124
}
123125

124-
impl StableHasherResult for Hash128 {
126+
impl FromStableHash for Hash128 {
127+
type Hash = StableHasherHash;
128+
125129
#[inline]
126-
fn finish(hasher: StableHasher) -> Self {
127-
let (_0, _1) = hasher.finalize();
130+
fn from(StableHasherHash([_0, _1]): Self::Hash) -> Self {
128131
Self { inner: u128::from(_0) | (u128::from(_1) << 64) }
129132
}
130133
}

‎compiler/rustc_data_structures/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#![feature(core_intrinsics)]
2525
#![feature(extend_one)]
2626
#![feature(hash_raw_entry)]
27-
#![feature(hasher_prefixfree_extras)]
2827
#![feature(macro_metavar_expr)]
2928
#![feature(map_try_insert)]
3029
#![feature(min_specialization)]
@@ -67,7 +66,6 @@ pub mod owned_slice;
6766
pub mod packed;
6867
pub mod profiling;
6968
pub mod sharded;
70-
pub mod sip128;
7169
pub mod small_c_str;
7270
pub mod snapshot_map;
7371
pub mod sorted_map;

‎compiler/rustc_data_structures/src/sip128.rs

Lines changed: 0 additions & 505 deletions
This file was deleted.

‎compiler/rustc_data_structures/src/sip128/tests.rs

Lines changed: 0 additions & 304 deletions
This file was deleted.

‎compiler/rustc_data_structures/src/stable_hasher.rs

Lines changed: 3 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use crate::sip128::SipHasher128;
21
use rustc_index::bit_set::{self, BitSet};
32
use rustc_index::{Idx, IndexSlice, IndexVec};
43
use smallvec::SmallVec;
5-
use std::fmt;
64
use std::hash::{BuildHasher, Hash, Hasher};
75
use std::marker::PhantomData;
86
use std::mem;
@@ -13,163 +11,9 @@ mod tests;
1311

1412
pub use crate::hashes::{Hash128, Hash64};
1513

16-
/// When hashing something that ends up affecting properties like symbol names,
17-
/// we want these symbol names to be calculated independently of other factors
18-
/// like what architecture you're compiling *from*.
19-
///
20-
/// To that end we always convert integers to little-endian format before
21-
/// hashing and the architecture dependent `isize` and `usize` types are
22-
/// extended to 64 bits if needed.
23-
pub struct StableHasher {
24-
state: SipHasher128,
25-
}
26-
27-
impl fmt::Debug for StableHasher {
28-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29-
write!(f, "{:?}", self.state)
30-
}
31-
}
32-
33-
pub trait StableHasherResult: Sized {
34-
fn finish(hasher: StableHasher) -> Self;
35-
}
36-
37-
impl StableHasher {
38-
#[inline]
39-
pub fn new() -> Self {
40-
StableHasher { state: SipHasher128::new_with_keys(0, 0) }
41-
}
42-
43-
#[inline]
44-
pub fn finish<W: StableHasherResult>(self) -> W {
45-
W::finish(self)
46-
}
47-
}
48-
49-
impl StableHasher {
50-
#[inline]
51-
pub fn finalize(self) -> (u64, u64) {
52-
self.state.finish128()
53-
}
54-
}
55-
56-
impl Hasher for StableHasher {
57-
fn finish(&self) -> u64 {
58-
panic!("use StableHasher::finalize instead");
59-
}
60-
61-
#[inline]
62-
fn write(&mut self, bytes: &[u8]) {
63-
self.state.write(bytes);
64-
}
65-
66-
#[inline]
67-
fn write_str(&mut self, s: &str) {
68-
self.state.write_str(s);
69-
}
70-
71-
#[inline]
72-
fn write_length_prefix(&mut self, len: usize) {
73-
// Our impl for `usize` will extend it if needed.
74-
self.write_usize(len);
75-
}
76-
77-
#[inline]
78-
fn write_u8(&mut self, i: u8) {
79-
self.state.write_u8(i);
80-
}
81-
82-
#[inline]
83-
fn write_u16(&mut self, i: u16) {
84-
self.state.short_write(i.to_le_bytes());
85-
}
86-
87-
#[inline]
88-
fn write_u32(&mut self, i: u32) {
89-
self.state.short_write(i.to_le_bytes());
90-
}
91-
92-
#[inline]
93-
fn write_u64(&mut self, i: u64) {
94-
self.state.short_write(i.to_le_bytes());
95-
}
96-
97-
#[inline]
98-
fn write_u128(&mut self, i: u128) {
99-
self.write_u64(i as u64);
100-
self.write_u64((i >> 64) as u64);
101-
}
102-
103-
#[inline]
104-
fn write_usize(&mut self, i: usize) {
105-
// Always treat usize as u64 so we get the same results on 32 and 64 bit
106-
// platforms. This is important for symbol hashes when cross compiling,
107-
// for example.
108-
self.state.short_write((i as u64).to_le_bytes());
109-
}
110-
111-
#[inline]
112-
fn write_i8(&mut self, i: i8) {
113-
self.state.write_i8(i);
114-
}
115-
116-
#[inline]
117-
fn write_i16(&mut self, i: i16) {
118-
self.state.short_write((i as u16).to_le_bytes());
119-
}
120-
121-
#[inline]
122-
fn write_i32(&mut self, i: i32) {
123-
self.state.short_write((i as u32).to_le_bytes());
124-
}
125-
126-
#[inline]
127-
fn write_i64(&mut self, i: i64) {
128-
self.state.short_write((i as u64).to_le_bytes());
129-
}
130-
131-
#[inline]
132-
fn write_i128(&mut self, i: i128) {
133-
self.state.write(&(i as u128).to_le_bytes());
134-
}
135-
136-
#[inline]
137-
fn write_isize(&mut self, i: isize) {
138-
// Always treat isize as a 64-bit number so we get the same results on 32 and 64 bit
139-
// platforms. This is important for symbol hashes when cross compiling,
140-
// for example. Sign extending here is preferable as it means that the
141-
// same negative number hashes the same on both 32 and 64 bit platforms.
142-
let value = i as u64;
143-
144-
// Cold path
145-
#[cold]
146-
#[inline(never)]
147-
fn hash_value(state: &mut SipHasher128, value: u64) {
148-
state.write_u8(0xFF);
149-
state.short_write(value.to_le_bytes());
150-
}
151-
152-
// `isize` values often seem to have a small (positive) numeric value in practice.
153-
// To exploit this, if the value is small, we will hash a smaller amount of bytes.
154-
// However, we cannot just skip the leading zero bytes, as that would produce the same hash
155-
// e.g. if you hash two values that have the same bit pattern when they are swapped.
156-
// See https://github.com/rust-lang/rust/pull/93014 for context.
157-
//
158-
// Therefore, we employ the following strategy:
159-
// 1) When we encounter a value that fits within a single byte (the most common case), we
160-
// hash just that byte. This is the most common case that is being optimized. However, we do
161-
// not do this for the value 0xFF, as that is a reserved prefix (a bit like in UTF-8).
162-
// 2) When we encounter a larger value, we hash a "marker" 0xFF and then the corresponding
163-
// 8 bytes. Since this prefix cannot occur when we hash a single byte, when we hash two
164-
// `isize`s that fit within a different amount of bytes, they should always produce a different
165-
// byte stream for the hasher.
166-
if value < 0xFF {
167-
self.state.write_u8(value as u8);
168-
} else {
169-
hash_value(&mut self.state, value);
170-
}
171-
}
172-
}
14+
pub use rustc_stable_hash::FromStableHash;
15+
pub use rustc_stable_hash::SipHasher128Hash as StableHasherHash;
16+
pub use rustc_stable_hash::StableSipHasher128 as StableHasher;
17317

17418
/// Something that implements `HashStable<CTX>` can be hashed in a way that is
17519
/// stable across multiple compilation sessions.

‎compiler/rustc_data_structures/src/stable_hasher/tests.rs

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,71 +7,6 @@ use super::*;
77
// ways). The expected values depend on the hashing algorithm used, so they
88
// need to be updated whenever StableHasher changes its hashing algorithm.
99

10-
#[test]
11-
fn test_hash_integers() {
12-
// Test that integers are handled consistently across platforms.
13-
let test_u8 = 0xAB_u8;
14-
let test_u16 = 0xFFEE_u16;
15-
let test_u32 = 0x445577AA_u32;
16-
let test_u64 = 0x01234567_13243546_u64;
17-
let test_u128 = 0x22114433_66557788_99AACCBB_EEDDFF77_u128;
18-
let test_usize = 0xD0C0B0A0_usize;
19-
20-
let test_i8 = -100_i8;
21-
let test_i16 = -200_i16;
22-
let test_i32 = -300_i32;
23-
let test_i64 = -400_i64;
24-
let test_i128 = -500_i128;
25-
let test_isize = -600_isize;
26-
27-
let mut h = StableHasher::new();
28-
test_u8.hash(&mut h);
29-
test_u16.hash(&mut h);
30-
test_u32.hash(&mut h);
31-
test_u64.hash(&mut h);
32-
test_u128.hash(&mut h);
33-
test_usize.hash(&mut h);
34-
test_i8.hash(&mut h);
35-
test_i16.hash(&mut h);
36-
test_i32.hash(&mut h);
37-
test_i64.hash(&mut h);
38-
test_i128.hash(&mut h);
39-
test_isize.hash(&mut h);
40-
41-
// This depends on the hashing algorithm. See note at top of file.
42-
let expected = (13997337031081104755, 6178945012502239489);
43-
44-
assert_eq!(h.finalize(), expected);
45-
}
46-
47-
#[test]
48-
fn test_hash_usize() {
49-
// Test that usize specifically is handled consistently across platforms.
50-
let test_usize = 0xABCDEF01_usize;
51-
52-
let mut h = StableHasher::new();
53-
test_usize.hash(&mut h);
54-
55-
// This depends on the hashing algorithm. See note at top of file.
56-
let expected = (12037165114281468837, 3094087741167521712);
57-
58-
assert_eq!(h.finalize(), expected);
59-
}
60-
61-
#[test]
62-
fn test_hash_isize() {
63-
// Test that isize specifically is handled consistently across platforms.
64-
let test_isize = -7_isize;
65-
66-
let mut h = StableHasher::new();
67-
test_isize.hash(&mut h);
68-
69-
// This depends on the hashing algorithm. See note at top of file.
70-
let expected = (3979067582695659080, 2322428596355037273);
71-
72-
assert_eq!(h.finalize(), expected);
73-
}
74-
7510
fn hash<T: HashStable<()>>(t: &T) -> Hash128 {
7611
let mut h = StableHasher::new();
7712
let ctx = &mut ();

‎compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::ptr;
22

3+
use crate::hashes::Hash128;
34
use crate::stable_hasher::{HashStable, StableHasher};
45
use crate::tagged_ptr::{CopyTaggedPtr, Pointer, Tag, Tag2};
56

@@ -31,14 +32,13 @@ fn stable_hash_hashes_as_tuple() {
3132
let hash_packed = {
3233
let mut hasher = StableHasher::new();
3334
tag_ptr(&12, Tag2::B11).hash_stable(&mut (), &mut hasher);
34-
35-
hasher.finalize()
35+
hasher.finish::<Hash128>()
3636
};
3737

3838
let hash_tupled = {
3939
let mut hasher = StableHasher::new();
4040
(&12, Tag2::B11).hash_stable(&mut (), &mut hasher);
41-
hasher.finalize()
41+
hasher.finish::<Hash128>()
4242
};
4343

4444
assert_eq!(hash_packed, hash_tupled);

‎src/tools/tidy/src/deps.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
353353
"rustc-hash",
354354
"rustc-rayon",
355355
"rustc-rayon-core",
356+
"rustc-stable-hash",
356357
"rustc_apfloat",
357358
"rustc_version",
358359
"rustix",

0 commit comments

Comments
 (0)
Please sign in to comment.