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
This commit is contained in:
Jacob Lifshay 2025-04-08 21:52:47 -07:00
parent 001fd31451
commit 5967e812a2
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
2 changed files with 19 additions and 20 deletions

View file

@ -765,7 +765,7 @@ macro_rules! impl_int {
} }
} }
#[derive(Clone, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]
pub struct $value<Width: Size = DynSize> { pub struct $value<Width: Size = DynSize> {
bits: Arc<BitVec>, bits: Arc<BitVec>,
_phantom: PhantomData<Width>, _phantom: PhantomData<Width>,
@ -811,24 +811,15 @@ macro_rules! impl_int {
} }
} }
impl<LhsWidth: Size, RhsWidth: Size> PartialEq<$value<RhsWidth>> for $value<LhsWidth> { impl<Width: Size> PartialOrd for $value<Width> {
fn eq(&self, other: &$value<RhsWidth>) -> bool { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.to_bigint() == other.to_bigint() if self.width() != other.width() {
} return None;
} }
impl<LhsWidth: Size, RhsWidth: Size> PartialOrd<$value<RhsWidth>> for $value<LhsWidth> {
fn partial_cmp(&self, other: &$value<RhsWidth>) -> Option<std::cmp::Ordering> {
Some(self.to_bigint().cmp(&other.to_bigint())) Some(self.to_bigint().cmp(&other.to_bigint()))
} }
} }
impl<Width: Size> Ord for $value<Width> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.to_bigint().cmp(&other.to_bigint())
}
}
impl<Width: Size> From<$value<Width>> for BigInt { impl<Width: Size> From<$value<Width>> for BigInt {
fn from(v: $value<Width>) -> BigInt { fn from(v: $value<Width>) -> BigInt {
v.to_bigint() v.to_bigint()
@ -1069,7 +1060,8 @@ pub trait BoolOrIntType: Type + sealed::BoolOrIntTypeSealed {
type Width: Size; type Width: Size;
type Signed: GenericConstBool; type Signed: GenericConstBool;
type Value: Clone type Value: Clone
+ Ord + PartialOrd
+ Eq
+ std::hash::Hash + std::hash::Hash
+ fmt::Debug + fmt::Debug
+ fmt::Display + fmt::Display
@ -1300,6 +1292,13 @@ impl ToLiteralBits for bool {
mod tests { mod tests {
use super::*; 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] #[test]
fn test_uint_for_value() { fn test_uint_for_value() {
assert_eq!(UInt::for_value(0u8).width, 0); assert_eq!(UInt::for_value(0u8).width, 0);

View file

@ -324,14 +324,14 @@ impl<T: SimValuePartialEq<U>, U: Type> PartialEq<SimValue<U>> for SimValue<T> {
} }
} }
impl<LhsWidth: Size, RhsWidth: Size> SimValuePartialEq<UIntType<RhsWidth>> for UIntType<LhsWidth> { impl<Width: Size> SimValuePartialEq<Self> for UIntType<Width> {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<UIntType<RhsWidth>>) -> bool { fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
**this == **other **this == **other
} }
} }
impl<LhsWidth: Size, RhsWidth: Size> SimValuePartialEq<SIntType<RhsWidth>> for SIntType<LhsWidth> { impl<Width: Size> SimValuePartialEq<Self> for SIntType<Width> {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<SIntType<RhsWidth>>) -> bool { fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
**this == **other **this == **other
} }
} }