diff --git a/crates/nargo_cli/tests/test_data/numeric_generics/src/main.nr b/crates/nargo_cli/tests/test_data/numeric_generics/src/main.nr index 7d73eabe2be..ebe50c4d0d9 100644 --- a/crates/nargo_cli/tests/test_data/numeric_generics/src/main.nr +++ b/crates/nargo_cli/tests/test_data/numeric_generics/src/main.nr @@ -19,10 +19,21 @@ fn id(x: [Field; I]) -> [Field; I] { } struct MyStruct { - data: [Field; S] + data: [Field; S], +} + +impl MyStruct { + fn insert(mut self: Self, index: comptime Field, elem: Field) -> Self { + // Regression test for numeric generics on impls + constrain index as u64 < S as u64; + + self.data[index] = elem; + self + } } fn foo(mut s: MyStruct<2+1>) -> MyStruct<10/2-2> { s.data[0] = s.data[0] + 1; s } + diff --git a/crates/noirc_frontend/src/hir/type_check/expr.rs b/crates/noirc_frontend/src/hir/type_check/expr.rs index f03420704cc..e57dcdb0ffc 100644 --- a/crates/noirc_frontend/src/hir/type_check/expr.rs +++ b/crates/noirc_frontend/src/hir/type_check/expr.rs @@ -512,6 +512,9 @@ impl<'interner> TypeChecker<'interner> { use crate::BinaryOpKind::{Equal, NotEqual}; use Type::*; match (lhs_type, rhs_type) { + // Avoid reporting errors multiple times + (Error, _) | (_,Error) => Ok(Bool(CompTime::Yes(None))), + // Matches on PolymorphicInteger and TypeVariable must be first to follow any type // bindings. (PolymorphicInteger(comptime, int), other) @@ -572,9 +575,6 @@ impl<'interner> TypeChecker<'interner> { Ok(Bool(comptime)) } - // Avoid reporting errors multiple times - (Error, _) | (_,Error) => Ok(Bool(CompTime::Yes(None))), - // Special-case == and != for arrays (Array(x_size, x_type), Array(y_size, y_type)) if matches!(op.kind, Equal | NotEqual) => { x_type.unify(y_type, op.location.span, &mut self.errors, || { @@ -728,6 +728,9 @@ impl<'interner> TypeChecker<'interner> { use Type::*; match (lhs_type, rhs_type) { + // An error type on either side will always return an error + (Error, _) | (_,Error) => Ok(Error), + // Matches on PolymorphicInteger and TypeVariable must be first so that we follow any type // bindings. (PolymorphicInteger(comptime, int), other) @@ -793,8 +796,6 @@ impl<'interner> TypeChecker<'interner> { (Struct(..), _) | (_, Struct(..)) => Err(make_error("Structs cannot be used in an infix operation".to_string())), (Tuple(_), _) | (_, Tuple(_)) => Err(make_error("Tuples cannot be used in an infix operation".to_string())), - // An error type on either side will always return an error - (Error, _) | (_,Error) => Ok(Error), (Unit, _) | (_,Unit) => Ok(Unit), // The result of two Fields is always a witness