fix enum discriminants not being included in the hash
This commit is contained in:
@@ -35,6 +35,11 @@ pub fn derive_hash2(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Data::Enum(data) => {
|
Data::Enum(data) => {
|
||||||
|
// Hash the discriminant first to ensure different variants hash differently
|
||||||
|
let discriminant_hash = quote! {
|
||||||
|
core::mem::discriminant(self).hash(state);
|
||||||
|
};
|
||||||
|
|
||||||
let variants = data.variants.iter().map(|variant| {
|
let variants = data.variants.iter().map(|variant| {
|
||||||
let variant_name = &variant.ident;
|
let variant_name = &variant.ident;
|
||||||
match &variant.fields {
|
match &variant.fields {
|
||||||
@@ -71,6 +76,7 @@ pub fn derive_hash2(input: TokenStream) -> TokenStream {
|
|||||||
});
|
});
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
|
#discriminant_hash
|
||||||
match self {
|
match self {
|
||||||
#(#variants)*
|
#(#variants)*
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use std::hash::{Hash, Hasher};
|
||||||
use hash2::Hash2;
|
use hash2::Hash2;
|
||||||
|
|
||||||
#[derive(Hash2)]
|
#[derive(Hash2)]
|
||||||
@@ -49,6 +50,13 @@ where
|
|||||||
ref2: &'b str,
|
ref2: &'b str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Hash2)]
|
||||||
|
enum ScalerEnum {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Hash2)]
|
#[derive(Hash2)]
|
||||||
enum SimpleEnum {
|
enum SimpleEnum {
|
||||||
A,
|
A,
|
||||||
@@ -141,6 +149,21 @@ fn test_complex() {
|
|||||||
let _ = hash_value(&s);
|
let _ = hash_value(&s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_scaler_enum() {
|
||||||
|
let e1 = ScalerEnum::A;
|
||||||
|
let e2 = ScalerEnum::B;
|
||||||
|
let e3 = ScalerEnum::C;
|
||||||
|
|
||||||
|
let a = hash_value(&e1);
|
||||||
|
let b = hash_value(&e2);
|
||||||
|
let c = hash_value(&e3);
|
||||||
|
assert_ne!(a, b);
|
||||||
|
assert_ne!(a, c);
|
||||||
|
assert_ne!(b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple_enum() {
|
fn test_simple_enum() {
|
||||||
let e1 = SimpleEnum::A;
|
let e1 = SimpleEnum::A;
|
||||||
|
|||||||
Reference in New Issue
Block a user