diff --git a/cairo-tests/src/integer_test.cairo b/cairo-tests/src/integer_test.cairo index 6cf54645a..efffa0f58 100644 --- a/cairo-tests/src/integer_test.cairo +++ b/cairo-tests/src/integer_test.cairo @@ -1088,9 +1088,7 @@ fn validate_cast_bounds_overlapping< validate_max_strictly_contained::(err); } -// TODO: fails #[test] -#[ignore] fn proper_cast() { validate_cast_bounds_contained_same_min::('u8 u16 casts'); validate_cast_bounds_contained_same_min::('u8 u32 casts'); diff --git a/src/libfuncs/cast.rs b/src/libfuncs/cast.rs index 381376d13..90f9996cb 100644 --- a/src/libfuncs/cast.rs +++ b/src/libfuncs/cast.rs @@ -81,24 +81,27 @@ pub fn build_downcast<'ctx, 'this>( location, ); - let is_signed = src_type.is_integer_signed().ok_or_else(|| { + let src_is_signed = src_type.is_integer_signed().ok_or_else(|| { Error::SierraAssert("casts always happen between numerical types".to_string()) - })? || dst_type.is_integer_signed().ok_or_else(|| { + })?; + let dst_is_signed = dst_type.is_integer_signed().ok_or_else(|| { Error::SierraAssert("casts always happen between numerical types".to_string()) })?; - let is_felt = matches!(src_type, CoreTypeConcrete::Felt252(_)); + + let is_signed = src_is_signed || dst_is_signed; + let src_is_felt = matches!(src_type, CoreTypeConcrete::Felt252(_)); let src_value: melior::ir::Value = entry.argument(1)?.into(); let mut block = entry; - let (is_in_range, result) = if src_ty == dst_ty { + let (is_in_range, result) = if info.from_ty == info.to_ty { let k0 = block.const_int(context, location, 0, 1)?; (k0, src_value) } else { // make unsigned felt into signed felt // felt > half prime = negative - let src_value = if is_felt { + let src_value = if src_is_felt { let attr_halfprime_i252 = metadata .get::>() .ok_or(Error::MissingMetadata)? @@ -184,7 +187,8 @@ pub fn build_downcast<'ctx, 'this>( info.to_range .intersection(&info.from_range) .ok_or_else(|| Error::SierraAssert("range should always interesct".to_string()))? - .upper, + .upper + - 1, compare_ty, )?; @@ -201,9 +205,9 @@ pub fn build_downcast<'ctx, 'this>( let is_in_range_upper = block.append_op_result(arith::cmpi( context, if is_signed { - CmpiPredicate::Slt + CmpiPredicate::Sle } else { - CmpiPredicate::Ult + CmpiPredicate::Ule }, compare_value, max_value,