From b6f65ca467e7df865d857e266f5e2d403517f845 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Thu, 27 Jul 2023 20:06:24 +0100 Subject: [PATCH] Derive PartialEq for ConstValue (impl only for dyn CustomConst) Add extra tuple to workaround https://github.com/rust-lang/rust/issues/78808 Rename CustomConst::(eq => equal_consts) to disambiguate --- src/hugr/typecheck.rs | 2 +- src/ops/constant.rs | 44 ++++++++++--------------------------------- 2 files changed, 11 insertions(+), 35 deletions(-) diff --git a/src/hugr/typecheck.rs b/src/hugr/typecheck.rs index 7d86346b0..b7e2fa01b 100644 --- a/src/hugr/typecheck.rs +++ b/src/hugr/typecheck.rs @@ -155,7 +155,7 @@ pub fn typecheck_const(typ: &ClassicType, val: &ConstValue) -> Result<(), ConstT (Container::Sum(_), _) => { Err(ConstTypeError::TypeMismatch(ty.clone(), tm.const_type())) } - (Container::Opaque(ty), ConstValue::Opaque(ty_act, _val)) => { + (Container::Opaque(ty), ConstValue::Opaque((ty_act, _val))) => { if ty_act != ty { return Err(ConstTypeError::TypeMismatch( ty.clone().into(), diff --git a/src/ops/constant.rs b/src/ops/constant.rs index db6f5941c..2c8a79fb3 100644 --- a/src/ops/constant.rs +++ b/src/ops/constant.rs @@ -48,7 +48,7 @@ pub(crate) const HUGR_MAX_INT_WIDTH: HugrIntWidthStore = /// /// TODO: Add more constants /// TODO: bigger/smaller integers. -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] +#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)] #[non_exhaustive] #[allow(missing_docs)] pub enum ConstValue { @@ -69,38 +69,14 @@ pub enum ConstValue { }, /// A tuple of constant values. Tuple(Vec), - /// An opaque constant value, with cached type. - Opaque(CustomType, Box), + /// An opaque constant value, with cached type + // Note: the extra level of tupling is to avoid https://github.com/rust-lang/rust/issues/78808 + Opaque((CustomType, Box)), } -impl PartialEq for ConstValue { +impl PartialEq for dyn CustomConst { fn eq(&self, other: &Self) -> bool { - match (self, other) { - ( - Self::Int { - value: l0, - width: l_width, - }, - Self::Int { - value: r0, - width: r_width, - }, - ) => l0 == r0 && l_width == r_width, - (Self::Opaque(l0, l1), Self::Opaque(r0, r1)) => l0 == r0 && l1.eq(&**r1), - ( - Self::Sum { tag, variants, val }, - Self::Sum { - tag: t1, - variants: type1, - val: v1, - }, - ) => tag == t1 && variants == type1 && val == v1, - - (Self::Tuple(v1), Self::Tuple(v2)) => v1.eq(v2), - (Self::F64(f1), Self::F64(f2)) => f1 == f2, - - _ => false, - } + (*self).equal_consts(other) } } @@ -118,7 +94,7 @@ impl ConstValue { pub fn const_type(&self) -> ClassicType { match self { Self::Int { value: _, width } => HashableType::Int(*width).into(), - Self::Opaque(_, b) => Container::Opaque((*b).custom_type()).into(), + Self::Opaque((_, b)) => Container::Opaque((*b).custom_type()).into(), Self::Sum { variants, .. } => ClassicType::new_sum(variants.clone()), Self::Tuple(vals) => { let row: Vec<_> = vals.iter().map(|val| val.const_type()).collect(); @@ -132,7 +108,7 @@ impl ConstValue { match self { Self::Int { value, width } => format!("const:int<{width}>:{value}"), Self::F64(f) => format!("const:float:{f}"), - Self::Opaque(_, v) => format!("const:{}", v.name()), + Self::Opaque((_, v)) => format!("const:{}", v.name()), Self::Sum { tag, val, .. } => { format!("const:sum:{{tag:{tag}, val:{}}}", val.name()) } @@ -203,7 +179,7 @@ impl ConstValue { impl From for ConstValue { fn from(v: T) -> Self { - Self::Opaque(v.custom_type(), Box::new(v)) + Self::Opaque((v.custom_type(), Box::new(v))) } } @@ -223,7 +199,7 @@ pub trait CustomConst: fn custom_type(&self) -> CustomType; /// Compare two constants for equality, using downcasting and comparing the definitions. - fn eq(&self, other: &dyn CustomConst) -> bool { + fn equal_consts(&self, other: &dyn CustomConst) -> bool { let _ = other; false }