fix enum discriminants not being included in the hash

This commit is contained in:
Intege-rs
2026-02-03 03:39:43 -05:00
parent f8e3e4ae8e
commit d99f1511eb
2 changed files with 30 additions and 1 deletions

View File

@@ -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 {
@@ -69,8 +74,9 @@ pub fn derive_hash2(input: TokenStream) -> TokenStream {
} }
} }
}); });
quote! { quote! {
#discriminant_hash
match self { match self {
#(#variants)* #(#variants)*
} }

View File

@@ -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;