Skip to content

Commit 58ce59e

Browse files
authored
fix: merge expr bindings with instantiations bindings during monomorphization (#8713)
1 parent 89783b6 commit 58ce59e

File tree

17 files changed

+394
-7
lines changed

17 files changed

+394
-7
lines changed

compiler/noirc_frontend/src/monomorphization/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2511,7 +2511,7 @@ pub fn perform_impl_bindings(
25112511
}
25122512

25132513
pub fn resolve_trait_method(
2514-
interner: &NodeInterner,
2514+
interner: &mut NodeInterner,
25152515
method: TraitMethodId,
25162516
expr_id: ExprId,
25172517
) -> Result<node_interner::FuncId, InterpreterError> {
@@ -2531,7 +2531,14 @@ pub fn resolve_trait_method(
25312531
&trait_generics.ordered,
25322532
&trait_generics.named,
25332533
) {
2534-
Ok((TraitImplKind::Normal(impl_id), _instantiation_bindings)) => impl_id,
2534+
Ok((TraitImplKind::Normal(impl_id), instantiation_bindings)) => {
2535+
// Insert any additional instantiation bindings into this expression's instantiation bindings.
2536+
// This is similar to what's done in `verify_trait_constraint` in the frontend.
2537+
let mut bindings = interner.get_instantiation_bindings(expr_id).clone();
2538+
bindings.extend(instantiation_bindings);
2539+
interner.store_instantiation_bindings(expr_id, bindings);
2540+
impl_id
2541+
}
25352542
Ok((TraitImplKind::Assumed { .. }, _instantiation_bindings)) => {
25362543
return Err(InterpreterError::NoImpl { location });
25372544
}

test_programs/compile_success_empty/serialize/Nargo.toml renamed to test_programs/compile_success_empty/serialize_1/Nargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "serialize"
2+
name = "serialize_1"
33
type = "bin"
44
authors = [""]
55
compiler_version = ">=0.32.0"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
trait Serialize {
2+
let Size: u32;
3+
4+
// Note that Rust disallows referencing constants here!
5+
fn serialize(self) -> [Field; Self::Size];
6+
}
7+
8+
impl<A, B> Serialize for (A, B)
9+
where
10+
A: Serialize,
11+
B: Serialize,
12+
{
13+
let Size = <A as Serialize>::Size + <B as Serialize>::Size;
14+
15+
fn serialize(self: Self) -> [Field; Self::Size] {
16+
let mut array: [Field; Self::Size] = std::mem::zeroed();
17+
let a = self.0.serialize();
18+
let b = self.1.serialize();
19+
20+
for i in 0..a.len() {
21+
array[i] = a[i];
22+
}
23+
for i in 0..b.len() {
24+
array[i + a.len()] = b[i];
25+
}
26+
array
27+
}
28+
}
29+
30+
impl<T, let N: u32> Serialize for [T; N]
31+
where
32+
T: Serialize,
33+
{
34+
let Size = <T as Serialize>::Size * N;
35+
36+
fn serialize(self: Self) -> [Field; Self::Size] {
37+
let mut array: [Field; Self::Size] = std::mem::zeroed();
38+
let mut array_i = 0;
39+
40+
for elem in self {
41+
let elem_fields = elem.serialize();
42+
43+
for i in 0..elem_fields.len() {
44+
array[array_i] = elem_fields[i];
45+
array_i += 1;
46+
}
47+
}
48+
49+
array
50+
}
51+
}
52+
53+
impl Serialize for Field {
54+
let Size: u32 = 1;
55+
56+
fn serialize(self) -> [Field; Self::Size] {
57+
[self]
58+
}
59+
}
60+
61+
fn main() {
62+
let x = (((1, [2, 3, 4]), [5, 6, 7, 8]), 9);
63+
assert_eq(x.serialize().len(), 9);
64+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "serialize_2"
3+
type = "bin"
4+
authors = [""]
5+
compiler_version = ">=0.32.0"
6+
7+
[dependencies]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
trait Serialize {
2+
let Size: u32;
3+
4+
fn serialize(self);
5+
}
6+
7+
impl Serialize for Field {
8+
let Size: u32 = 1;
9+
10+
fn serialize(self) {}
11+
}
12+
13+
impl<A> Serialize for (A,)
14+
where
15+
A: Serialize,
16+
{
17+
let Size = <A as Serialize>::Size;
18+
19+
fn serialize(self: Self) {
20+
self.0.serialize();
21+
}
22+
}
23+
24+
fn main() {
25+
let x = ((1,),);
26+
x.serialize();
27+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "serialize_3"
3+
type = "bin"
4+
authors = [""]
5+
compiler_version = ">=0.32.0"
6+
7+
[dependencies]
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
trait Serialize {
2+
let Size: u32;
3+
4+
fn serialize(self) -> [Field; Self::Size];
5+
}
6+
7+
impl<A, B> Serialize for (A, B)
8+
where
9+
A: Serialize,
10+
B: Serialize,
11+
{
12+
let Size = <A as Serialize>::Size + <B as Serialize>::Size;
13+
14+
fn serialize(self: Self) -> [Field; Self::Size] {
15+
let _ = self.0.serialize();
16+
[0; Self::Size]
17+
}
18+
}
19+
20+
impl<T, let N: u32> Serialize for [T; N]
21+
where
22+
T: Serialize,
23+
{
24+
let Size = <T as Serialize>::Size * N;
25+
26+
fn serialize(self: Self) -> [Field; Self::Size] {
27+
[0; Self::Size]
28+
}
29+
}
30+
31+
impl Serialize for Field {
32+
let Size: u32 = 1;
33+
34+
fn serialize(self) -> [Field; Self::Size] {
35+
[self]
36+
}
37+
}
38+
39+
fn main() {
40+
let x = (((1, [2, 3, 4]), [5, 6, 7, 8]), 9);
41+
assert_eq(x.serialize().len(), 9);
42+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "serialize_4"
3+
type = "bin"
4+
authors = [""]
5+
compiler_version = ">=0.32.0"
6+
7+
[dependencies]

test_programs/compile_success_empty/serialize/src/main.nr renamed to test_programs/compile_success_empty/serialize_4/src/main.nr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,6 @@ impl Serialize for Field {
5959
}
6060

6161
fn main() {
62-
let x = ((1, [2, 3, 4]), [5, 6, 7, 8]);
63-
assert_eq(x.serialize().len(), 8);
62+
let x = (1, [2, 3, 4]);
63+
assert_eq(x.serialize().len(), 4);
6464
}

tooling/nargo_cli/build.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ const TESTS_WITHOUT_STDOUT_CHECK: [&str; 0] = [];
145145
/// These tests are ignored because of existing bugs in `nargo expand`.
146146
/// As the bugs are fixed these tests should be removed from this list.
147147
/// (some are ignored on purpose for the same reason as `IGNORED_NARGO_EXPAND_EXECUTION_TESTS`)
148-
const IGNORED_NARGO_EXPAND_COMPILE_SUCCESS_EMPTY_TESTS: [&str; 17] = [
148+
const IGNORED_NARGO_EXPAND_COMPILE_SUCCESS_EMPTY_TESTS: [&str; 20] = [
149149
// bug
150150
"associated_type_bounds",
151151
// bug
@@ -163,7 +163,13 @@ const IGNORED_NARGO_EXPAND_COMPILE_SUCCESS_EMPTY_TESTS: [&str; 17] = [
163163
// bug
164164
"regression_7038_4",
165165
// bug
166-
"serialize",
166+
"serialize_1",
167+
// bug
168+
"serialize_2",
169+
// bug
170+
"serialize_3",
171+
// bug
172+
"serialize_4",
167173
// bug
168174
"trait_allowed_item_name_matches",
169175
// bug

0 commit comments

Comments
 (0)