diff --git a/crates/nargo_cli/tests/execution_success/4_sub/src/main.nr b/crates/nargo_cli/tests/execution_success/4_sub/src/main.nr index 80fc0177e41..43ea9d5b4f0 100644 --- a/crates/nargo_cli/tests/execution_success/4_sub/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/4_sub/src/main.nr @@ -2,4 +2,8 @@ fn main(mut x: u32, y: u32, z: u32) { x -= y; assert(x == z); + + // Test constant underflow (regression for #2045) + let x = -1 as u4; + assert(x == 15); } diff --git a/crates/noirc_evaluator/src/errors.rs b/crates/noirc_evaluator/src/errors.rs index 27a87ccce36..038210f86e1 100644 --- a/crates/noirc_evaluator/src/errors.rs +++ b/crates/noirc_evaluator/src/errors.rs @@ -22,7 +22,7 @@ pub enum RuntimeError { InternalError(#[from] InternalError), #[error("Index out of bounds, array has size {index:?}, but index was {array_size:?}")] IndexOutOfBounds { index: usize, array_size: usize, location: Option }, - #[error("All Witnesses are by default u{num_bits:?} Applying this type does not apply any constraints.\n We also currently do not allow integers of size more than {num_bits:?}, this will be handled by BigIntegers.")] + #[error("Range constraint of {num_bits} bits is too large for the Field size")] InvalidRangeConstraint { num_bits: u32, location: Option }, #[error("Expected array index to fit into a u64")] TypeConversion { from: String, into: String, location: Option }, diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction.rs b/crates/noirc_evaluator/src/ssa/ir/instruction.rs index 510c876e25c..433bf2013a7 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/crates/noirc_evaluator/src/ssa/ir/instruction.rs @@ -653,7 +653,7 @@ impl Binary { let lhs = truncate(lhs.try_into_u128()?, *bit_size); let rhs = truncate(rhs.try_into_u128()?, *bit_size); - let result = function(lhs, rhs)?; + let result = function(lhs, rhs); truncate(result, *bit_size).into() } _ => return None, @@ -689,18 +689,18 @@ impl BinaryOp { } } - fn get_u128_function(self) -> fn(u128, u128) -> Option { + fn get_u128_function(self) -> fn(u128, u128) -> u128 { match self { - BinaryOp::Add => u128::checked_add, - BinaryOp::Sub => u128::checked_sub, - BinaryOp::Mul => u128::checked_mul, - BinaryOp::Div => u128::checked_div, - BinaryOp::Mod => u128::checked_rem, - BinaryOp::And => |x, y| Some(x & y), - BinaryOp::Or => |x, y| Some(x | y), - BinaryOp::Xor => |x, y| Some(x ^ y), - BinaryOp::Eq => |x, y| Some((x == y) as u128), - BinaryOp::Lt => |x, y| Some((x < y) as u128), + BinaryOp::Add => u128::wrapping_add, + BinaryOp::Sub => u128::wrapping_sub, + BinaryOp::Mul => u128::wrapping_mul, + BinaryOp::Div => u128::wrapping_div, + BinaryOp::Mod => u128::wrapping_rem, + BinaryOp::And => |x, y| x & y, + BinaryOp::Or => |x, y| x | y, + BinaryOp::Xor => |x, y| x ^ y, + BinaryOp::Eq => |x, y| (x == y) as u128, + BinaryOp::Lt => |x, y| (x < y) as u128, } } } diff --git a/crates/noirc_evaluator/src/ssa/ssa_gen/mod.rs b/crates/noirc_evaluator/src/ssa/ssa_gen/mod.rs index 0c0dd35211b..65129f1f933 100644 --- a/crates/noirc_evaluator/src/ssa/ssa_gen/mod.rs +++ b/crates/noirc_evaluator/src/ssa/ssa_gen/mod.rs @@ -268,6 +268,7 @@ impl<'a> FunctionContext<'a> { fn codegen_cast(&mut self, cast: &ast::Cast) -> Values { let lhs = self.codegen_non_tuple_expression(&cast.lhs); let typ = Self::convert_non_tuple_type(&cast.r#type); + self.builder.set_location(cast.location); self.builder.insert_cast(lhs, typ).into() } diff --git a/crates/noirc_frontend/src/monomorphization/ast.rs b/crates/noirc_frontend/src/monomorphization/ast.rs index 33c3bbebff4..e748cc74d13 100644 --- a/crates/noirc_frontend/src/monomorphization/ast.rs +++ b/crates/noirc_frontend/src/monomorphization/ast.rs @@ -120,6 +120,7 @@ pub struct If { pub struct Cast { pub lhs: Box, pub r#type: Type, + pub location: Location, } #[derive(Debug, Clone)] diff --git a/crates/noirc_frontend/src/monomorphization/mod.rs b/crates/noirc_frontend/src/monomorphization/mod.rs index 6c9724de6ce..78d540f398e 100644 --- a/crates/noirc_frontend/src/monomorphization/mod.rs +++ b/crates/noirc_frontend/src/monomorphization/mod.rs @@ -319,6 +319,7 @@ impl<'interner> Monomorphizer<'interner> { HirExpression::Cast(cast) => ast::Expression::Cast(ast::Cast { lhs: Box::new(self.expr(cast.lhs)), r#type: Self::convert_type(&cast.r#type), + location: self.interner.expr_location(&expr), }), HirExpression::For(for_expr) => {