diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/Nargo.toml new file mode 100644 index 00000000000..670888e37cd --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/Nargo.toml @@ -0,0 +1,5 @@ +[package] +authors = [""] +compiler_version = "0.6.0" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/Prover.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/Prover.toml new file mode 100644 index 00000000000..1a59cd124a7 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/Prover.toml @@ -0,0 +1 @@ +values = [1,2,3,4,5,6] \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/src/main.nr new file mode 100644 index 00000000000..46c4ebe938e --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/src/main.nr @@ -0,0 +1,26 @@ +struct Header { + params: [Field; 3], +} + +struct MyNote { + plain: Field, + array: [Field; 2], + header: Header, +} + +fn access_nested(notes: [MyNote; 2]) -> Field { + notes[0].array[1] + notes[1].array[0] + notes[0].plain + notes[1].header.params[0] +} + +unconstrained fn create_inside_brillig(values: [Field; 6]) -> [MyNote; 2] { + let header = Header { params: [values[0], values[1], values[2]]}; + let note0 = MyNote { array: [values[0], values[1]], plain : values[2], header }; + let note1 = MyNote { array: [values[3], values[4]], plain : values[5], header }; + [note0, note1] +} + +fn main(values: [Field; 6]) { + let notes = create_inside_brillig(values); + assert(access_nested(notes) == (2 + 4 + 3 + 1)); +} + diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/target/main.json b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/target/main.json new file mode 100644 index 00000000000..5fa561b3ef8 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/target/main.json @@ -0,0 +1 @@ +{"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"values","type":{"kind":"array","length":6,"type":{"kind":"field"}},"visibility":"private"}],"param_witnesses":{"values":[1,2,3,4,5,6]},"return_type":null,"return_witnesses":[]},"bytecode":"H4sIAAAAAAAA/92a21LiQBCGh1MiBCOCGE6+Q44Q7niVdRcv9pn3YTYzpsufqSGidrtkp2oqCRO6vz5mjKyUUkP1Om7qo1cfO9XsVrNXzX41B/WaV6/RPXS/gs/0ONTH+Gsj6fDJiqUYuy1g7LWAsd8CxkELGD1GRqz1cX3uq9d+oXvHqJpBvXZbzbCad9WcVPO+mlP1Nv7UR/29rjod2EcOPOxbj9+3sY7/b2Ae8Mr/qX3Tt3zTsa4PcD4AFp/ZVi3zhlmmUm/PHD0oD4h9pN5yAe/Dc/IPsQWw7sGRmT0R8HFCNtv+uAF/DOGcfDGyfNGx5Bzg2gefjGGdgd/kyC2zTC0jBFvI/jH4IajP8T48J9uJLYD1APzBzJ4I+Dg554/bT/hj/I4/mPM7FajDDH2gh6uHYK3Qkc6xZlDOQbn3w22sGTvel+SInVf/U83Y/eAj/nivZpjZUwEfp+f8IZEf3PUu0Je2aI8erufupfsQH3zg2ocws+cCPt6RzbY/sKd+dR+CPZW7/0n0aS3ju5673P1Pok+f84fEvow5vwuBOtyjD/Rw9ZCv7kNw797GmmnRc/dbaqZF+7JUYm9zzh/c+YHvmPrW9xSshbXv+rx2mjoYOPT1wc5efY7vcDxeDpN/voPDAw7Sj72Guf+m5/yPvZL04x5KIi6ufQ7Gxd7nSMUlcHBgXEi/4HPRxGXs4MC4kP4xcDD3GvM3fejgwL5A+kPguOPlyLWMiYPjDjhI/wQ47nk5Ci1j6uC4Bw7SPwWOGS/Hdmhx6NH0PnoGLA+8LKZ256CLuEhPAOtYM3NeDvM/yQfLfrqeg95HXr3pUJ3ar0dTLB6BJeJlMbFYgC7iisD/tI79fMHLYWIRWfbTNfJdyjq6Ala8x5XjkWWHQHwbczyS81E2VKf269GU4wtgWfKymBxfgS7iIj0BrPeAY8XLYWKxtOyna+S7lHXQIlb/CljxHlc9Li07BHKxsR6Xn2Cd/GNWgXia5yPar0dT71gBy5qXxfSODegiLtITwDruqze8HCYWa8t+uka+S1nDK2DFe1w5vrbsEIhvY46v5fR++PmILMzxMjn+BLqIi/QEsI7PxydeDhOLjWU/XSPfpayDFrH6V8CK97jqcWPZIdU7ztUj6RrCZ1P4rGsxa5/aNcX64odGj1n2BGRl8TbPj7v0mGTJjzjdP5dFnBfP2zIpk6IsfqVllh3LvNztn/e7eJ/k2TF5KfbZSy1sxigrUrxNR8p/PqOsIaOsBUMsji9m7CT9FzLKihjzb8HHFeOPSnFw/4h3xsiMvNgk6aV315ETnoBNytJj+zFUwo1XIkgPAnLnii/5peye88fopLlfu09x/AWj8PM1SjMAAA==","proving_key":null,"verification_key":null} \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/target/witness.tr b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/target/witness.tr new file mode 100644 index 00000000000..a602afdf521 Binary files /dev/null and b/crates/nargo_cli/tests/test_data_ssa_refactor/nested_arrays_from_brillig/target/witness.tr differ 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 ed45f7cda51..2fdfb0bd10f 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 @@ -855,18 +855,9 @@ impl AcirContext { AcirValue::Var(var, output.clone()) } AcirType::Array(element_types, size) => { - let mut witnesses = Vec::new(); - let mut array_values = im::Vector::new(); - for _ in 0..size { - for element_type in &element_types { - let witness_index = self.acir_ir.next_witness_index(); - witnesses.push(witness_index); - let var = self.add_data(AcirVarData::Witness(witness_index)); - array_values.push_back(AcirValue::Var(var, element_type.clone())); - } - } + let (acir_value, witnesses) = self.brillig_array_output(&element_types, size); b_outputs.push(BrilligOutputs::Array(witnesses)); - AcirValue::Array(array_values) + acir_value } }); let predicate = self.vars[&predicate].to_expression().into_owned(); @@ -906,6 +897,36 @@ impl AcirContext { } } + /// Recursively create acir values for returned arrays. This is necessary because a brillig returned array can have nested arrays as elements. + /// A singular array of witnesses is collected for a top level array, by deflattening the assigned witnesses at each level. + fn brillig_array_output( + &mut self, + element_types: &[AcirType], + size: usize, + ) -> (AcirValue, Vec) { + let mut witnesses = Vec::new(); + let mut array_values = im::Vector::new(); + for _ in 0..size { + for element_type in element_types { + match element_type { + AcirType::Array(nested_element_types, nested_size) => { + let (nested_acir_value, mut nested_witnesses) = + self.brillig_array_output(nested_element_types, *nested_size); + witnesses.append(&mut nested_witnesses); + array_values.push_back(nested_acir_value); + } + AcirType::NumericType(_) => { + let witness_index = self.acir_ir.next_witness_index(); + witnesses.push(witness_index); + let var = self.add_data(AcirVarData::Witness(witness_index)); + array_values.push_back(AcirValue::Var(var, element_type.clone())); + } + } + } + } + (AcirValue::Array(array_values), witnesses) + } + /// Generate output variables that are constrained to be the sorted inputs /// The outputs are the sorted inputs iff /// outputs are sorted and