From 5967e812a2a887f44fb49443f06e1fac5cf4e916 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 8 Apr 2025 21:52:47 -0700 Subject: [PATCH] fix [SU]IntValue's PartialEq for interning different widths must make values compare not equal otherwise interning will e.g. substitute a 0x0_u8 for a 0x0_u2 --- crates/fayalite/src/int.rs | 31 +++++++++++++++---------------- crates/fayalite/src/sim/value.rs | 8 ++++---- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/crates/fayalite/src/int.rs b/crates/fayalite/src/int.rs index 053bd1d..d8364b1 100644 --- a/crates/fayalite/src/int.rs +++ b/crates/fayalite/src/int.rs @@ -765,7 +765,7 @@ macro_rules! impl_int { } } - #[derive(Clone, Eq, Hash)] + #[derive(Clone, PartialEq, Eq, Hash)] pub struct $value { bits: Arc, _phantom: PhantomData, @@ -811,24 +811,15 @@ macro_rules! impl_int { } } - impl PartialEq<$value> for $value { - fn eq(&self, other: &$value) -> bool { - self.to_bigint() == other.to_bigint() - } - } - - impl PartialOrd<$value> for $value { - fn partial_cmp(&self, other: &$value) -> Option { + impl PartialOrd for $value { + fn partial_cmp(&self, other: &Self) -> Option { + if self.width() != other.width() { + return None; + } Some(self.to_bigint().cmp(&other.to_bigint())) } } - impl Ord for $value { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.to_bigint().cmp(&other.to_bigint()) - } - } - impl From<$value> for BigInt { fn from(v: $value) -> BigInt { v.to_bigint() @@ -1069,7 +1060,8 @@ pub trait BoolOrIntType: Type + sealed::BoolOrIntTypeSealed { type Width: Size; type Signed: GenericConstBool; type Value: Clone - + Ord + + PartialOrd + + Eq + std::hash::Hash + fmt::Debug + fmt::Display @@ -1300,6 +1292,13 @@ impl ToLiteralBits for bool { mod tests { use super::*; + #[test] + fn test_different_value_widths_compare_ne() { + // interning relies on [SU]IntValue with different `width` comparing not equal + assert_ne!(UInt[3].from_int_wrapping(0), UInt[4].from_int_wrapping(0)); + assert_ne!(SInt[3].from_int_wrapping(0), SInt[4].from_int_wrapping(0)); + } + #[test] fn test_uint_for_value() { assert_eq!(UInt::for_value(0u8).width, 0); diff --git a/crates/fayalite/src/sim/value.rs b/crates/fayalite/src/sim/value.rs index 737043a..8dace78 100644 --- a/crates/fayalite/src/sim/value.rs +++ b/crates/fayalite/src/sim/value.rs @@ -324,14 +324,14 @@ impl, U: Type> PartialEq> for SimValue { } } -impl SimValuePartialEq> for UIntType { - fn sim_value_eq(this: &SimValue, other: &SimValue>) -> bool { +impl SimValuePartialEq for UIntType { + fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { **this == **other } } -impl SimValuePartialEq> for SIntType { - fn sim_value_eq(this: &SimValue, other: &SimValue>) -> bool { +impl SimValuePartialEq for SIntType { + fn sim_value_eq(this: &SimValue, other: &SimValue) -> bool { **this == **other } }