parent
5bdec9e1d8
commit
de40124adb
@ -964,8 +964,11 @@ fn create_native_elem_impl(element: &Elem) -> TokenStream {
|
||||
#foundations::Element::of::<Self>()
|
||||
}
|
||||
|
||||
fn dyn_hash(&self, mut hasher: &mut dyn ::std::hash::Hasher) {
|
||||
<Self as ::std::hash::Hash>::hash(self, &mut hasher);
|
||||
fn dyn_hash(&self, mut state: &mut dyn ::std::hash::Hasher) {
|
||||
// Also hash the TypeId since values with different types but
|
||||
// equal data should be different.
|
||||
::std::hash::Hash::hash(&::std::any::TypeId::of::<Self>(), &mut state);
|
||||
::std::hash::Hash::hash(self, &mut state);
|
||||
}
|
||||
|
||||
fn dyn_eq(&self, other: &#foundations::Content) -> bool {
|
||||
|
@ -66,7 +66,8 @@ use crate::util::fat;
|
||||
/// elements the content is composed of and what fields they have.
|
||||
/// Alternatively, you can inspect the output of the [`repr`]($repr) function.
|
||||
#[ty(scope)]
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Hash)]
|
||||
#[allow(clippy::derived_hash_with_manual_eq)]
|
||||
pub struct Content(Arc<dyn NativeElement>);
|
||||
|
||||
impl Content {
|
||||
@ -607,12 +608,6 @@ impl From<Arc<dyn NativeElement>> for Content {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for Content {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.dyn_hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Content {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
// Additional short circuit for different elements.
|
||||
|
@ -2,7 +2,7 @@ use std::any::{Any, TypeId};
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::hash::Hasher;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ecow::EcoString;
|
||||
@ -275,6 +275,12 @@ pub trait NativeElement: Debug + Repr + Construct + Set + Send + Sync + 'static
|
||||
fn fields(&self) -> Dict;
|
||||
}
|
||||
|
||||
impl Hash for dyn NativeElement {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.dyn_hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// An element's constructor function.
|
||||
pub trait Construct {
|
||||
/// Construct an element from the arguments.
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::any::Any;
|
||||
use std::any::{Any, TypeId};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::hash::{Hash, Hasher};
|
||||
@ -258,6 +258,7 @@ impl Debug for Property {
|
||||
/// We're using a `Box` since values will either be contained in an `Arc` and
|
||||
/// therefore already on the heap or they will be small enough that we can just
|
||||
/// clone them.
|
||||
#[derive(Hash)]
|
||||
struct Block(Box<dyn Blockable>);
|
||||
|
||||
impl Block {
|
||||
@ -278,12 +279,6 @@ impl Debug for Block {
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for Block {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.0.dyn_hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Block {
|
||||
fn clone(&self) -> Self {
|
||||
self.0.dyn_clone()
|
||||
@ -318,6 +313,9 @@ impl<T: Debug + Clone + Hash + Send + Sync + 'static> Blockable for T {
|
||||
}
|
||||
|
||||
fn dyn_hash(&self, mut state: &mut dyn Hasher) {
|
||||
// Also hash the TypeId since values with different types but
|
||||
// equal data should be different.
|
||||
TypeId::of::<Self>().hash(&mut state);
|
||||
self.hash(&mut state);
|
||||
}
|
||||
|
||||
@ -326,6 +324,12 @@ impl<T: Debug + Clone + Hash + Send + Sync + 'static> Blockable for T {
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for dyn Blockable {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.dyn_hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// A show rule recipe.
|
||||
#[derive(Clone, PartialEq, Hash)]
|
||||
pub struct Recipe {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::any::Any;
|
||||
use std::any::{Any, TypeId};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::hash::{Hash, Hasher};
|
||||
@ -8,7 +8,6 @@ use ecow::{eco_format, EcoString};
|
||||
use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
|
||||
use serde::de::{Error, MapAccess, SeqAccess, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use siphasher::sip128::{Hasher128, SipHasher13};
|
||||
|
||||
use crate::diag::StrResult;
|
||||
use crate::eval::ops;
|
||||
@ -544,7 +543,7 @@ trait Bounds: Debug + Repr + Sync + Send + 'static {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn dyn_eq(&self, other: &Dynamic) -> bool;
|
||||
fn dyn_ty(&self) -> Type;
|
||||
fn hash128(&self) -> u128;
|
||||
fn dyn_hash(&self, state: &mut dyn Hasher);
|
||||
}
|
||||
|
||||
impl<T> Bounds for T
|
||||
@ -564,20 +563,17 @@ where
|
||||
Type::of::<T>()
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
fn hash128(&self) -> u128 {
|
||||
fn dyn_hash(&self, mut state: &mut dyn Hasher) {
|
||||
// Also hash the TypeId since values with different types but
|
||||
// equal data should be different.
|
||||
let mut state = SipHasher13::new();
|
||||
self.type_id().hash(&mut state);
|
||||
TypeId::of::<Self>().hash(&mut state);
|
||||
self.hash(&mut state);
|
||||
state.finish128().as_u128()
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for dyn Bounds {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
state.write_u128(self.hash128());
|
||||
self.dyn_hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user