Rollup merge of #64824 - Mark-Simulacrum:no-stable-hasher-result-everywhere, r=michaelwoerister

No StableHasherResult everywhere

This removes the generic parameter on `StableHasher`, instead moving it to the call to `finish`. This has the side-effect of making all `HashStable` impls nicer, since we no longer need the verbose `<W: StableHasherResult>` that previously existed -- often forcing line wrapping.

This is done for two reasons:
 * we should avoid false "generic" dependency on the result of StableHasher
     * we don't need to codegen two/three copies of all the HashStable impls when they're transitively used to produce a fingerprint, u64, or u128. I haven't measured, but this might actually make our artifacts somewhat smaller too.
 * Easier to understand/read/write code -- the result of the stable hasher is irrelevant when writing a hash impl.
This commit is contained in:
Mazdak Farrokhzad
2019-09-29 04:36:02 +02:00
committed by GitHub
36 changed files with 191 additions and 472 deletions
+1 -1
View File
@@ -76,7 +76,7 @@ fn fmt(&self, formatter: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
impl stable_hasher::StableHasherResult for Fingerprint {
#[inline]
fn finish(hasher: stable_hasher::StableHasher<Self>) -> Self {
fn finish(hasher: stable_hasher::StableHasher) -> Self {
let (_0, _1) = hasher.finalize();
Fingerprint(_0, _1)
}
+45 -113
View File
@@ -1,5 +1,4 @@
use std::hash::{Hash, Hasher, BuildHasher};
use std::marker::PhantomData;
use std::mem;
use smallvec::SmallVec;
use crate::sip128::SipHasher128;
@@ -13,55 +12,53 @@
/// To that end we always convert integers to little-endian format before
/// hashing and the architecture dependent `isize` and `usize` types are
/// extended to 64 bits if needed.
pub struct StableHasher<W> {
pub struct StableHasher {
state: SipHasher128,
width: PhantomData<W>,
}
impl<W: StableHasherResult> ::std::fmt::Debug for StableHasher<W> {
impl ::std::fmt::Debug for StableHasher {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
write!(f, "{:?}", self.state)
}
}
pub trait StableHasherResult: Sized {
fn finish(hasher: StableHasher<Self>) -> Self;
fn finish(hasher: StableHasher) -> Self;
}
impl<W: StableHasherResult> StableHasher<W> {
impl StableHasher {
pub fn new() -> Self {
StableHasher {
state: SipHasher128::new_with_keys(0, 0),
width: PhantomData,
}
}
pub fn finish(self) -> W {
pub fn finish<W: StableHasherResult>(self) -> W {
W::finish(self)
}
}
impl StableHasherResult for u128 {
fn finish(hasher: StableHasher<Self>) -> Self {
fn finish(hasher: StableHasher) -> Self {
let (_0, _1) = hasher.finalize();
u128::from(_0) | (u128::from(_1) << 64)
}
}
impl StableHasherResult for u64 {
fn finish(hasher: StableHasher<Self>) -> Self {
fn finish(hasher: StableHasher) -> Self {
hasher.finalize().0
}
}
impl<W> StableHasher<W> {
impl StableHasher {
#[inline]
pub fn finalize(self) -> (u64, u64) {
self.state.finish128()
}
}
impl<W> Hasher for StableHasher<W> {
impl Hasher for StableHasher {
fn finish(&self) -> u64 {
panic!("use StableHasher::finalize instead");
}
@@ -165,9 +162,7 @@ fn write_isize(&mut self, i: isize) {
/// `StableHasher` takes care of endianness and `isize`/`usize` platform
/// differences.
pub trait HashStable<CTX> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut CTX,
hasher: &mut StableHasher<W>);
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher);
}
/// Implement this for types that can be turned into stable keys like, for
@@ -185,10 +180,10 @@ macro_rules! impl_stable_hash_via_hash {
($t:ty) => (
impl<CTX> $crate::stable_hasher::HashStable<CTX> for $t {
#[inline]
fn hash_stable<W: $crate::stable_hasher::StableHasherResult>(
fn hash_stable(
&self,
_: &mut CTX,
hasher: &mut $crate::stable_hasher::StableHasher<W>
hasher: &mut $crate::stable_hasher::StableHasher
) {
::std::hash::Hash::hash(self, hasher);
}
@@ -215,17 +210,13 @@ fn hash_stable<W: $crate::stable_hasher::StableHasherResult>(
impl_stable_hash_via_hash!(());
impl<CTX> HashStable<CTX> for ::std::num::NonZeroU32 {
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.get().hash_stable(ctx, hasher)
}
}
impl<CTX> HashStable<CTX> for f32 {
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
let val: u32 = unsafe {
::std::mem::transmute(*self)
};
@@ -234,9 +225,7 @@ fn hash_stable<W: StableHasherResult>(&self,
}
impl<CTX> HashStable<CTX> for f64 {
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
let val: u64 = unsafe {
::std::mem::transmute(*self)
};
@@ -245,26 +234,20 @@ fn hash_stable<W: StableHasherResult>(&self,
}
impl<CTX> HashStable<CTX> for ::std::cmp::Ordering {
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(*self as i8).hash_stable(ctx, hasher);
}
}
impl<T1: HashStable<CTX>, CTX> HashStable<CTX> for (T1,) {
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
let (ref _0,) = *self;
_0.hash_stable(ctx, hasher);
}
}
impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2) {
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
let (ref _0, ref _1) = *self;
_0.hash_stable(ctx, hasher);
_1.hash_stable(ctx, hasher);
@@ -276,9 +259,7 @@ impl<T1, T2, T3, CTX> HashStable<CTX> for (T1, T2, T3)
T2: HashStable<CTX>,
T3: HashStable<CTX>,
{
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
let (ref _0, ref _1, ref _2) = *self;
_0.hash_stable(ctx, hasher);
_1.hash_stable(ctx, hasher);
@@ -292,9 +273,7 @@ impl<T1, T2, T3, T4, CTX> HashStable<CTX> for (T1, T2, T3, T4)
T3: HashStable<CTX>,
T4: HashStable<CTX>,
{
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
let (ref _0, ref _1, ref _2, ref _3) = *self;
_0.hash_stable(ctx, hasher);
_1.hash_stable(ctx, hasher);
@@ -304,9 +283,7 @@ fn hash_stable<W: StableHasherResult>(&self,
}
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] {
default fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
default fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.len().hash_stable(ctx, hasher);
for item in self {
item.hash_stable(ctx, hasher);
@@ -316,9 +293,7 @@ impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] {
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Vec<T> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(&self[..]).hash_stable(ctx, hasher);
}
}
@@ -329,9 +304,7 @@ impl<K, V, R, CTX> HashStable<CTX> for indexmap::IndexMap<K, V, R>
R: BuildHasher,
{
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.len().hash_stable(ctx, hasher);
for kv in self {
kv.hash_stable(ctx, hasher);
@@ -344,9 +317,7 @@ impl<K, R, CTX> HashStable<CTX> for indexmap::IndexSet<K, R>
R: BuildHasher,
{
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.len().hash_stable(ctx, hasher);
for key in self {
key.hash_stable(ctx, hasher);
@@ -356,45 +327,35 @@ fn hash_stable<W: StableHasherResult>(&self,
impl<A, CTX> HashStable<CTX> for SmallVec<[A; 1]> where A: HashStable<CTX> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(&self[..]).hash_stable(ctx, hasher);
}
}
impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for Box<T> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(**self).hash_stable(ctx, hasher);
}
}
impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::rc::Rc<T> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(**self).hash_stable(ctx, hasher);
}
}
impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::sync::Arc<T> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(**self).hash_stable(ctx, hasher);
}
}
impl<CTX> HashStable<CTX> for str {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
_: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, _: &mut CTX, hasher: &mut StableHasher) {
self.len().hash(hasher);
self.as_bytes().hash(hasher);
}
@@ -403,9 +364,7 @@ fn hash_stable<W: StableHasherResult>(&self,
impl<CTX> HashStable<CTX> for String {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
(&self[..]).hash_stable(hcx, hasher);
}
}
@@ -420,9 +379,7 @@ fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
impl<CTX> HashStable<CTX> for bool {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(if *self { 1u8 } else { 0u8 }).hash_stable(ctx, hasher);
}
}
@@ -432,9 +389,7 @@ impl<T, CTX> HashStable<CTX> for Option<T>
where T: HashStable<CTX>
{
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
if let Some(ref value) = *self {
1u8.hash_stable(ctx, hasher);
value.hash_stable(ctx, hasher);
@@ -449,9 +404,7 @@ impl<T1, T2, CTX> HashStable<CTX> for Result<T1, T2>
T2: HashStable<CTX>,
{
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
mem::discriminant(self).hash_stable(ctx, hasher);
match *self {
Ok(ref x) => x.hash_stable(ctx, hasher),
@@ -464,18 +417,14 @@ impl<'a, T, CTX> HashStable<CTX> for &'a T
where T: HashStable<CTX> + ?Sized
{
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(**self).hash_stable(ctx, hasher);
}
}
impl<T, CTX> HashStable<CTX> for ::std::mem::Discriminant<T> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
_: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, _: &mut CTX, hasher: &mut StableHasher) {
::std::hash::Hash::hash(self, hasher);
}
}
@@ -483,9 +432,7 @@ fn hash_stable<W: StableHasherResult>(&self,
impl<I: indexed_vec::Idx, T, CTX> HashStable<CTX> for indexed_vec::IndexVec<I, T>
where T: HashStable<CTX>,
{
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.len().hash_stable(ctx, hasher);
for v in &self.raw {
v.hash_stable(ctx, hasher);
@@ -496,9 +443,7 @@ fn hash_stable<W: StableHasherResult>(&self,
impl<I: indexed_vec::Idx, CTX> HashStable<CTX> for bit_set::BitSet<I>
{
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.words().hash_stable(ctx, hasher);
}
}
@@ -506,9 +451,7 @@ fn hash_stable<W: StableHasherResult>(&self,
impl<R: indexed_vec::Idx, C: indexed_vec::Idx, CTX> HashStable<CTX>
for bit_set::BitMatrix<R, C>
{
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.words().hash_stable(ctx, hasher);
}
}
@@ -522,9 +465,7 @@ impl<K, V, R, HCX> HashStable<HCX> for ::std::collections::HashMap<K, V, R>
R: BuildHasher,
{
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut HCX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
hash_stable_hashmap(hcx, hasher, self, ToStableHashKey::to_stable_hash_key);
}
}
@@ -533,9 +474,7 @@ impl<K, R, HCX> HashStable<HCX> for ::std::collections::HashSet<K, R>
where K: ToStableHashKey<HCX> + Eq + Hash,
R: BuildHasher,
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut HCX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
let mut keys: Vec<_> = self.iter()
.map(|k| k.to_stable_hash_key(hcx))
.collect();
@@ -548,9 +487,7 @@ impl<K, V, HCX> HashStable<HCX> for ::std::collections::BTreeMap<K, V>
where K: ToStableHashKey<HCX>,
V: HashStable<HCX>,
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut HCX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
let mut entries: Vec<_> = self.iter()
.map(|(k, v)| (k.to_stable_hash_key(hcx), v))
.collect();
@@ -562,9 +499,7 @@ fn hash_stable<W: StableHasherResult>(&self,
impl<K, HCX> HashStable<HCX> for ::std::collections::BTreeSet<K>
where K: ToStableHashKey<HCX>,
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut HCX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
let mut keys: Vec<_> = self.iter()
.map(|k| k.to_stable_hash_key(hcx))
.collect();
@@ -573,9 +508,9 @@ fn hash_stable<W: StableHasherResult>(&self,
}
}
pub fn hash_stable_hashmap<HCX, K, V, R, SK, F, W>(
pub fn hash_stable_hashmap<HCX, K, V, R, SK, F>(
hcx: &mut HCX,
hasher: &mut StableHasher<W>,
hasher: &mut StableHasher,
map: &::std::collections::HashMap<K, V, R>,
to_stable_hash_key: F)
where K: Eq + Hash,
@@ -583,7 +518,6 @@ pub fn hash_stable_hashmap<HCX, K, V, R, SK, F, W>(
R: BuildHasher,
SK: HashStable<HCX> + Ord + Clone,
F: Fn(&K, &HCX) -> SK,
W: StableHasherResult,
{
let mut entries: Vec<_> = map.iter()
.map(|(k, v)| (to_stable_hash_key(k, hcx), v))
@@ -614,9 +548,7 @@ fn deref(&self) -> &Vec<T> {
impl<T, HCX> HashStable<HCX> for StableVec<T>
where T: HashStable<HCX> + ToStableHashKey<HCX>
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut HCX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
let StableVec(ref v) = *self;
let mut sorted: Vec<_> = v.iter()
+1 -5
View File
@@ -61,11 +61,7 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Svh, D::Error> {
impl<T> stable_hasher::HashStable<T> for Svh {
#[inline]
fn hash_stable<W: stable_hasher::StableHasherResult>(
&self,
ctx: &mut T,
hasher: &mut stable_hasher::StableHasher<W>
) {
fn hash_stable(&self, ctx: &mut T, hasher: &mut stable_hasher::StableHasher) {
let Svh {
hash
} = *self;
+2 -4
View File
@@ -1,4 +1,4 @@
use crate::stable_hasher::{StableHasher, StableHasherResult, HashStable};
use crate::stable_hasher::{StableHasher, HashStable};
/// A vector type optimized for cases where this size is usually 0 (cf. `SmallVector`).
/// The `Option<Box<..>>` wrapping allows us to represent a zero sized vector with `None`,
@@ -60,9 +60,7 @@ fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
}
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for ThinVec<T> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
(**self).hash_stable(hcx, hasher)
}
}
@@ -1,6 +1,6 @@
use crate::bit_set::BitMatrix;
use crate::fx::FxHashMap;
use crate::stable_hasher::{HashStable, StableHasher, StableHasherResult};
use crate::stable_hasher::{HashStable, StableHasher};
use crate::sync::Lock;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::fmt::Debug;
@@ -442,9 +442,7 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
impl<CTX, T> HashStable<CTX> for TransitiveRelation<T>
where T: HashStable<CTX> + Eq + Debug + Clone + Hash
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
// We are assuming here that the relation graph has been built in a
// deterministic way and we can just hash it the way it is.
let TransitiveRelation {
@@ -462,9 +460,7 @@ fn hash_stable<W: StableHasherResult>(&self,
}
impl<CTX> HashStable<CTX> for Edge {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
let Edge {
ref source,
ref target,
@@ -476,9 +472,7 @@ fn hash_stable<W: StableHasherResult>(&self,
}
impl<CTX> HashStable<CTX> for Index {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut CTX,
hasher: &mut StableHasher<W>) {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
let Index(idx) = *self;
idx.hash_stable(hcx, hasher);
}