diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index 01c6c273d12..e8e72375c07 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -2511,7 +2511,7 @@ pub fn perform_impl_bindings( } pub fn resolve_trait_method( - interner: &NodeInterner, + interner: &mut NodeInterner, method: TraitMethodId, expr_id: ExprId, ) -> Result { @@ -2531,7 +2531,14 @@ pub fn resolve_trait_method( &trait_generics.ordered, &trait_generics.named, ) { - Ok((TraitImplKind::Normal(impl_id), _instantiation_bindings)) => impl_id, + Ok((TraitImplKind::Normal(impl_id), instantiation_bindings)) => { + // Insert any additional instantiation bindings into this expression's instantiation bindings. + // This is similar to what's done in `verify_trait_constraint` in the frontend. + let mut bindings = interner.get_instantiation_bindings(expr_id).clone(); + bindings.extend(instantiation_bindings); + interner.store_instantiation_bindings(expr_id, bindings); + impl_id + } Ok((TraitImplKind::Assumed { .. }, _instantiation_bindings)) => { return Err(InterpreterError::NoImpl { location }); } diff --git a/test_programs/compile_success_empty/serialize/Nargo.toml b/test_programs/compile_success_empty/serialize_1/Nargo.toml similarity index 80% rename from test_programs/compile_success_empty/serialize/Nargo.toml rename to test_programs/compile_success_empty/serialize_1/Nargo.toml index 2cf87765b8a..62bbf337b11 100644 --- a/test_programs/compile_success_empty/serialize/Nargo.toml +++ b/test_programs/compile_success_empty/serialize_1/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "serialize" +name = "serialize_1" type = "bin" authors = [""] compiler_version = ">=0.32.0" diff --git a/test_programs/compile_success_empty/serialize_1/src/main.nr b/test_programs/compile_success_empty/serialize_1/src/main.nr new file mode 100644 index 00000000000..5eec603d83e --- /dev/null +++ b/test_programs/compile_success_empty/serialize_1/src/main.nr @@ -0,0 +1,64 @@ +trait Serialize { + let Size: u32; + + // Note that Rust disallows referencing constants here! + fn serialize(self) -> [Field; Self::Size]; +} + +impl Serialize for (A, B) +where + A: Serialize, + B: Serialize, +{ + let Size = ::Size + ::Size; + + fn serialize(self: Self) -> [Field; Self::Size] { + let mut array: [Field; Self::Size] = std::mem::zeroed(); + let a = self.0.serialize(); + let b = self.1.serialize(); + + for i in 0..a.len() { + array[i] = a[i]; + } + for i in 0..b.len() { + array[i + a.len()] = b[i]; + } + array + } +} + +impl Serialize for [T; N] +where + T: Serialize, +{ + let Size = ::Size * N; + + fn serialize(self: Self) -> [Field; Self::Size] { + let mut array: [Field; Self::Size] = std::mem::zeroed(); + let mut array_i = 0; + + for elem in self { + let elem_fields = elem.serialize(); + + for i in 0..elem_fields.len() { + array[array_i] = elem_fields[i]; + array_i += 1; + } + } + + array + } +} + +impl Serialize for Field { + let Size: u32 = 1; + + fn serialize(self) -> [Field; Self::Size] { + [self] + } +} + +fn main() { + let x = (((1, [2, 3, 4]), [5, 6, 7, 8]), 9); + assert_eq(x.serialize().len(), 9); +} diff --git a/test_programs/compile_success_empty/serialize_2/Nargo.toml b/test_programs/compile_success_empty/serialize_2/Nargo.toml new file mode 100644 index 00000000000..0534529f5d4 --- /dev/null +++ b/test_programs/compile_success_empty/serialize_2/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "serialize_2" +type = "bin" +authors = [""] +compiler_version = ">=0.32.0" + +[dependencies] diff --git a/test_programs/compile_success_empty/serialize_2/src/main.nr b/test_programs/compile_success_empty/serialize_2/src/main.nr new file mode 100644 index 00000000000..32aff8dfc2e --- /dev/null +++ b/test_programs/compile_success_empty/serialize_2/src/main.nr @@ -0,0 +1,27 @@ +trait Serialize { + let Size: u32; + + fn serialize(self); +} + +impl Serialize for Field { + let Size: u32 = 1; + + fn serialize(self) {} +} + +impl Serialize for (A,) +where + A: Serialize, +{ + let Size = ::Size; + + fn serialize(self: Self) { + self.0.serialize(); + } +} + +fn main() { + let x = ((1,),); + x.serialize(); +} diff --git a/test_programs/compile_success_empty/serialize_3/Nargo.toml b/test_programs/compile_success_empty/serialize_3/Nargo.toml new file mode 100644 index 00000000000..33dca9c1a65 --- /dev/null +++ b/test_programs/compile_success_empty/serialize_3/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "serialize_3" +type = "bin" +authors = [""] +compiler_version = ">=0.32.0" + +[dependencies] diff --git a/test_programs/compile_success_empty/serialize_3/src/main.nr b/test_programs/compile_success_empty/serialize_3/src/main.nr new file mode 100644 index 00000000000..b7b1df24f22 --- /dev/null +++ b/test_programs/compile_success_empty/serialize_3/src/main.nr @@ -0,0 +1,42 @@ +trait Serialize { + let Size: u32; + + fn serialize(self) -> [Field; Self::Size]; +} + +impl Serialize for (A, B) +where + A: Serialize, + B: Serialize, +{ + let Size = ::Size + ::Size; + + fn serialize(self: Self) -> [Field; Self::Size] { + let _ = self.0.serialize(); + [0; Self::Size] + } +} + +impl Serialize for [T; N] +where + T: Serialize, +{ + let Size = ::Size * N; + + fn serialize(self: Self) -> [Field; Self::Size] { + [0; Self::Size] + } +} + +impl Serialize for Field { + let Size: u32 = 1; + + fn serialize(self) -> [Field; Self::Size] { + [self] + } +} + +fn main() { + let x = (((1, [2, 3, 4]), [5, 6, 7, 8]), 9); + assert_eq(x.serialize().len(), 9); +} diff --git a/test_programs/compile_success_empty/serialize_4/Nargo.toml b/test_programs/compile_success_empty/serialize_4/Nargo.toml new file mode 100644 index 00000000000..d6f36ccf4ae --- /dev/null +++ b/test_programs/compile_success_empty/serialize_4/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "serialize_4" +type = "bin" +authors = [""] +compiler_version = ">=0.32.0" + +[dependencies] diff --git a/test_programs/compile_success_empty/serialize/src/main.nr b/test_programs/compile_success_empty/serialize_4/src/main.nr similarity index 93% rename from test_programs/compile_success_empty/serialize/src/main.nr rename to test_programs/compile_success_empty/serialize_4/src/main.nr index a11fdf570d0..41879392c4f 100644 --- a/test_programs/compile_success_empty/serialize/src/main.nr +++ b/test_programs/compile_success_empty/serialize_4/src/main.nr @@ -59,6 +59,6 @@ impl Serialize for Field { } fn main() { - let x = ((1, [2, 3, 4]), [5, 6, 7, 8]); - assert_eq(x.serialize().len(), 8); + let x = (1, [2, 3, 4]); + assert_eq(x.serialize().len(), 4); } diff --git a/tooling/nargo_cli/build.rs b/tooling/nargo_cli/build.rs index 63a79a9fe51..8d0ecc2a815 100644 --- a/tooling/nargo_cli/build.rs +++ b/tooling/nargo_cli/build.rs @@ -145,7 +145,7 @@ const TESTS_WITHOUT_STDOUT_CHECK: [&str; 0] = []; /// These tests are ignored because of existing bugs in `nargo expand`. /// As the bugs are fixed these tests should be removed from this list. /// (some are ignored on purpose for the same reason as `IGNORED_NARGO_EXPAND_EXECUTION_TESTS`) -const IGNORED_NARGO_EXPAND_COMPILE_SUCCESS_EMPTY_TESTS: [&str; 17] = [ +const IGNORED_NARGO_EXPAND_COMPILE_SUCCESS_EMPTY_TESTS: [&str; 20] = [ // bug "associated_type_bounds", // bug @@ -163,7 +163,13 @@ const IGNORED_NARGO_EXPAND_COMPILE_SUCCESS_EMPTY_TESTS: [&str; 17] = [ // bug "regression_7038_4", // bug - "serialize", + "serialize_1", + // bug + "serialize_2", + // bug + "serialize_3", + // bug + "serialize_4", // bug "trait_allowed_item_name_matches", // bug diff --git a/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize/execute__tests__force_brillig_false_inliner_0.snap b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_1/execute__tests__force_brillig_false_inliner_0.snap similarity index 100% rename from tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize/execute__tests__force_brillig_false_inliner_0.snap rename to tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_1/execute__tests__force_brillig_false_inliner_0.snap diff --git a/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_2/execute__tests__expanded.snap b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_2/execute__tests__expanded.snap new file mode 100644 index 00000000000..ba5ebb3d93c --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_2/execute__tests__expanded.snap @@ -0,0 +1,67 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: expanded_code +--- +trait Serialize { + let Size: u32; + + fn serialize(self) -> [Field; Size]; +} + +impl Serialize for (A, B) where A: Serialize, B: Serialize { + type Size = ::Size + ::Size; + + fn serialize(self) -> [Field; ::Size + ::Size] where A: Serialize, B: Serialize { + let mut array: [Field; ::Size + ::Size] = std::mem::zeroed(); + let a: [Field; ::Size] = Serialize::serialize(self.0); + let b: [Field; ::Size] = Serialize::serialize(self.1); + for i in 0..a.len() { + array[i] = a[i]; + }; + for i in 0..b.len() { + { + let i_3793: u32 = i + a.len(); + array[i_3793] = b[i]; + } + }; + array + } +} + +impl Serialize for [T; N] where T: Serialize { + type Size = N * ::Size; + + fn serialize(self) -> [Field; N * ::Size] where T: Serialize { + let mut array: [Field; N * ::Size] = std::mem::zeroed(); + let mut array_i: Field = 0; + { + let ___i0: Self = self; + for ___i1 in 0..___i0.len() { + let elem: T = ___i0[___i1]; + { + let elem_fields: [Field; ::Size] = Serialize::serialize(elem); + for i in 0..elem_fields.len() { + array[array_i] = elem_fields[i]; + array_i = array_i + 1; + } + } + } + }; + array + } +} + +impl Serialize for Field { + let Size: u32 = 1; + + fn serialize(self) -> [Self; 1] { + [self] + } +} + +fn main() { + let x: (((Field, [Field; 3]), [Field; 4]), Field) = (((1, [2, 3, 4]), [5, 6, 7, 8]), 9); + assert(x.serialize().len() == 9); +} + +// Warning: the generated code has syntax errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_2/execute__tests__force_brillig_false_inliner_0.snap b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_2/execute__tests__force_brillig_false_inliner_0.snap new file mode 100644 index 00000000000..7de940827c8 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_2/execute__tests__force_brillig_false_inliner_0.snap @@ -0,0 +1,26 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: artifact +--- +{ + "noir_version": "[noir_version]", + "hash": "[hash]", + "abi": { + "parameters": [], + "return_type": null, + "error_types": {} + }, + "bytecode": [ + "func 0", + "current witness index : _0", + "private parameters indices : []", + "public parameters indices : []", + "return value indices : []" + ], + "debug_symbols": "XY5BCsQwCEXv4rqLWfcqw1BsaosgJtikMITefWyYQOlK/3/6tcJCc9km1jXuML4rzMYivE0SA2aO6m49B+hyykbkFty4byU00gyjFpEBDpTShvaE2mpGc/oagHTx6oErC13d+XGBge158UBjnIX+ci0abjR/Uyf942Qx0FKMrqTGPPsH", + "file_map": {}, + "names": [ + "main" + ], + "brillig_names": [] +} diff --git a/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_3/execute__tests__expanded.snap b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_3/execute__tests__expanded.snap new file mode 100644 index 00000000000..7d4d0ef29c9 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_3/execute__tests__expanded.snap @@ -0,0 +1,34 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: expanded_code +--- +trait Serialize { + let Size: u32; + + fn serialize(self); +} + +impl Serialize for Field { + let Size: u32 = 1; + + fn serialize(self) {} +} + +impl Serialize for (A,) +where + A: Serialize, +{ + type Size = ::Size; + + fn serialize(self) + where + A: Serialize, + { + Serialize::serialize(self.0); + } +} + +fn main() { + let x: ((Field,),) = ((1,),); + x.serialize(); +} diff --git a/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_3/execute__tests__force_brillig_false_inliner_0.snap b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_3/execute__tests__force_brillig_false_inliner_0.snap new file mode 100644 index 00000000000..7de940827c8 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_3/execute__tests__force_brillig_false_inliner_0.snap @@ -0,0 +1,26 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: artifact +--- +{ + "noir_version": "[noir_version]", + "hash": "[hash]", + "abi": { + "parameters": [], + "return_type": null, + "error_types": {} + }, + "bytecode": [ + "func 0", + "current witness index : _0", + "private parameters indices : []", + "public parameters indices : []", + "return value indices : []" + ], + "debug_symbols": "XY5BCsQwCEXv4rqLWfcqw1BsaosgJtikMITefWyYQOlK/3/6tcJCc9km1jXuML4rzMYivE0SA2aO6m49B+hyykbkFty4byU00gyjFpEBDpTShvaE2mpGc/oagHTx6oErC13d+XGBge158UBjnIX+ci0abjR/Uyf942Qx0FKMrqTGPPsH", + "file_map": {}, + "names": [ + "main" + ], + "brillig_names": [] +} diff --git a/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_4/execute__tests__expanded.snap b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_4/execute__tests__expanded.snap new file mode 100644 index 00000000000..0040ddafe24 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_4/execute__tests__expanded.snap @@ -0,0 +1,41 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: expanded_code +--- +trait Serialize { + let Size: u32; + + fn serialize(self) -> [Field; Size]; +} + +impl Serialize for (A, B) where A: Serialize, B: Serialize { + type Size = ::Size + ::Size; + + fn serialize(self) -> [Field; ::Size + ::Size] where A: Serialize, B: Serialize { + let _: [Field; ::Size] = Serialize::serialize(self.0); + [0; ::Size + ::Size] + } +} + +impl Serialize for [T; N] where T: Serialize { + type Size = N * ::Size; + + fn serialize(self) -> [Field; N * ::Size] where T: Serialize { + [0; N * ::Size] + } +} + +impl Serialize for Field { + let Size: u32 = 1; + + fn serialize(self) -> [Self; 1] { + [self] + } +} + +fn main() { + let x: (((Field, [Field; 3]), [Field; 4]), Field) = (((1, [2, 3, 4]), [5, 6, 7, 8]), 9); + assert(x.serialize().len() == 9); +} + +// Warning: the generated code has syntax errors diff --git a/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_4/execute__tests__force_brillig_false_inliner_0.snap b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_4/execute__tests__force_brillig_false_inliner_0.snap new file mode 100644 index 00000000000..7de940827c8 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_success_empty/serialize_4/execute__tests__force_brillig_false_inliner_0.snap @@ -0,0 +1,26 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: artifact +--- +{ + "noir_version": "[noir_version]", + "hash": "[hash]", + "abi": { + "parameters": [], + "return_type": null, + "error_types": {} + }, + "bytecode": [ + "func 0", + "current witness index : _0", + "private parameters indices : []", + "public parameters indices : []", + "return value indices : []" + ], + "debug_symbols": "XY5BCsQwCEXv4rqLWfcqw1BsaosgJtikMITefWyYQOlK/3/6tcJCc9km1jXuML4rzMYivE0SA2aO6m49B+hyykbkFty4byU00gyjFpEBDpTShvaE2mpGc/oagHTx6oErC13d+XGBge158UBjnIX+ci0abjR/Uyf942Qx0FKMrqTGPPsH", + "file_map": {}, + "names": [ + "main" + ], + "brillig_names": [] +}