diff --git a/crates/nargo_cli/tests/test_data/array_len/Prover.toml b/crates/nargo_cli/tests/test_data/array_len/Prover.toml index 3c3295e684..a5ffe607b7 100644 --- a/crates/nargo_cli/tests/test_data/array_len/Prover.toml +++ b/crates/nargo_cli/tests/test_data/array_len/Prover.toml @@ -1,2 +1,3 @@ len3 = [1, 2, 3] len4 = [1, 2, 3, 4] +x = 123 diff --git a/crates/nargo_cli/tests/test_data/array_len/src/main.nr b/crates/nargo_cli/tests/test_data/array_len/src/main.nr index 2c3cc0aee6..65c2295cef 100644 --- a/crates/nargo_cli/tests/test_data/array_len/src/main.nr +++ b/crates/nargo_cli/tests/test_data/array_len/src/main.nr @@ -12,7 +12,7 @@ fn nested_call(b: [Field; N]) -> Field { len_plus_1(b) } -fn main(len3: [u8; 3], len4: [Field; 4]) { +fn main(x: Field, len3: [u8; 3], len4: [Field; 4]) { assert(len_plus_1(len3) == 4); assert(len_plus_1(len4) == 5); assert(add_lens(len3, len4) == 7); @@ -20,4 +20,9 @@ fn main(len3: [u8; 3], len4: [Field; 4]) { // std::array::len returns a comptime value assert(len4[len3.len()] == 4); + + // Regression for #1023, ensure .len still works after calling to_le_bytes on a witness. + // This was needed because normally .len is evaluated before acir-gen where to_le_bytes + // on a witness is only evaluated during/after acir-gen. + assert(x.to_le_bytes(8).len() != 0); } diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs index 6d8178b6a2..25d92ed8b8 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs @@ -55,6 +55,11 @@ impl AcirType { } } + /// Returns a field type + pub(crate) fn field() -> Self { + AcirType::NumericType(NumericType::NativeField) + } + /// Returns a boolean type fn boolean() -> Self { AcirType::NumericType(NumericType::Unsigned { bit_size: 1 }) diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs index 1fce4cd76a..da8409431c 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/mod.rs @@ -996,6 +996,14 @@ impl Context { Ok(Self::convert_vars_to_values(out_vars, dfg, result_ids)) } + Intrinsic::ArrayLen => { + let len = match self.convert_value(arguments[0], dfg) { + AcirValue::Var(_, _) => unreachable!("Non-array passed to array.len() method"), + AcirValue::Array(values) => (values.len() as u128).into(), + AcirValue::DynamicArray(array) => (array.len as u128).into(), + }; + Ok(vec![AcirValue::Var(self.acir_context.add_constant(len), AcirType::field())]) + } _ => todo!("expected a black box function"), } }