Skip to content

Commit

Permalink
fix!: Reduce max int width in arithmetic extension to 64 (#504)
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
mark-koch and cqc-alec authored Sep 7, 2023
1 parent be0be36 commit 014a957
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 12 deletions.
2 changes: 1 addition & 1 deletion specification/hugr.md
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,7 @@ below).
The `int<N>` 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<N>` type represents an arbitrary bit string of length `N`.
Semantics are defined by the operations. There are three possible
Expand Down
19 changes: 8 additions & 11 deletions src/std_extensions/arithmetic/int_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<Self, ConstTypeError> {
pub fn new(log_width: u8, value: u64) -> Result<Self, ConstTypeError> {
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(),
Expand All @@ -106,15 +106,14 @@ impl ConstIntU {

impl ConstIntS {
/// Create a new [`ConstIntS`]
pub fn new(log_width: u8, value: i128) -> Result<Self, ConstTypeError> {
pub fn new(log_width: u8, value: i64) -> Result<Self, ConstTypeError> {
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(),
Expand Down Expand Up @@ -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 { .. })
);
}
Expand Down

0 comments on commit 014a957

Please sign in to comment.