From 014a9575ed1b99f5585549b08f7dbad0acc6d586 Mon Sep 17 00:00:00 2001 From: Mark Koch <48097969+mark-koch@users.noreply.github.com> Date: Thu, 7 Sep 2023 12:52:18 +0100 Subject: [PATCH] fix!: Reduce max int width in arithmetic extension to 64 (#504) This is required for serialisation since msgpack doesn't support `i128` and `u128`: https://github.com/msgpack/msgpack/blob/master/spec.md#int-format-family --------- Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> --- specification/hugr.md | 2 +- src/std_extensions/arithmetic/int_types.rs | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/specification/hugr.md b/specification/hugr.md index 0197ec0aa..c2c01c3dd 100644 --- a/specification/hugr.md +++ b/specification/hugr.md @@ -1583,7 +1583,7 @@ below). The `int` type is parametrized by its width `N`, which is a positive integer. -The possible values of `N` are 2^i for i in the range [0,7]. +The possible values of `N` are 2^i for i in the range [0,6]. The `int` type represents an arbitrary bit string of length `N`. Semantics are defined by the operations. There are three possible diff --git a/src/std_extensions/arithmetic/int_types.rs b/src/std_extensions/arithmetic/int_types.rs index 655441f26..d8d80063b 100644 --- a/src/std_extensions/arithmetic/int_types.rs +++ b/src/std_extensions/arithmetic/int_types.rs @@ -44,7 +44,7 @@ const fn is_valid_log_width(n: u8) -> bool { } /// The smallest forbidden log width. -pub const LOG_WIDTH_BOUND: u8 = 8; +pub const LOG_WIDTH_BOUND: u8 = 7; /// Type parameter for the log width of the integer. // SAFETY: unsafe block should be ok as the value is definitely not zero. @@ -75,25 +75,25 @@ pub(super) const fn type_arg(log_width: u8) -> TypeArg { #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)] pub struct ConstIntU { log_width: u8, - value: u128, + value: u64, } /// A signed integer #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)] pub struct ConstIntS { log_width: u8, - value: i128, + value: i64, } impl ConstIntU { /// Create a new [`ConstIntU`] - pub fn new(log_width: u8, value: u128) -> Result { + pub fn new(log_width: u8, value: u64) -> Result { if !is_valid_log_width(log_width) { return Err(ConstTypeError::CustomCheckFail( crate::types::CustomCheckFailure::Message("Invalid integer width.".to_owned()), )); } - if (log_width <= 6) && (value >= (1u128 << (1u8 << log_width))) { + if (log_width <= 5) && (value >= (1u64 << (1u8 << log_width))) { return Err(ConstTypeError::CustomCheckFail( crate::types::CustomCheckFailure::Message( "Invalid unsigned integer value.".to_owned(), @@ -106,15 +106,14 @@ impl ConstIntU { impl ConstIntS { /// Create a new [`ConstIntS`] - pub fn new(log_width: u8, value: i128) -> Result { + pub fn new(log_width: u8, value: i64) -> Result { if !is_valid_log_width(log_width) { return Err(ConstTypeError::CustomCheckFail( crate::types::CustomCheckFailure::Message("Invalid integer width.".to_owned()), )); } let width = 1u8 << log_width; - if (log_width <= 6) && (value >= (1i128 << (width - 1)) || value < -(1i128 << (width - 1))) - { + if (log_width <= 5) && (value >= (1i64 << (width - 1)) || value < -(1i64 << (width - 1))) { return Err(ConstTypeError::CustomCheckFail( crate::types::CustomCheckFailure::Message( "Invalid signed integer value.".to_owned(), @@ -199,10 +198,8 @@ mod test { assert_matches!(get_log_width(&type_arg_32), Ok(5)); let type_arg_128 = TypeArg::BoundedNat { n: 7 }; - assert_matches!(get_log_width(&type_arg_128), Ok(7)); - let type_arg_256 = TypeArg::BoundedNat { n: 8 }; assert_matches!( - get_log_width(&type_arg_256), + get_log_width(&type_arg_128), Err(TypeArgError::TypeMismatch { .. }) ); }