diff --git a/Cargo.lock b/Cargo.lock index b1307249df5..6700e30dec2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1421,9 +1421,9 @@ dependencies = [ [[package]] name = "gloo-utils" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +checksum = "a8e8fc851e9c7b9852508bc6e3f690f452f474417e8545ec9857b7f7377036b5" dependencies = [ "js-sys", "serde", diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/struct_array_inputs/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/struct_array_inputs/Nargo.toml new file mode 100644 index 00000000000..670888e37cd --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/struct_array_inputs/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/struct_array_inputs/Prover.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/struct_array_inputs/Prover.toml new file mode 100644 index 00000000000..c2212c1a9c9 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/struct_array_inputs/Prover.toml @@ -0,0 +1,11 @@ +[[foos]] +bar = 0 +baz = 0 + +[[foos]] +bar = 0 +baz = 0 + +[[foos]] +bar = 1 +baz = 2 diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/struct_array_inputs/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/struct_array_inputs/src/main.nr new file mode 100644 index 00000000000..de317fe35e7 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/struct_array_inputs/src/main.nr @@ -0,0 +1,8 @@ +struct Foo { + bar: Field, + baz: Field, +} + +fn main(foos: [Foo; 3]) -> pub Field { + foos[2].bar + foos[2].baz +} \ No newline at end of file diff --git a/crates/noirc_abi/src/input_parser/json.rs b/crates/noirc_abi/src/input_parser/json.rs index 22b0b49852b..748c0d09e04 100644 --- a/crates/noirc_abi/src/input_parser/json.rs +++ b/crates/noirc_abi/src/input_parser/json.rs @@ -1,7 +1,7 @@ use super::{parse_str_to_field, InputValue}; use crate::{errors::InputParserError, Abi, AbiType, MAIN_RETURN_NAME}; use acvm::FieldElement; -use iter_extended::{try_btree_map, try_vecmap, vecmap}; +use iter_extended::{try_btree_map, try_vecmap}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -71,12 +71,8 @@ enum JsonTypes { Integer(u64), // Simple boolean flag Bool(bool), - // Array of regular integers - ArrayNum(Vec), - // Array of hexadecimal integers - ArrayString(Vec), - // Array of booleans - ArrayBool(Vec), + // Array of JsonTypes + Array(Vec), // Struct of JsonTypes Table(BTreeMap), } @@ -93,17 +89,11 @@ impl JsonTypes { } (InputValue::Field(f), AbiType::Boolean) => JsonTypes::Bool(f.is_one()), - (InputValue::Vec(v), AbiType::Array { typ, .. }) => match typ.as_ref() { - AbiType::Field | AbiType::Integer { .. } => { - let array = v.iter().map(|i| format!("0x{}", i.to_hex())).collect(); - JsonTypes::ArrayString(array) - } - AbiType::Boolean => { - let array = v.iter().map(|i| i.is_one()).collect(); - JsonTypes::ArrayBool(array) - } - _ => return Err(InputParserError::AbiTypeMismatch(abi_type.clone())), - }, + (InputValue::Vec(vector), AbiType::Array { typ, .. }) => { + let array = + try_vecmap(vector, |value| JsonTypes::try_from_input_value(value, typ))?; + JsonTypes::Array(array) + } (InputValue::String(s), AbiType::String { .. }) => JsonTypes::String(s.to_string()), @@ -145,32 +135,9 @@ impl InputValue { (JsonTypes::Bool(boolean), AbiType::Boolean) => InputValue::Field(boolean.into()), - (JsonTypes::ArrayNum(arr_num), AbiType::Array { typ, .. }) - if matches!( - typ.as_ref(), - AbiType::Field | AbiType::Integer { .. } | AbiType::Boolean - ) => - { + (JsonTypes::Array(array), AbiType::Array { typ, .. }) => { let array_elements = - vecmap(arr_num, |elem_num| FieldElement::from(i128::from(elem_num))); - - InputValue::Vec(array_elements) - } - (JsonTypes::ArrayString(arr_str), AbiType::Array { typ, .. }) - if matches!( - typ.as_ref(), - AbiType::Field | AbiType::Integer { .. } | AbiType::Boolean - ) => - { - let array_elements = try_vecmap(arr_str, |elem_str| parse_str_to_field(&elem_str))?; - - InputValue::Vec(array_elements) - } - (JsonTypes::ArrayBool(arr_bool), AbiType::Array { typ, .. }) - if matches!(typ.as_ref(), AbiType::Boolean) => - { - let array_elements = vecmap(arr_bool, FieldElement::from); - + try_vecmap(array, |value| InputValue::try_from_json(value, typ, arg_name))?; InputValue::Vec(array_elements) } diff --git a/crates/noirc_abi/src/input_parser/mod.rs b/crates/noirc_abi/src/input_parser/mod.rs index 2c90aac862c..da9d777d0ab 100644 --- a/crates/noirc_abi/src/input_parser/mod.rs +++ b/crates/noirc_abi/src/input_parser/mod.rs @@ -14,8 +14,8 @@ use crate::{Abi, AbiType}; #[derive(Debug, Clone, Serialize, PartialEq)] pub enum InputValue { Field(FieldElement), - Vec(Vec), String(String), + Vec(Vec), Struct(BTreeMap), } @@ -32,14 +32,12 @@ impl InputValue { field_element.is_one() || field_element.is_zero() } - (InputValue::Vec(field_elements), AbiType::Array { length, typ, .. }) => { - if field_elements.len() != *length as usize { + (InputValue::Vec(array_elements), AbiType::Array { length, typ, .. }) => { + if array_elements.len() != *length as usize { return false; } // Check that all of the array's elements' values match the ABI as well. - field_elements - .iter() - .all(|field_element| Self::Field(*field_element).matches_abi(typ)) + array_elements.iter().all(|input_value| input_value.matches_abi(typ)) } (InputValue::String(string), AbiType::String { length }) => { @@ -164,7 +162,13 @@ mod serialization_tests { "bar".into(), InputValue::Struct(BTreeMap::from([ ("field1".into(), InputValue::Field(255u128.into())), - ("field2".into(), InputValue::Vec(vec![true.into(), false.into()])), + ( + "field2".into(), + InputValue::Vec(vec![ + InputValue::Field(true.into()), + InputValue::Field(false.into()), + ]), + ), ])), ), (MAIN_RETURN_NAME.into(), InputValue::String("hello".to_owned())), diff --git a/crates/noirc_abi/src/input_parser/toml.rs b/crates/noirc_abi/src/input_parser/toml.rs index 316f52a4048..d96496410d9 100644 --- a/crates/noirc_abi/src/input_parser/toml.rs +++ b/crates/noirc_abi/src/input_parser/toml.rs @@ -1,7 +1,7 @@ use super::{parse_str_to_field, InputValue}; use crate::{errors::InputParserError, Abi, AbiType, MAIN_RETURN_NAME}; use acvm::FieldElement; -use iter_extended::{try_btree_map, try_vecmap, vecmap}; +use iter_extended::{try_btree_map, try_vecmap}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -68,12 +68,8 @@ enum TomlTypes { Integer(u64), // Simple boolean flag Bool(bool), - // Array of regular integers - ArrayNum(Vec), - // Array of hexadecimal integers - ArrayString(Vec), - // Array of booleans - ArrayBool(Vec), + // Array of TomlTypes + Array(Vec), // Struct of TomlTypes Table(BTreeMap), } @@ -90,17 +86,11 @@ impl TomlTypes { } (InputValue::Field(f), AbiType::Boolean) => TomlTypes::Bool(f.is_one()), - (InputValue::Vec(v), AbiType::Array { typ, .. }) => match typ.as_ref() { - AbiType::Field | AbiType::Integer { .. } => { - let array = v.iter().map(|i| format!("0x{}", i.to_hex())).collect(); - TomlTypes::ArrayString(array) - } - AbiType::Boolean => { - let array = v.iter().map(|i| i.is_one()).collect(); - TomlTypes::ArrayBool(array) - } - _ => return Err(InputParserError::AbiTypeMismatch(abi_type.clone())), - }, + (InputValue::Vec(vector), AbiType::Array { typ, .. }) => { + let array = + try_vecmap(vector, |value| TomlTypes::try_from_input_value(value, typ))?; + TomlTypes::Array(array) + } (InputValue::String(s), AbiType::String { .. }) => TomlTypes::String(s.to_string()), @@ -142,32 +132,9 @@ impl InputValue { (TomlTypes::Bool(boolean), AbiType::Boolean) => InputValue::Field(boolean.into()), - (TomlTypes::ArrayNum(arr_num), AbiType::Array { typ, .. }) - if matches!( - typ.as_ref(), - AbiType::Field | AbiType::Integer { .. } | AbiType::Boolean - ) => - { + (TomlTypes::Array(array), AbiType::Array { typ, .. }) => { let array_elements = - vecmap(arr_num, |elem_num| FieldElement::from(i128::from(elem_num))); - - InputValue::Vec(array_elements) - } - (TomlTypes::ArrayString(arr_str), AbiType::Array { typ, .. }) - if matches!( - typ.as_ref(), - AbiType::Field | AbiType::Integer { .. } | AbiType::Boolean - ) => - { - let array_elements = try_vecmap(arr_str, |elem_str| parse_str_to_field(&elem_str))?; - - InputValue::Vec(array_elements) - } - (TomlTypes::ArrayBool(arr_bool), AbiType::Array { typ, .. }) - if matches!(typ.as_ref(), AbiType::Boolean) => - { - let array_elements = vecmap(arr_bool, FieldElement::from); - + try_vecmap(array, |value| InputValue::try_from_toml(value, typ, arg_name))?; InputValue::Vec(array_elements) } diff --git a/crates/noirc_abi/src/lib.rs b/crates/noirc_abi/src/lib.rs index 6ecce8d8748..856889b3860 100644 --- a/crates/noirc_abi/src/lib.rs +++ b/crates/noirc_abi/src/lib.rs @@ -305,7 +305,11 @@ impl Abi { match (value, abi_type) { (InputValue::Field(elem), _) => encoded_value.push(elem), - (InputValue::Vec(vec_elem), _) => encoded_value.extend(vec_elem), + (InputValue::Vec(vec_elements), AbiType::Array { typ, .. }) => { + for elem in vec_elements { + encoded_value.extend(Self::encode_value(elem, typ)?); + } + } (InputValue::String(string), _) => { let str_as_fields = @@ -384,11 +388,14 @@ impl Abi { InputValue::Field(field_element) } - AbiType::Array { length, .. } => { - let field_elements: Vec = - field_iterator.take(*length as usize).collect(); + AbiType::Array { length, typ } => { + let length = *length as usize; + let mut array_elements = Vec::with_capacity(length); + for _ in 0..length { + array_elements.push(Self::decode_value(field_iterator, typ)?); + } - InputValue::Vec(field_elements) + InputValue::Vec(array_elements) } AbiType::String { length } => { let field_elements: Vec = @@ -459,7 +466,13 @@ mod test { // Note we omit return value from inputs let inputs: InputMap = BTreeMap::from([ - ("thing1".to_string(), InputValue::Vec(vec![FieldElement::one(), FieldElement::one()])), + ( + "thing1".to_string(), + InputValue::Vec(vec![ + InputValue::Field(FieldElement::one()), + InputValue::Field(FieldElement::one()), + ]), + ), ("thing2".to_string(), InputValue::Field(FieldElement::zero())), ]);