Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "tuple_inputs"
type = "bin"
authors = [""]
compiler_version = "0.14.1"

[dependencies]
12 changes: 12 additions & 0 deletions tooling/nargo_cli/tests/execution_success/tuple_inputs/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pair = [1, 0]
x = [[0, 1, 2], [3, 4, 5]]

[[struct_pair]]
a = "1"
b = ["2", "3", "20"]

[struct_pair.bar]
inner = ["100", "101", "102"]

[[struct_pair]]
inner = ["103", "104", "105"]
37 changes: 37 additions & 0 deletions tooling/nargo_cli/tests/execution_success/tuple_inputs/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
struct Bar {
inner: [Field; 3],
}

struct Foo {
a: Field,
b: [Field; 3],
bar: Bar,
}

fn main(pair : (Field, Field), x: [(u8, u8, u8); 2], struct_pair: (Foo, Bar)) -> pub (Field, u8) {
assert(pair.0 == 1);
assert(pair.1 == 0);

let mut start_val = 0;
for i in 0..2 {
assert(x[i].0 == start_val);
assert(x[i].1 == start_val + 1);
assert(x[i].2 == start_val + 2);
start_val += 3;
}

assert(struct_pair.0.a == 1);
assert(struct_pair.0.b == [2, 3, 20]);
assert(struct_pair.0.bar.inner == [100, 101, 102]);
assert(struct_pair.1.inner == [103, 104, 105]);

let (u, v) = if pair.0 as u32 < 1 {
(pair.0, pair.0 + 1)
} else {
(pair.0 + 1, pair.0)
};
assert(u == pair.0 + 1);
assert(v == pair.0);

(u, v as u8)
}
14 changes: 14 additions & 0 deletions tooling/noirc_abi/src/input_parser/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ impl JsonTypes {
JsonTypes::Table(map_with_json_types)
}

(InputValue::Vec(vector), AbiType::Tuple { fields }) => {
let fields = try_vecmap(vector.iter().zip(fields), |(value, typ)| {
JsonTypes::try_from_input_value(value, typ)
})?;
JsonTypes::Array(fields)
}

_ => return Err(InputParserError::AbiTypeMismatch(abi_type.clone())),
};
Ok(json_value)
Expand Down Expand Up @@ -169,6 +176,13 @@ impl InputValue {
InputValue::Struct(native_table)
}

(JsonTypes::Array(array), AbiType::Tuple { fields }) => {
let tuple_fields = try_vecmap(array.into_iter().zip(fields), |(value, typ)| {
InputValue::try_from_json(value, typ, arg_name)
})?;
InputValue::Vec(tuple_fields)
}

(_, _) => return Err(InputParserError::AbiTypeMismatch(param_type.clone())),
};

Expand Down
11 changes: 11 additions & 0 deletions tooling/noirc_abi/src/input_parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ impl InputValue {
})
}

(InputValue::Vec(vec_elements), AbiType::Tuple { fields }) => {
if vec_elements.len() != fields.len() {
return false;
}

vec_elements
.iter()
.zip(fields)
.all(|(input_value, abi_param)| input_value.matches_abi(abi_param))
}

// All other InputValue-AbiType combinations are fundamentally incompatible.
_ => false,
}
Expand Down
14 changes: 14 additions & 0 deletions tooling/noirc_abi/src/input_parser/toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ impl TomlTypes {
TomlTypes::Table(map_with_toml_types)
}

(InputValue::Vec(vector), AbiType::Tuple { fields }) => {
let fields = try_vecmap(vector.iter().zip(fields), |(value, typ)| {
TomlTypes::try_from_input_value(value, typ)
})?;
TomlTypes::Array(fields)
}

_ => return Err(InputParserError::AbiTypeMismatch(abi_type.clone())),
};
Ok(toml_value)
Expand Down Expand Up @@ -156,6 +163,13 @@ impl InputValue {
InputValue::Struct(native_table)
}

(TomlTypes::Array(array), AbiType::Tuple { fields }) => {
let tuple_fields = try_vecmap(array.into_iter().zip(fields), |(value, typ)| {
InputValue::try_from_toml(value, typ, arg_name)
})?;
InputValue::Vec(tuple_fields)
}

(_, _) => return Err(InputParserError::AbiTypeMismatch(param_type.clone())),
};

Expand Down
24 changes: 23 additions & 1 deletion tooling/noirc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ pub enum AbiType {
)]
fields: Vec<(String, AbiType)>,
},
Tuple {
fields: Vec<AbiType>,
},
String {
length: u64,
},
Expand Down Expand Up @@ -164,7 +167,10 @@ impl AbiType {
context.fully_qualified_struct_path(context.root_crate_id(), struct_type.id);
Self::Struct { fields, path }
}
Type::Tuple(_) => todo!("AbiType::from_type not yet implemented for tuple types"),
Type::Tuple(fields) => {
let fields = vecmap(fields, |typ| Self::from_type(context, typ));
Self::Tuple { fields }
}
Type::TypeVariable(_, _) => unreachable!(),
Type::NamedGeneric(..) => unreachable!(),
Type::Forall(..) => unreachable!(),
Expand All @@ -182,6 +188,9 @@ impl AbiType {
AbiType::Struct { fields, .. } => {
fields.iter().fold(0, |acc, (_, field_type)| acc + field_type.field_count())
}
AbiType::Tuple { fields } => {
fields.iter().fold(0, |acc, field_typ| acc + field_typ.field_count())
}
AbiType::String { length } => *length as u32,
}
}
Expand Down Expand Up @@ -370,6 +379,11 @@ impl Abi {
encoded_value.extend(Self::encode_value(object[field].clone(), typ)?);
}
}
(InputValue::Vec(vec_elements), AbiType::Tuple { fields }) => {
for (value, typ) in vec_elements.into_iter().zip(fields) {
encoded_value.extend(Self::encode_value(value, typ)?);
}
}
_ => unreachable!("value should have already been checked to match abi type"),
}
Ok(encoded_value)
Expand Down Expand Up @@ -462,6 +476,14 @@ fn decode_value(

InputValue::Struct(struct_map)
}
AbiType::Tuple { fields } => {
let mut tuple_elements = Vec::with_capacity(fields.len());
for field_typ in fields {
tuple_elements.push(decode_value(field_iterator, field_typ)?);
}

InputValue::Vec(tuple_elements)
}
};

Ok(value)
Expand Down
14 changes: 14 additions & 0 deletions tooling/noirc_abi_wasm/src/temp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ impl JsonTypes {
JsonTypes::Table(map_with_json_types)
}

(InputValue::Vec(vector), AbiType::Tuple { fields }) => {
let fields = try_vecmap(vector.iter().zip(fields), |(value, typ)| {
JsonTypes::try_from_input_value(value, typ)
})?;
JsonTypes::Array(fields)
}

_ => return Err(InputParserError::AbiTypeMismatch(abi_type.clone())),
};
Ok(json_value)
Expand Down Expand Up @@ -104,6 +111,13 @@ pub(super) fn input_value_from_json_type(
InputValue::Struct(native_table)
}

(JsonTypes::Array(array), AbiType::Tuple { fields }) => {
let tuple_fields = try_vecmap(array.into_iter().zip(fields), |(value, typ)| {
input_value_from_json_type(value, typ, arg_name)
})?;
InputValue::Vec(tuple_fields)
}

(_, _) => return Err(InputParserError::AbiTypeMismatch(param_type.clone())),
};

Expand Down