diff --git a/corelib/src/test/integer_test.cairo b/corelib/src/test/integer_test.cairo index 887484ebda9..c7a76699754 100644 --- a/corelib/src/test/integer_test.cairo +++ b/corelib/src/test/integer_test.cairo @@ -2003,14 +2003,15 @@ mod bounded_int { type RemT; } extern fn bounded_int_div_rem>( - a: T1, b: T2 + a: T1, b: NonZero ) -> (DRR::DivT, DRR::RemT) implicits(RangeCheck) nopanic; + extern fn bounded_int_wrap_non_zero(v: T) -> NonZero nopanic; /// Same as `bounded_int_div_rem`, but unwraps the result into felt252s. fn bounded_int_div_rem_unwrapped>( a: T1, b: T2 ) -> (felt252, felt252) { - let (q, r) = bounded_int_div_rem(a, b); + let (q, r) = bounded_int_div_rem(a, bounded_int_wrap_non_zero(b)); (upcast(q), upcast(r)) } diff --git a/crates/cairo-lang-sierra/src/extensions/modules/bounded_int.rs b/crates/cairo-lang-sierra/src/extensions/modules/bounded_int.rs index c67aab936dc..d07a59d07a7 100644 --- a/crates/cairo-lang-sierra/src/extensions/modules/bounded_int.rs +++ b/crates/cairo-lang-sierra/src/extensions/modules/bounded_int.rs @@ -163,9 +163,10 @@ impl NamedLibfunc for BoundedIntDivRemLibfunc { let (lhs, rhs) = args_as_two_types(args)?; let lhs_range = Range::from_type(context, lhs.clone())?; let rhs_range = Range::from_type(context, rhs.clone())?; - // Supporting only division of a non-negative number by a positive number. + // Supporting only division of a non-negative number by a positive number (non zero + and + // non negative). // TODO(orizi): Consider relaxing the constraint, and defining the div_rem of negatives. - if lhs_range.lower.is_negative() || !rhs_range.lower.is_positive() { + if lhs_range.lower.is_negative() || rhs_range.lower.is_negative() { return Err(SpecializationError::UnsupportedGenericArg); } // Making sure the algorithm is runnable. @@ -179,7 +180,7 @@ impl NamedLibfunc for BoundedIntDivRemLibfunc { vec![ ParamSignature::new(range_check_type.clone()).with_allow_add_const(), ParamSignature::new(lhs.clone()), - ParamSignature::new(rhs.clone()), + ParamSignature::new(nonzero_ty(context, &rhs)?), ], vec![ OutputVarInfo::new_builtin(range_check_type.clone(), 0), diff --git a/tests/e2e_test_data/libfuncs/bounded_int b/tests/e2e_test_data/libfuncs/bounded_int index 76bb754be82..3865aa6b63b 100644 --- a/tests/e2e_test_data/libfuncs/bounded_int +++ b/tests/e2e_test_data/libfuncs/bounded_int @@ -169,9 +169,9 @@ type DivRemType = ( BoundedInt<0, 7>, ); -extern fn bounded_int_div_rem(a: T1, b: T2) -> DivRemType implicits(RangeCheck) nopanic; +extern fn bounded_int_div_rem(a: T1, b: NonZero) -> DivRemType implicits(RangeCheck) nopanic; -fn foo(a: BoundedInt<128, 255>, b: BoundedInt<3, 8>) -> DivRemType { +fn foo(a: BoundedInt<128, 255>, b: NonZero>) -> DivRemType { bounded_int_div_rem(a, b) } @@ -198,6 +198,7 @@ type BoundedInt<16, 85> = BoundedInt<16, 85> [storable: true, drop: true, dup: t type BoundedInt<0, 7> = BoundedInt<0, 7> [storable: true, drop: true, dup: true, zero_sized: false]; type Tuple, BoundedInt<0, 7>> = Struct, BoundedInt<0, 7>> [storable: true, drop: true, dup: true, zero_sized: false]; type BoundedInt<3, 8> = BoundedInt<3, 8> [storable: true, drop: true, dup: true, zero_sized: false]; +type NonZero> = NonZero> [storable: true, drop: true, dup: true, zero_sized: false]; type BoundedInt<128, 255> = BoundedInt<128, 255> [storable: true, drop: true, dup: true, zero_sized: false]; libfunc bounded_int_div_rem, BoundedInt<3, 8>> = bounded_int_div_rem, BoundedInt<3, 8>>; @@ -211,7 +212,7 @@ store_temp([3]) -> ([3]); // 2 store_temp, BoundedInt<0, 7>>>([6]) -> ([6]); // 3 return([3], [6]); // 4 -test::foo@0([0]: RangeCheck, [1]: BoundedInt<128, 255>, [2]: BoundedInt<3, 8>) -> (RangeCheck, Tuple, BoundedInt<0, 7>>); +test::foo@0([0]: RangeCheck, [1]: BoundedInt<128, 255>, [2]: NonZero>) -> (RangeCheck, Tuple, BoundedInt<0, 7>>); //! > ========================================================================== @@ -227,9 +228,9 @@ type DivRemType = ( BoundedInt<0, 0xfffffffffffffffffffffffffffffffe>, ); -extern fn bounded_int_div_rem(a: T1, b: T2) -> DivRemType implicits(RangeCheck) nopanic; +extern fn bounded_int_div_rem(a: T1, b: NonZero) -> DivRemType implicits(RangeCheck) nopanic; -fn foo(a: u128, b: BoundedInt<1, 0xffffffffffffffffffffffffffffffff>) -> DivRemType { +fn foo(a: u128, b: NonZero>) -> DivRemType { bounded_int_div_rem(a, b) } @@ -262,6 +263,7 @@ type BoundedInt<0, 340282366920938463463374607431768211455> = BoundedInt<0, 3402 type BoundedInt<0, 340282366920938463463374607431768211454> = BoundedInt<0, 340282366920938463463374607431768211454> [storable: true, drop: true, dup: true, zero_sized: false]; type Tuple, BoundedInt<0, 340282366920938463463374607431768211454>> = Struct, BoundedInt<0, 340282366920938463463374607431768211454>> [storable: true, drop: true, dup: true, zero_sized: false]; type BoundedInt<1, 340282366920938463463374607431768211455> = BoundedInt<1, 340282366920938463463374607431768211455> [storable: true, drop: true, dup: true, zero_sized: false]; +type NonZero> = NonZero> [storable: true, drop: true, dup: true, zero_sized: false]; type u128 = u128 [storable: true, drop: true, dup: true, zero_sized: false]; libfunc bounded_int_div_rem> = bounded_int_div_rem>; @@ -275,7 +277,7 @@ store_temp([3]) -> ([3]); // 2 store_temp, BoundedInt<0, 340282366920938463463374607431768211454>>>([6]) -> ([6]); // 3 return([3], [6]); // 4 -test::foo@0([0]: RangeCheck, [1]: u128, [2]: BoundedInt<1, 340282366920938463463374607431768211455>) -> (RangeCheck, Tuple, BoundedInt<0, 340282366920938463463374607431768211454>>); +test::foo@0([0]: RangeCheck, [1]: u128, [2]: NonZero>) -> (RangeCheck, Tuple, BoundedInt<0, 340282366920938463463374607431768211454>>); //! > ========================================================================== @@ -291,9 +293,9 @@ type DivRemType = ( BoundedInt<0, 0xfffffffffffffffffffffffffffffff>, ); -extern fn bounded_int_div_rem(a: T1, b: T2) -> DivRemType implicits(RangeCheck) nopanic; +extern fn bounded_int_div_rem(a: T1, b: NonZero) -> DivRemType implicits(RangeCheck) nopanic; -fn foo(a: u128, b: BoundedInt<0x10000000000000000000000000000000, 0x10000000000000000000000000000000>) -> DivRemType { +fn foo(a: u128, b: NonZero>) -> DivRemType { bounded_int_div_rem(a, b) } @@ -322,6 +324,7 @@ type BoundedInt<0, 15> = BoundedInt<0, 15> [storable: true, drop: true, dup: tru type BoundedInt<0, 21267647932558653966460912964485513215> = BoundedInt<0, 21267647932558653966460912964485513215> [storable: true, drop: true, dup: true, zero_sized: false]; type Tuple, BoundedInt<0, 21267647932558653966460912964485513215>> = Struct, BoundedInt<0, 21267647932558653966460912964485513215>> [storable: true, drop: true, dup: true, zero_sized: false]; type BoundedInt<21267647932558653966460912964485513216, 21267647932558653966460912964485513216> = BoundedInt<21267647932558653966460912964485513216, 21267647932558653966460912964485513216> [storable: true, drop: true, dup: true, zero_sized: false]; +type NonZero> = NonZero> [storable: true, drop: true, dup: true, zero_sized: false]; type u128 = u128 [storable: true, drop: true, dup: true, zero_sized: false]; libfunc bounded_int_div_rem> = bounded_int_div_rem>; @@ -335,7 +338,7 @@ store_temp([3]) -> ([3]); // 2 store_temp, BoundedInt<0, 21267647932558653966460912964485513215>>>([6]) -> ([6]); // 3 return([3], [6]); // 4 -test::foo@0([0]: RangeCheck, [1]: u128, [2]: BoundedInt<21267647932558653966460912964485513216, 21267647932558653966460912964485513216>) -> (RangeCheck, Tuple, BoundedInt<0, 21267647932558653966460912964485513215>>); +test::foo@0([0]: RangeCheck, [1]: u128, [2]: NonZero>) -> (RangeCheck, Tuple, BoundedInt<0, 21267647932558653966460912964485513215>>); //! > ==========================================================================