fix [SU]IntValue's PartialEq for interning
All checks were successful
/ deps (pull_request) Successful in 17s
/ test (pull_request) Successful in 4m23s
/ deps (push) Successful in 13s
/ test (push) Successful in 4m52s

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> {
bits: Arc<BitVec>,
_phantom: PhantomData<Width>,
@ -811,24 +811,15 @@ macro_rules! impl_int {
}
}
impl<LhsWidth: Size, RhsWidth: Size> PartialEq<$value<RhsWidth>> for $value<LhsWidth> {
fn eq(&self, other: &$value<RhsWidth>) -> bool {
self.to_bigint() == other.to_bigint()
}
}
impl<LhsWidth: Size, RhsWidth: Size> PartialOrd<$value<RhsWidth>> for $value<LhsWidth> {
fn partial_cmp(&self, other: &$value<RhsWidth>) -> Option<std::cmp::Ordering> {
impl<Width: Size> PartialOrd for $value<Width> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if self.width() != other.width() {
return None;
}
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 {
fn from(v: $value<Width>) -> 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);

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> {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<UIntType<RhsWidth>>) -> bool {
impl<Width: Size> SimValuePartialEq<Self> for UIntType<Width> {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
**this == **other
}
}
impl<LhsWidth: Size, RhsWidth: Size> SimValuePartialEq<SIntType<RhsWidth>> for SIntType<LhsWidth> {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<SIntType<RhsWidth>>) -> bool {
impl<Width: Size> SimValuePartialEq<Self> for SIntType<Width> {
fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
**this == **other
}
}