diff --git a/crates/nargo/tests/test_data/global_consts/src/main.nr b/crates/nargo/tests/test_data/global_consts/src/main.nr index 2eb785d27fd..fb48eb2b798 100644 --- a/crates/nargo/tests/test_data/global_consts/src/main.nr +++ b/crates/nargo/tests/test_data/global_consts/src/main.nr @@ -4,6 +4,7 @@ mod baz; global M: Field = 32; global L: Field = 10; // Unused globals currently allowed global N: Field = 5; +global T_LEN = 2; // Type inference is allowed on globals //global N: Field = 5; // Uncomment to see duplicate globals error struct Dummy { @@ -40,9 +41,7 @@ fn main(a: [Field; M + N - N], b: [Field; 30 + N / 2], c : pub [Field; foo::MAGI arrays_neq(a, b); - //let mut L: Field = 2; // Uncomment to show expected comptime error for array annotations - let L: comptime Field = 2; - let t: [Field; L] = [N, M]; + let t: [Field; T_LEN] = [N, M]; constrain t[1] == 32; constrain 15 == mysubmodule::my_helper(); diff --git a/crates/nargo/tests/test_data/numeric_generics/Nargo.toml b/crates/nargo/tests/test_data/numeric_generics/Nargo.toml new file mode 100644 index 00000000000..d9434868157 --- /dev/null +++ b/crates/nargo/tests/test_data/numeric_generics/Nargo.toml @@ -0,0 +1,7 @@ + + [package] + authors = [""] + compiler_version = "0.1" + + [dependencies] + \ No newline at end of file diff --git a/crates/nargo/tests/test_data/numeric_generics/Prover.toml b/crates/nargo/tests/test_data/numeric_generics/Prover.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/crates/nargo/tests/test_data/numeric_generics/src/main.nr b/crates/nargo/tests/test_data/numeric_generics/src/main.nr new file mode 100644 index 00000000000..7d73eabe2be --- /dev/null +++ b/crates/nargo/tests/test_data/numeric_generics/src/main.nr @@ -0,0 +1,28 @@ +fn main() { + let a = id([1, 2]); + let b = id([1, 2, 3]); + + let itWorks1 = MyStruct { data: a }; + constrain itWorks1.data[1] == 2; + let itWorks2 = MyStruct { data: b }; + constrain itWorks2.data[1] == 2; + + let c = [1, 2]; + let itAlsoWorks = MyStruct { data: c }; + constrain itAlsoWorks.data[1] == 2; + + constrain foo(itWorks2).data[0] == itWorks2.data[0] + 1; +} + +fn id(x: [Field; I]) -> [Field; I] { + x +} + +struct MyStruct { + data: [Field; S] +} + +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/ast/mod.rs b/crates/noirc_frontend/src/ast/mod.rs index c404b014044..f9c01ff6380 100644 --- a/crates/noirc_frontend/src/ast/mod.rs +++ b/crates/noirc_frontend/src/ast/mod.rs @@ -12,7 +12,7 @@ use noirc_errors::Span; pub use statement::*; pub use structure::*; -use crate::{token::IntType, Comptime}; +use crate::{parser::ParserError, token::IntType, BinaryTypeOperator, Comptime}; use iter_extended::vecmap; /// The parser parses types as 'UnresolvedType's which @@ -21,10 +21,11 @@ use iter_extended::vecmap; #[derive(Debug, PartialEq, Eq, Clone)] pub enum UnresolvedType { FieldElement(Comptime), - Array(Option, Box), // [4]Witness = Array(4, Witness) - Integer(Comptime, Signedness, u32), // u32 = Integer(unsigned, 32) + Array(Option, Box), // [4]Witness = Array(4, Witness) + Integer(Comptime, Signedness, u32), // u32 = Integer(unsigned, 32) Bool(Comptime), - String(Option), + Expression(UnresolvedTypeExpression), + String(Option), Unit, /// A Named UnresolvedType can be a struct type or a type variable @@ -39,6 +40,21 @@ pub enum UnresolvedType { Error, } +/// The precursor to TypeExpression, this is the type that the parser allows +/// to be used in the length position of an array type. Only constants, variables, +/// and numeric binary operators are allowed here. +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum UnresolvedTypeExpression { + Variable(Path), + Constant(u64, Span), + BinaryOperation( + Box, + BinaryTypeOperator, + Box, + Span, + ), +} + impl Recoverable for UnresolvedType { fn error(_: Span) -> Self { UnresolvedType::Error @@ -70,6 +86,7 @@ impl std::fmt::Display for UnresolvedType { let elements = vecmap(elements, ToString::to_string); write!(f, "({})", elements.join(", ")) } + Expression(expression) => expression.fmt(f), Bool(is_const) => write!(f, "{is_const}bool"), String(len) => match len { None => write!(f, "str[]"), @@ -86,6 +103,18 @@ impl std::fmt::Display for UnresolvedType { } } +impl std::fmt::Display for UnresolvedTypeExpression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + UnresolvedTypeExpression::Variable(name) => name.fmt(f), + UnresolvedTypeExpression::Constant(x, _) => x.fmt(f), + UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, _) => { + write!(f, "({lhs} {op} {rhs})") + } + } + } +} + impl UnresolvedType { pub fn from_int_token(token: (Comptime, IntType)) -> UnresolvedType { use {IntType::*, UnresolvedType::Integer}; @@ -101,3 +130,66 @@ pub enum Signedness { Unsigned, Signed, } + +impl UnresolvedTypeExpression { + pub fn from_expr( + expr: Expression, + span: Span, + ) -> Result { + Self::from_expr_helper(expr).map_err(|err| { + ParserError::with_reason( + format!("Expression is invalid in an array-length type: '{err}'. Only unsigned integer constants, globals, generics, +, -, *, /, and % may be used in this context."), + span, + ) + }) + } + + pub fn span(&self) -> Span { + match self { + UnresolvedTypeExpression::Variable(path) => path.span(), + UnresolvedTypeExpression::Constant(_, span) => *span, + UnresolvedTypeExpression::BinaryOperation(_, _, _, span) => *span, + } + } + + fn from_expr_helper(expr: Expression) -> Result { + match expr.kind { + ExpressionKind::Literal(Literal::Integer(int)) => match int.try_to_u64() { + Some(int) => Ok(UnresolvedTypeExpression::Constant(int, expr.span)), + None => Err(expr), + }, + ExpressionKind::Variable(path) => Ok(UnresolvedTypeExpression::Variable(path)), + ExpressionKind::Prefix(prefix) if prefix.operator == UnaryOp::Minus => { + let lhs = Box::new(UnresolvedTypeExpression::Constant(0, expr.span)); + let rhs = Box::new(UnresolvedTypeExpression::from_expr_helper(prefix.rhs)?); + let op = BinaryTypeOperator::Subtraction; + Ok(UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, expr.span)) + } + ExpressionKind::Infix(infix) if Self::operator_allowed(infix.operator.contents) => { + let lhs = Box::new(UnresolvedTypeExpression::from_expr_helper(infix.lhs)?); + let rhs = Box::new(UnresolvedTypeExpression::from_expr_helper(infix.rhs)?); + let op = match infix.operator.contents { + BinaryOpKind::Add => BinaryTypeOperator::Addition, + BinaryOpKind::Subtract => BinaryTypeOperator::Subtraction, + BinaryOpKind::Multiply => BinaryTypeOperator::Multiplication, + BinaryOpKind::Divide => BinaryTypeOperator::Division, + BinaryOpKind::Modulo => BinaryTypeOperator::Modulo, + _ => unreachable!(), // impossible via operator_allowed check + }; + Ok(UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, expr.span)) + } + _ => Err(expr), + } + } + + fn operator_allowed(op: BinaryOpKind) -> bool { + matches!( + op, + BinaryOpKind::Add + | BinaryOpKind::Subtract + | BinaryOpKind::Multiply + | BinaryOpKind::Divide + | BinaryOpKind::Modulo + ) + } +} diff --git a/crates/noirc_frontend/src/hir/resolution/errors.rs b/crates/noirc_frontend/src/hir/resolution/errors.rs index 8429bc50ab5..bc9449de438 100644 --- a/crates/noirc_frontend/src/hir/resolution/errors.rs +++ b/crates/noirc_frontend/src/hir/resolution/errors.rs @@ -38,6 +38,8 @@ pub enum ResolverError { InvalidArrayLengthExpr { span: Span }, #[error("Integer too large to be evaluated in an array length context")] IntegerTooLarge { span: Span }, + #[error("No global or generic type parameter found with the given name")] + NoSuchNumericTypeVariable { path: crate::Path }, #[error("Closures cannot capture mutable variables")] CapturedMutableVariable { span: Span }, } @@ -189,6 +191,11 @@ impl ResolverError { "Array-lengths may be a maximum size of usize::MAX, including intermediate calculations".into(), span, ), + ResolverError::NoSuchNumericTypeVariable { path } => Diagnostic::simple_error( + format!("Cannot find a global or generic type parameter named `{path}`"), + "Only globals or generic type parameters are allowed to be used as an array type's length".to_string(), + path.span(), + ), ResolverError::CapturedMutableVariable { span } => Diagnostic::simple_error( "Closures cannot capture mutable variables".into(), "Mutable variable".into(), diff --git a/crates/noirc_frontend/src/hir/resolution/resolver.rs b/crates/noirc_frontend/src/hir/resolution/resolver.rs index c989c8c6e18..0845ee4aee1 100644 --- a/crates/noirc_frontend/src/hir/resolution/resolver.rs +++ b/crates/noirc_frontend/src/hir/resolution/resolver.rs @@ -39,7 +39,7 @@ use crate::{ }; use crate::{ ArrayLiteral, Generics, LValue, NoirStruct, Path, Pattern, Shared, StructType, Type, - TypeBinding, TypeVariable, UnresolvedType, ERROR_IDENT, + TypeBinding, TypeVariable, UnresolvedType, UnresolvedTypeExpression, ERROR_IDENT, }; use fm::FileId; use iter_extended::vecmap; @@ -302,6 +302,7 @@ impl<'a> Resolver<'a> { let elem = Box::new(self.resolve_type_inner(*elem, new_variables)); Type::Array(Box::new(resolved_size), elem) } + UnresolvedType::Expression(expr) => self.convert_expression_type(expr), UnresolvedType::Integer(comptime, sign, bits) => Type::Integer(comptime, sign, bits), UnresolvedType::Bool(comptime) => Type::Bool(comptime), UnresolvedType::String(size) => { @@ -313,7 +314,7 @@ impl<'a> Resolver<'a> { UnresolvedType::Error => Type::Error, UnresolvedType::Named(path, args) => { // Check if the path is a type variable first. We currently disallow generics on type - // variables since this is what rust does. + // variables since we do not support higher-kinded types. if args.is_empty() && path.segments.len() == 1 { let name = &path.last_segment().0.contents; if let Some((name, (var, _))) = self.generics.get_key_value(name) { @@ -342,10 +343,10 @@ impl<'a> Resolver<'a> { fn resolve_array_size( &mut self, - size: Option, + length: Option, new_variables: &mut Generics, ) -> Type { - match &size { + match length { None => { let id = self.interner.next_type_variable_id(); let typevar = Shared::new(TypeBinding::Unbound(id)); @@ -356,9 +357,47 @@ impl<'a> Resolver<'a> { // require users to explicitly be generic over array lengths. Type::NamedGeneric(typevar, Rc::new("".into())) } - Some(expr) => { - let len = self.eval_array_length(expr); - Type::ArrayLength(len) + Some(length) => self.convert_expression_type(length), + } + } + + fn convert_expression_type(&mut self, length: UnresolvedTypeExpression) -> Type { + match length { + UnresolvedTypeExpression::Variable(path) => { + if path.segments.len() == 1 { + let name = &path.last_segment().0.contents; + if let Some((name, (var, _))) = self.generics.get_key_value(name) { + return Type::NamedGeneric(var.clone(), name.clone()); + } + } + + // If we cannot find a local generic of the same name, try to look up a global + if let Ok(ModuleDefId::GlobalId(id)) = + self.path_resolver.resolve(self.def_maps, path.clone()) + { + Type::Constant(self.eval_global_as_array_length(id)) + } else { + self.push_err(ResolverError::NoSuchNumericTypeVariable { path }); + Type::Constant(0) + } + } + UnresolvedTypeExpression::Constant(int, _) => Type::Constant(int), + UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, _) => { + let (lhs_span, rhs_span) = (lhs.span(), rhs.span()); + let lhs = self.convert_expression_type(*lhs); + let rhs = self.convert_expression_type(*rhs); + + match (lhs, rhs) { + (Type::Constant(lhs), Type::Constant(rhs)) => { + Type::Constant(op.function()(lhs, rhs)) + } + (lhs, _) => { + let span = + if !matches!(lhs, Type::Constant(_)) { lhs_span } else { rhs_span }; + self.push_err(ResolverError::InvalidArrayLengthExpr { span }); + Type::Constant(0) + } + } } } } @@ -914,11 +953,32 @@ impl<'a> Resolver<'a> { } fn eval_array_length(&mut self, length: &Expression) -> u64 { - match self.try_eval_array_length(length).map(|length| length.try_into()) { - Ok(Ok(length_value)) => return length_value, - Ok(Err(_cast_err)) => { - self.push_err(ResolverError::IntegerTooLarge { span: length.span }) + let result = self.try_eval_array_length(length); + self.unwrap_array_length_eval_result(result, length.span) + } + + fn eval_global_as_array_length(&mut self, global: StmtId) -> u64 { + let stmt = match self.interner.statement(&global) { + HirStatement::Let(let_expr) => let_expr, + other => { + unreachable!("Expected global while evaluating array length, found {:?}", other) } + }; + + let length = stmt.expression; + let span = self.interner.expr_span(&length); + let result = self.try_eval_array_length_id(length, span); + self.unwrap_array_length_eval_result(result, span) + } + + fn unwrap_array_length_eval_result( + &mut self, + result: Result>, + span: Span, + ) -> u64 { + match result.map(|length| length.try_into()) { + Ok(Ok(length_value)) => return length_value, + Ok(Err(_cast_err)) => self.push_err(ResolverError::IntegerTooLarge { span }), Err(Some(error)) => self.push_err(error), Err(None) => (), } diff --git a/crates/noirc_frontend/src/hir/type_check/expr.rs b/crates/noirc_frontend/src/hir/type_check/expr.rs index c139cf3531b..b5ad956ed45 100644 --- a/crates/noirc_frontend/src/hir/type_check/expr.rs +++ b/crates/noirc_frontend/src/hir/type_check/expr.rs @@ -31,16 +31,13 @@ pub(crate) fn type_check_expression( HirExpression::Literal(literal) => { match literal { HirLiteral::Array(arr) => { - // Type check the contents of the array let elem_types = vecmap(&arr, |arg| type_check_expression(interner, arg, errors)); let first_elem_type = elem_types.get(0).cloned().unwrap_or(Type::Error); - // Specify the type of the Array - // Note: This assumes that the array is homogeneous, which will be checked next let arr_type = Type::Array( - Box::new(Type::ArrayLength(arr.len() as u64)), + Box::new(Type::Constant(arr.len() as u64)), Box::new(first_elem_type.clone()), ); @@ -72,7 +69,8 @@ pub(crate) fn type_check_expression( ) } HirLiteral::Str(string) => { - Type::String(Box::new(Type::ArrayLength(string.len() as u64))) + let len = Type::Constant(string.len() as u64); + Type::String(Box::new(len)) } } } @@ -783,7 +781,7 @@ pub fn comparator_operand_type_rules( x_size.unify(y_size, op.location.span, errors, || { TypeCheckError::Unstructured { - msg: format!("Can only compare arrays of the same length. Here LHS is of length {x_size}, and RHS is {y_size} "), + msg: format!("Can only compare arrays of the same length. Here LHS is of length {x_size}, and RHS is {y_size}"), span: op.location.span, } }); diff --git a/crates/noirc_frontend/src/hir_def/types.rs b/crates/noirc_frontend/src/hir_def/types.rs index a127d583ad6..2f7bdd250df 100644 --- a/crates/noirc_frontend/src/hir_def/types.rs +++ b/crates/noirc_frontend/src/hir_def/types.rs @@ -217,11 +217,22 @@ pub enum Type { /// A type-level integer. Included to let an Array's size type variable /// bind to an integer without special checks to bind it to a non-type. - ArrayLength(u64), + Constant(u64), Error, } +/// A restricted subset of binary operators useable on +/// type level integers for use in the array length positions of types. +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum BinaryTypeOperator { + Addition, + Subtraction, + Multiplication, + Division, + Modulo, +} + pub type TypeVariable = Shared; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -230,6 +241,12 @@ pub enum TypeBinding { Unbound(TypeVariableId), } +impl TypeBinding { + pub fn is_unbound(&self) -> bool { + matches!(self, TypeBinding::Unbound(_)) + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct TypeVariableId(pub usize); @@ -469,10 +486,7 @@ impl std::fmt::Display for Type { Type::FieldElement(comptime) => { write!(f, "{comptime}Field") } - Type::Array(len, typ) => match len.array_length() { - Some(len) => write!(f, "[{typ}; {len}]"), - None => write!(f, "[{typ}]"), - }, + Type::Array(len, typ) => write!(f, "[{typ}; {len}]"), Type::Integer(comptime, sign, num_bits) => match sign { Signedness::Signed => write!(f, "{comptime}i{num_bits}"), Signedness::Unsigned => write!(f, "{comptime}u{num_bits}"), @@ -500,10 +514,7 @@ impl std::fmt::Display for Type { write!(f, "({})", elements.join(", ")) } Type::Bool(comptime) => write!(f, "{comptime}bool"), - Type::String(len) => match len.array_length() { - Some(len) => write!(f, "str[{len}]"), - None => write!(f, "str[]]"), - }, + Type::String(len) => write!(f, "str<{len}>"), Type::Unit => write!(f, "()"), Type::Error => write!(f, "error"), Type::TypeVariable(id) => write!(f, "{}", id.borrow()), @@ -512,7 +523,7 @@ impl std::fmt::Display for Type { TypeBinding::Unbound(_) if name.is_empty() => write!(f, "_"), TypeBinding::Unbound(_) => write!(f, "{name}"), }, - Type::ArrayLength(n) => n.fmt(f), + Type::Constant(x) => x.fmt(f), Type::Forall(typevars, typ) => { let typevars = vecmap(typevars, |(var, _)| var.to_string()); write!(f, "forall {}. {}", typevars.join(" "), typ) @@ -525,6 +536,18 @@ impl std::fmt::Display for Type { } } +impl std::fmt::Display for BinaryTypeOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BinaryTypeOperator::Addition => write!(f, "+"), + BinaryTypeOperator::Subtraction => write!(f, "-"), + BinaryTypeOperator::Multiplication => write!(f, "*"), + BinaryTypeOperator::Division => write!(f, "/"), + BinaryTypeOperator::Modulo => write!(f, "%"), + } + } +} + impl std::fmt::Display for TypeVariableId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "_") @@ -664,7 +687,7 @@ impl Type { TypeBinding::Unbound(id) => *id, }; - if let Type::TypeVariable(binding) = self { + if let Some(binding) = self.get_inner_typevariable() { match &*binding.borrow() { TypeBinding::Bound(typ) => return typ.try_bind_to(var), // Don't recursively bind the same id to itself @@ -683,6 +706,15 @@ impl Type { } } + fn get_inner_typevariable(&self) -> Option> { + match self { + Type::PolymorphicInteger(_, var) + | Type::TypeVariable(var) + | Type::NamedGeneric(var, _) => Some(var.clone()), + _ => None, + } + } + fn is_comptime(&self) -> bool { match self { Type::FieldElement(comptime) => comptime.is_comptime(), @@ -758,7 +790,7 @@ impl Type { return link.try_unify(other, span); } - Ok(()) + other.try_bind_to(binding) } (Array(len_a, elem_a), Array(len_b, elem_b)) => { @@ -806,12 +838,10 @@ impl Type { (Bool(comptime_a), Bool(comptime_b)) => comptime_a.unify(comptime_b, span), (NamedGeneric(binding_a, name_a), NamedGeneric(binding_b, name_b)) => { - let is_unbound = |binding: &Shared| { - matches!(&*binding.borrow(), TypeBinding::Unbound(_)) - }; - // Ensure NamedGenerics are never bound during type checking - assert!(is_unbound(binding_a) && is_unbound(binding_b)); + assert!(binding_a.borrow().is_unbound()); + assert!(binding_b.borrow().is_unbound()); + if name_a == name_b { Ok(()) } else { @@ -825,7 +855,6 @@ impl Type { a.try_unify(b, span)?; } - // return types are contravariant, so this must be ret_b <: ret_a instead of the reverse ret_b.try_unify(ret_a, span) } else { Err(SpanKind::None) @@ -842,8 +871,8 @@ impl Type { } } - /// The `subtype` term here is somewhat loose, the only subtyping relations remaining are - /// between fixed and variable sized arrays, and Comptime tracking. + /// The `subtype` term here is somewhat loose, the only subtyping relations remaining + /// have to do with Comptime tracking. pub fn make_subtype_of( &self, expected: &Type, @@ -939,12 +968,10 @@ impl Type { (Bool(comptime_a), Bool(comptime_b)) => comptime_a.is_subtype_of(comptime_b, span), (NamedGeneric(binding_a, name_a), NamedGeneric(binding_b, name_b)) => { - let is_unbound = |binding: &Shared| { - matches!(&*binding.borrow(), TypeBinding::Unbound(_)) - }; - // Ensure NamedGenerics are never bound during type checking - assert!(is_unbound(binding_a) && is_unbound(binding_b)); + assert!(binding_a.borrow().is_unbound()); + assert!(binding_b.borrow().is_unbound()); + if name_a == name_b { Ok(()) } else { @@ -975,16 +1002,16 @@ impl Type { } } - pub fn array_length(&self) -> Option { + pub fn evaluate_to_u64(&self) -> Option { match self { Type::PolymorphicInteger(_, binding) | Type::NamedGeneric(binding, _) | Type::TypeVariable(binding) => match &*binding.borrow() { - TypeBinding::Bound(binding) => binding.array_length(), + TypeBinding::Bound(binding) => binding.evaluate_to_u64(), TypeBinding::Unbound(_) => None, }, - Type::Array(len, _elem) => len.array_length(), - Type::ArrayLength(size) => Some(*size), + Type::Array(len, _elem) => len.evaluate_to_u64(), + Type::Constant(x) => Some(*x), _ => None, } } @@ -995,10 +1022,10 @@ impl Type { match self { Type::FieldElement(_) => AbiType::Field, Type::Array(size, typ) => { - let size = size - .array_length() + let length = size + .evaluate_to_u64() .expect("Cannot have variable sized arrays as a parameter to main"); - AbiType::Array { length: size, typ: Box::new(typ.as_abi_type()) } + AbiType::Array { length, typ: Box::new(typ.as_abi_type()) } } Type::Integer(_, sign, bit_width) => { let sign = match sign { @@ -1015,13 +1042,13 @@ impl Type { Type::Bool(_) => AbiType::Boolean, Type::String(size) => { let size = size - .array_length() + .evaluate_to_u64() .expect("Cannot have variable sized strings as a parameter to main"); AbiType::String { length: size } } Type::Error => unreachable!(), Type::Unit => unreachable!(), - Type::ArrayLength(_) => unreachable!(), + Type::Constant(_) => unreachable!(), Type::Struct(def, args) => { let struct_type = def.borrow(); let fields = struct_type.get_fields(args); @@ -1150,7 +1177,7 @@ impl Type { Type::FieldElement(_) | Type::Integer(_, _, _) | Type::Bool(_) - | Type::ArrayLength(_) + | Type::Constant(_) | Type::Error | Type::Unit => self.clone(), } @@ -1180,7 +1207,7 @@ impl Type { Type::FieldElement(_) | Type::Integer(_, _, _) | Type::Bool(_) - | Type::ArrayLength(_) + | Type::Constant(_) | Type::Error | Type::Unit => false, } @@ -1221,9 +1248,22 @@ impl Type { // Expect that this function should only be called on instantiated types Forall(..) => unreachable!(), - FieldElement(_) | Integer(_, _, _) | Bool(_) | ArrayLength(_) | Unit | Error => { + FieldElement(_) | Integer(_, _, _) | Bool(_) | Constant(_) | Unit | Error => { self.clone() } } } } + +impl BinaryTypeOperator { + /// Return the actual rust numeric function associated with this operator + pub fn function(self) -> fn(u64, u64) -> u64 { + match self { + BinaryTypeOperator::Addition => |a, b| a.wrapping_add(b), + BinaryTypeOperator::Subtraction => |a, b| a.wrapping_sub(b), + BinaryTypeOperator::Multiplication => |a, b| a.wrapping_mul(b), + BinaryTypeOperator::Division => |a, b| a.wrapping_div(b), + BinaryTypeOperator::Modulo => |a, b| a.wrapping_rem(b), // % b, + } + } +} diff --git a/crates/noirc_frontend/src/monomorphisation/mod.rs b/crates/noirc_frontend/src/monomorphisation/mod.rs index 72a4ea83495..2f640866884 100644 --- a/crates/noirc_frontend/src/monomorphisation/mod.rs +++ b/crates/noirc_frontend/src/monomorphisation/mod.rs @@ -504,14 +504,11 @@ impl Monomorphiser { HirType::FieldElement(_) => ast::Type::Field, HirType::Integer(_, sign, bits) => ast::Type::Integer(*sign, *bits), HirType::Bool(_) => ast::Type::Bool, - HirType::String(size) => { - let size = size.array_length().unwrap_or(0); - ast::Type::String(size) - } + HirType::String(size) => ast::Type::String(size.evaluate_to_u64().unwrap_or(0)), HirType::Unit => ast::Type::Unit, HirType::Array(size, element) => { - let size = size.array_length().unwrap_or(0); + let size = size.evaluate_to_u64().unwrap_or(0); let element = Self::convert_type(element.as_ref()); ast::Type::Array(size, Box::new(element)) } @@ -552,7 +549,7 @@ impl Monomorphiser { ast::Type::Function(args, ret) } - HirType::Forall(_, _) | HirType::ArrayLength(_) | HirType::Error => { + HirType::Forall(_, _) | HirType::Constant(_) | HirType::Error => { unreachable!("Unexpected type {} found", typ) } } @@ -592,7 +589,7 @@ impl Monomorphiser { ast::Expression::Ident(ident) => match &ident.definition { Definition::Builtin(opcode) if opcode == "arraylen" => { let typ = self.interner.id_type(arguments[0]); - let len = typ.array_length().unwrap(); + let len = typ.evaluate_to_u64().unwrap(); Some(ast::Expression::Literal(ast::Literal::Integer( (len as u128).into(), ast::Type::Field, diff --git a/crates/noirc_frontend/src/parser/mod.rs b/crates/noirc_frontend/src/parser/mod.rs index c8c66114dac..7b57018d533 100644 --- a/crates/noirc_frontend/src/parser/mod.rs +++ b/crates/noirc_frontend/src/parser/mod.rs @@ -292,6 +292,7 @@ impl Precedence { Some(precedence) } + /// Return the next higher precedence. E.g. `Sum.next() == Product` fn next(self) -> Self { use Precedence::*; match self { @@ -307,7 +308,7 @@ impl Precedence { } } - /// Type expressions only contain basic arithmetic operators and + /// TypeExpressions only contain basic arithmetic operators and /// notably exclude `>` due to parsing conflicts with generic type brackets. fn next_type_precedence(self) -> Self { use Precedence::*; diff --git a/crates/noirc_frontend/src/parser/parser.rs b/crates/noirc_frontend/src/parser/parser.rs index 9b02fb58ecf..22e0a352d83 100644 --- a/crates/noirc_frontend/src/parser/parser.rs +++ b/crates/noirc_frontend/src/parser/parser.rs @@ -10,7 +10,7 @@ use crate::token::{Attribute, Keyword, Token, TokenKind}; use crate::{ BinaryOp, BinaryOpKind, BlockExpression, Comptime, ConstrainStatement, FunctionDefinition, Ident, IfExpression, ImportStatement, InfixExpression, LValue, Lambda, NoirFunction, NoirImpl, - NoirStruct, Path, PathKind, Pattern, Recoverable, UnaryOp, + NoirStruct, Path, PathKind, Pattern, Recoverable, UnaryOp, UnresolvedTypeExpression, }; use chumsky::prelude::*; @@ -95,7 +95,7 @@ fn function_definition(allow_self: bool) -> impl NoirParser { .then_ignore(keyword(Keyword::Fn)) .then(ident()) .then(generics()) - .then(parenthesized(function_parameters(allow_self, expression()))) + .then(parenthesized(function_parameters(allow_self))) .then(function_return_type()) .then(block(expression())) .map( @@ -132,14 +132,14 @@ fn struct_definition() -> impl NoirParser { use self::Keyword::Struct; use Token::*; - let fields = struct_fields(expression()) - .delimited_by(just(LeftBrace), just(RightBrace)) - .recover_with(nested_delimiters( + let fields = struct_fields().delimited_by(just(LeftBrace), just(RightBrace)).recover_with( + nested_delimiters( LeftBrace, RightBrace, [(LeftParen, RightParen), (LeftBracket, RightBracket)], |_| vec![], - )); + ), + ); keyword(Struct).ignore_then(ident()).then(generics()).then(fields).map_with_span( |((name, generics), fields), span| { @@ -148,19 +148,17 @@ fn struct_definition() -> impl NoirParser { ) } -fn lambda_return_type<'a>( - expr_parser: impl NoirParser + 'a, -) -> impl NoirParser + 'a { +fn lambda_return_type() -> impl NoirParser { just(Token::Arrow) - .ignore_then(parse_type(expr_parser)) + .ignore_then(parse_type()) .or_not() .map(|ret| ret.unwrap_or(UnresolvedType::Unspecified)) } -fn function_return_type<'a>() -> impl NoirParser<(AbiVisibility, UnresolvedType)> + 'a { +fn function_return_type() -> impl NoirParser<(AbiVisibility, UnresolvedType)> { just(Token::Arrow) .ignore_then(optional_visibility()) - .then(parse_type(expression())) + .then(parse_type()) .or_not() .map(|ret| ret.unwrap_or((AbiVisibility::Private, UnresolvedType::Unit))) } @@ -172,20 +170,16 @@ fn attribute() -> impl NoirParser { }) } -fn struct_fields<'a>( - expr_parser: impl NoirParser + 'a, -) -> impl NoirParser> + 'a { +fn struct_fields() -> impl NoirParser> { ident() .then_ignore(just(Token::Colon)) - .then(parse_type(expr_parser)) + .then(parse_type()) .separated_by(just(Token::Comma)) .allow_trailing() } -fn lambda_parameters<'a>( - expr_parser: impl NoirParser + 'a, -) -> impl NoirParser> + 'a { - let typ = parse_type(expr_parser).recover_via(parameter_recovery()); +fn lambda_parameters() -> impl NoirParser> { + let typ = parse_type().recover_via(parameter_recovery()); let typ = just(Token::Colon).ignore_then(typ); let parameter = pattern() @@ -197,9 +191,8 @@ fn lambda_parameters<'a>( fn function_parameters<'a>( allow_self: bool, - expr_parser: impl NoirParser + 'a, ) -> impl NoirParser> + 'a { - let typ = parse_type(expr_parser).recover_via(parameter_recovery()); + let typ = parse_type().recover_via(parameter_recovery()); let full_parameter = pattern() .recover_via(parameter_name_recovery()) @@ -282,7 +275,7 @@ fn check_statements_require_semicolon( /// Parse an optional ': type' and implicitly add a 'comptime' to the type fn global_type_annotation() -> impl NoirParser { - ignore_then_commit(just(Token::Colon), parse_type(expression())) + ignore_then_commit(just(Token::Colon), parse_type()) .map(|r#type| match r#type { UnresolvedType::FieldElement(_) => UnresolvedType::FieldElement(Comptime::Yes(None)), UnresolvedType::Bool(_) => UnresolvedType::Bool(Comptime::Yes(None)), @@ -295,10 +288,8 @@ fn global_type_annotation() -> impl NoirParser { .map(|opt| opt.unwrap_or(UnresolvedType::Unspecified)) } -fn optional_type_annotation<'a>( - expr_parser: impl NoirParser + 'a, -) -> impl NoirParser + 'a { - ignore_then_commit(just(Token::Colon), parse_type(expr_parser)) +fn optional_type_annotation<'a>() -> impl NoirParser + 'a { + ignore_then_commit(just(Token::Colon), parse_type()) .or_not() .map(|r#type| r#type.unwrap_or(UnresolvedType::Unspecified)) } @@ -373,7 +364,7 @@ where P: ExprParser + 'a, { let p = ignore_then_commit(keyword(Keyword::Let).labelled("statement"), pattern()); - let p = p.then(optional_type_annotation(expr_parser.clone())); + let p = p.then(optional_type_annotation()); let p = then_commit_ignore(p, just(Token::Assign)); let p = then_commit(p, expr_parser); p.map(Statement::new_let) @@ -453,26 +444,18 @@ where }) } -fn parse_type<'a, P>(expr_parser: P) -> impl NoirParser + 'a -where - P: NoirParser + 'a, -{ - recursive(move |typ| parse_type_inner(typ, expr_parser)) +fn parse_type<'a>() -> impl NoirParser + 'a { + recursive(parse_type_inner) } -fn parse_type_inner( - recursive_type_parser: T, - expr_parser: P, -) -> impl NoirParser -where - T: NoirParser, - P: NoirParser, -{ +fn parse_type_inner( + recursive_type_parser: impl NoirParser, +) -> impl NoirParser { choice(( field_type(), int_type(), named_type(recursive_type_parser.clone()), - array_type(recursive_type_parser.clone(), expr_parser), + array_type(recursive_type_parser.clone()), tuple_type(recursive_type_parser.clone()), bool_type(), string_type(), @@ -531,6 +514,12 @@ fn generic_type_args( type_parser: impl NoirParser, ) -> impl NoirParser> { type_parser + // Without checking for a terminating ',' or '>' here we may incorrectly + // parse a generic `N * 2` as just the type `N` then fail when there is no + // separator afterward. Failing early here ensures we try the `type_expression` + // parser afterward. + .then_ignore(one_of([Token::Comma, Token::Greater]).rewind()) + .or(type_expression().map(UnresolvedType::Expression)) .separated_by(just(Token::Comma)) .allow_trailing() .at_least(1) @@ -539,23 +528,20 @@ fn generic_type_args( .map(Option::unwrap_or_default) } -fn type_expression() -> impl NoirParser { - recursive(|expr| expression_with_precedence(Precedence::lowest_type_precedence(), expr, true)) - .labelled("type expression") -} - -fn array_type(type_parser: T, expr_parser: P) -> impl NoirParser -where - T: NoirParser, - P: NoirParser, -{ +fn array_type(type_parser: impl NoirParser) -> impl NoirParser { just(Token::LeftBracket) .ignore_then(type_parser) - .then(just(Token::Semicolon).ignore_then(expr_parser).or_not()) + .then(just(Token::Semicolon).ignore_then(type_expression()).or_not()) .then_ignore(just(Token::RightBracket)) .map(|(element_type, size)| UnresolvedType::Array(size, Box::new(element_type))) } +fn type_expression() -> impl NoirParser { + recursive(|expr| expression_with_precedence(Precedence::lowest_type_precedence(), expr, true)) + .labelled("type expression") + .try_map(UnresolvedTypeExpression::from_expr) +} + fn tuple_type(type_parser: T) -> impl NoirParser where T: NoirParser, @@ -680,10 +666,8 @@ where .map(UnaryRhs::ArrayIndex); // `as Type` in `atom as Type` - let cast_rhs = keyword(Keyword::As) - .ignore_then(parse_type(expr_parser.clone())) - .map(UnaryRhs::Cast) - .labelled("cast"); + let cast_rhs = + keyword(Keyword::As).ignore_then(parse_type()).map(UnaryRhs::Cast).labelled("cast"); // `.foo` or `.foo(args)` in `atom.foo` or `atom.foo(args)` let member_rhs = just(Token::Dot) @@ -731,9 +715,9 @@ where fn lambda<'a>( expr_parser: impl NoirParser + 'a, ) -> impl NoirParser + 'a { - lambda_parameters(expr_parser.clone()) + lambda_parameters() .delimited_by(just(Token::Pipe), just(Token::Pipe)) - .then(lambda_return_type(expr_parser.clone())) + .then(lambda_return_type()) .then(expr_parser) .map(|((parameters, return_type), body)| { ExpressionKind::Lambda(Box::new(Lambda { parameters, return_type, body })) diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 5a90df2069c..40e9ef4511e 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -27,110 +27,111 @@ fn mimc(x: Field, k: Field, constants: [Field], exp : Field) -> Field { h + k } +global MIMC_BN254_ROUNDS = 91; //mimc implementation with hardcoded parameters for BN254 curve. fn mimc_bn254(x: [Field]) -> Field { //mimc parameters - let ROUNDS: Field = 91; let exponent = 7; //generated from seed "mimc" using keccak256 - let constants :[Field; ROUNDS] = [0, - 20888961410941983456478427210666206549300505294776164667214940546594746570981, -15265126113435022738560151911929040668591755459209400716467504685752745317193, -8334177627492981984476504167502758309043212251641796197711684499645635709656, -1374324219480165500871639364801692115397519265181803854177629327624133579404, -11442588683664344394633565859260176446561886575962616332903193988751292992472, -2558901189096558760448896669327086721003508630712968559048179091037845349145, -11189978595292752354820141775598510151189959177917284797737745690127318076389, -3262966573163560839685415914157855077211340576201936620532175028036746741754, -17029914891543225301403832095880481731551830725367286980611178737703889171730, -4614037031668406927330683909387957156531244689520944789503628527855167665518, -19647356996769918391113967168615123299113119185942498194367262335168397100658, -5040699236106090655289931820723926657076483236860546282406111821875672148900, -2632385916954580941368956176626336146806721642583847728103570779270161510514, -17691411851977575435597871505860208507285462834710151833948561098560743654671, -11482807709115676646560379017491661435505951727793345550942389701970904563183, -8360838254132998143349158726141014535383109403565779450210746881879715734773, -12663821244032248511491386323242575231591777785787269938928497649288048289525, -3067001377342968891237590775929219083706800062321980129409398033259904188058, -8536471869378957766675292398190944925664113548202769136103887479787957959589, -19825444354178182240559170937204690272111734703605805530888940813160705385792, -16703465144013840124940690347975638755097486902749048533167980887413919317592, -13061236261277650370863439564453267964462486225679643020432589226741411380501, -10864774797625152707517901967943775867717907803542223029967000416969007792571, -10035653564014594269791753415727486340557376923045841607746250017541686319774, -3446968588058668564420958894889124905706353937375068998436129414772610003289, -4653317306466493184743870159523234588955994456998076243468148492375236846006, -8486711143589723036499933521576871883500223198263343024003617825616410932026, -250710584458582618659378487568129931785810765264752039738223488321597070280, -2104159799604932521291371026105311735948154964200596636974609406977292675173, -16313562605837709339799839901240652934758303521543693857533755376563489378839, -6032365105133504724925793806318578936233045029919447519826248813478479197288, -14025118133847866722315446277964222215118620050302054655768867040006542798474, -7400123822125662712777833064081316757896757785777291653271747396958201309118, -1744432620323851751204287974553233986555641872755053103823939564833813704825, -8316378125659383262515151597439205374263247719876250938893842106722210729522, -6739722627047123650704294650168547689199576889424317598327664349670094847386, -21211457866117465531949733809706514799713333930924902519246949506964470524162, -13718112532745211817410303291774369209520657938741992779396229864894885156527, -5264534817993325015357427094323255342713527811596856940387954546330728068658, -18884137497114307927425084003812022333609937761793387700010402412840002189451, -5148596049900083984813839872929010525572543381981952060869301611018636120248, -19799686398774806587970184652860783461860993790013219899147141137827718662674, -19240878651604412704364448729659032944342952609050243268894572835672205984837, -10546185249390392695582524554167530669949955276893453512788278945742408153192, -5507959600969845538113649209272736011390582494851145043668969080335346810411, -18177751737739153338153217698774510185696788019377850245260475034576050820091, -19603444733183990109492724100282114612026332366576932662794133334264283907557, -10548274686824425401349248282213580046351514091431715597441736281987273193140, -1823201861560942974198127384034483127920205835821334101215923769688644479957, -11867589662193422187545516240823411225342068709600734253659804646934346124945, -18718569356736340558616379408444812528964066420519677106145092918482774343613, -10530777752259630125564678480897857853807637120039176813174150229243735996839, -20486583726592018813337145844457018474256372770211860618687961310422228379031, -12690713110714036569415168795200156516217175005650145422920562694422306200486, -17386427286863519095301372413760745749282643730629659997153085139065756667205, -2216432659854733047132347621569505613620980842043977268828076165669557467682, -6309765381643925252238633914530877025934201680691496500372265330505506717193, -20806323192073945401862788605803131761175139076694468214027227878952047793390, -4037040458505567977365391535756875199663510397600316887746139396052445718861, -19948974083684238245321361840704327952464170097132407924861169241740046562673, -845322671528508199439318170916419179535949348988022948153107378280175750024, -16222384601744433420585982239113457177459602187868460608565289920306145389382, -10232118865851112229330353999139005145127746617219324244541194256766741433339, -6699067738555349409504843460654299019000594109597429103342076743347235369120, -6220784880752427143725783746407285094967584864656399181815603544365010379208, -6129250029437675212264306655559561251995722990149771051304736001195288083309, -10773245783118750721454994239248013870822765715268323522295722350908043393604, -4490242021765793917495398271905043433053432245571325177153467194570741607167, -19596995117319480189066041930051006586888908165330319666010398892494684778526, -837850695495734270707668553360118467905109360511302468085569220634750561083, -11803922811376367215191737026157445294481406304781326649717082177394185903907, -10201298324909697255105265958780781450978049256931478989759448189112393506592, -13564695482314888817576351063608519127702411536552857463682060761575100923924, -9262808208636973454201420823766139682381973240743541030659775288508921362724, -173271062536305557219323722062711383294158572562695717740068656098441040230, -18120430890549410286417591505529104700901943324772175772035648111937818237369, -20484495168135072493552514219686101965206843697794133766912991150184337935627, -19155651295705203459475805213866664350848604323501251939850063308319753686505, -11971299749478202793661982361798418342615500543489781306376058267926437157297, -18285310723116790056148596536349375622245669010373674803854111592441823052978, -7069216248902547653615508023941692395371990416048967468982099270925308100727, -6465151453746412132599596984628739550147379072443683076388208843341824127379, -16143532858389170960690347742477978826830511669766530042104134302796355145785, -19362583304414853660976404410208489566967618125972377176980367224623492419647, -1702213613534733786921602839210290505213503664731919006932367875629005980493, -10781825404476535814285389902565833897646945212027592373510689209734812292327, -4212716923652881254737947578600828255798948993302968210248673545442808456151, -7594017890037021425366623750593200398174488805473151513558919864633711506220, -18979889247746272055963929241596362599320706910852082477600815822482192194401, -13602139229813231349386885113156901793661719180900395818909719758150455500533,]; + let constants: [Field; MIMC_BN254_ROUNDS] = [ + 0, + 20888961410941983456478427210666206549300505294776164667214940546594746570981, + 15265126113435022738560151911929040668591755459209400716467504685752745317193, + 8334177627492981984476504167502758309043212251641796197711684499645635709656, + 1374324219480165500871639364801692115397519265181803854177629327624133579404, + 11442588683664344394633565859260176446561886575962616332903193988751292992472, + 2558901189096558760448896669327086721003508630712968559048179091037845349145, + 11189978595292752354820141775598510151189959177917284797737745690127318076389, + 3262966573163560839685415914157855077211340576201936620532175028036746741754, + 17029914891543225301403832095880481731551830725367286980611178737703889171730, + 4614037031668406927330683909387957156531244689520944789503628527855167665518, + 19647356996769918391113967168615123299113119185942498194367262335168397100658, + 5040699236106090655289931820723926657076483236860546282406111821875672148900, + 2632385916954580941368956176626336146806721642583847728103570779270161510514, + 17691411851977575435597871505860208507285462834710151833948561098560743654671, + 11482807709115676646560379017491661435505951727793345550942389701970904563183, + 8360838254132998143349158726141014535383109403565779450210746881879715734773, + 12663821244032248511491386323242575231591777785787269938928497649288048289525, + 3067001377342968891237590775929219083706800062321980129409398033259904188058, + 8536471869378957766675292398190944925664113548202769136103887479787957959589, + 19825444354178182240559170937204690272111734703605805530888940813160705385792, + 16703465144013840124940690347975638755097486902749048533167980887413919317592, + 13061236261277650370863439564453267964462486225679643020432589226741411380501, + 10864774797625152707517901967943775867717907803542223029967000416969007792571, + 10035653564014594269791753415727486340557376923045841607746250017541686319774, + 3446968588058668564420958894889124905706353937375068998436129414772610003289, + 4653317306466493184743870159523234588955994456998076243468148492375236846006, + 8486711143589723036499933521576871883500223198263343024003617825616410932026, + 250710584458582618659378487568129931785810765264752039738223488321597070280, + 2104159799604932521291371026105311735948154964200596636974609406977292675173, + 16313562605837709339799839901240652934758303521543693857533755376563489378839, + 6032365105133504724925793806318578936233045029919447519826248813478479197288, + 14025118133847866722315446277964222215118620050302054655768867040006542798474, + 7400123822125662712777833064081316757896757785777291653271747396958201309118, + 1744432620323851751204287974553233986555641872755053103823939564833813704825, + 8316378125659383262515151597439205374263247719876250938893842106722210729522, + 6739722627047123650704294650168547689199576889424317598327664349670094847386, + 21211457866117465531949733809706514799713333930924902519246949506964470524162, + 13718112532745211817410303291774369209520657938741992779396229864894885156527, + 5264534817993325015357427094323255342713527811596856940387954546330728068658, + 18884137497114307927425084003812022333609937761793387700010402412840002189451, + 5148596049900083984813839872929010525572543381981952060869301611018636120248, + 19799686398774806587970184652860783461860993790013219899147141137827718662674, + 19240878651604412704364448729659032944342952609050243268894572835672205984837, + 10546185249390392695582524554167530669949955276893453512788278945742408153192, + 5507959600969845538113649209272736011390582494851145043668969080335346810411, + 18177751737739153338153217698774510185696788019377850245260475034576050820091, + 19603444733183990109492724100282114612026332366576932662794133334264283907557, + 10548274686824425401349248282213580046351514091431715597441736281987273193140, + 1823201861560942974198127384034483127920205835821334101215923769688644479957, + 11867589662193422187545516240823411225342068709600734253659804646934346124945, + 18718569356736340558616379408444812528964066420519677106145092918482774343613, + 10530777752259630125564678480897857853807637120039176813174150229243735996839, + 20486583726592018813337145844457018474256372770211860618687961310422228379031, + 12690713110714036569415168795200156516217175005650145422920562694422306200486, + 17386427286863519095301372413760745749282643730629659997153085139065756667205, + 2216432659854733047132347621569505613620980842043977268828076165669557467682, + 6309765381643925252238633914530877025934201680691496500372265330505506717193, + 20806323192073945401862788605803131761175139076694468214027227878952047793390, + 4037040458505567977365391535756875199663510397600316887746139396052445718861, + 19948974083684238245321361840704327952464170097132407924861169241740046562673, + 845322671528508199439318170916419179535949348988022948153107378280175750024, + 16222384601744433420585982239113457177459602187868460608565289920306145389382, + 10232118865851112229330353999139005145127746617219324244541194256766741433339, + 6699067738555349409504843460654299019000594109597429103342076743347235369120, + 6220784880752427143725783746407285094967584864656399181815603544365010379208, + 6129250029437675212264306655559561251995722990149771051304736001195288083309, + 10773245783118750721454994239248013870822765715268323522295722350908043393604, + 4490242021765793917495398271905043433053432245571325177153467194570741607167, + 19596995117319480189066041930051006586888908165330319666010398892494684778526, + 837850695495734270707668553360118467905109360511302468085569220634750561083, + 11803922811376367215191737026157445294481406304781326649717082177394185903907, + 10201298324909697255105265958780781450978049256931478989759448189112393506592, + 13564695482314888817576351063608519127702411536552857463682060761575100923924, + 9262808208636973454201420823766139682381973240743541030659775288508921362724, + 173271062536305557219323722062711383294158572562695717740068656098441040230, + 18120430890549410286417591505529104700901943324772175772035648111937818237369, + 20484495168135072493552514219686101965206843697794133766912991150184337935627, + 19155651295705203459475805213866664350848604323501251939850063308319753686505, + 11971299749478202793661982361798418342615500543489781306376058267926437157297, + 18285310723116790056148596536349375622245669010373674803854111592441823052978, + 7069216248902547653615508023941692395371990416048967468982099270925308100727, + 6465151453746412132599596984628739550147379072443683076388208843341824127379, + 16143532858389170960690347742477978826830511669766530042104134302796355145785, + 19362583304414853660976404410208489566967618125972377176980367224623492419647, + 1702213613534733786921602839210290505213503664731919006932367875629005980493, + 10781825404476535814285389902565833897646945212027592373510689209734812292327, + 4212716923652881254737947578600828255798948993302968210248673545442808456151, + 7594017890037021425366623750593200398174488805473151513558919864633711506220, + 18979889247746272055963929241596362599320706910852082477600815822482192194401, + 13602139229813231349386885113156901793661719180900395818909719758150455500533, + ]; let mut r = 0; - for i in 0..crate::array::len(x) { + for i in 0 .. crate::array::len(x) { let h = mimc(x[i], r, constants, exponent); - r = r + x[i] +h; + r = r + x[i] + h; }; - r - -} \ No newline at end of file + r +}