Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
37 changes: 13 additions & 24 deletions compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,27 +687,7 @@ impl Context {
}

let read = self.acir_context.read_from_memory(block_id, &var_index)?;
let typ = match dfg.type_of_value(array) {
Type::Array(typ, _) => {
if typ.len() != 1 {
// TODO(#2461)
unimplemented!(
"Non-const array indices is not implemented for non-homogenous array"
);
}
typ[0].clone()
}
Type::Slice(typ) => {
if typ.len() != 1 {
// TODO(#2461)
unimplemented!(
"Non-const array indices is not implemented for non-homogenous array"
);
}
typ[0].clone()
}
_ => unreachable!("ICE - expected an array"),
};
let typ = dfg.type_of_value(array);
let typ = AcirType::from(typ);
self.define_result(dfg, instruction, AcirValue::Var(read, typ));
Ok(read)
Expand Down Expand Up @@ -744,16 +724,25 @@ impl Context {

// Every array has a length in its type, so we fetch that from
// the SSA IR.
//
// A slice's size must be fetched from the SSA value that represents the slice.
// However, this size is simply the capacity of a slice. The capacity is dependent upon the witness
// and may contain data for which we want to restrict access. The true slice length is tracked in a
// a separate SSA value and restrictions on slice indices should be generated elsewhere in the SSA.
let len = match dfg.type_of_value(array) {
Type::Array(_, len) => len,
Type::Slice(_) => {
Type::Array(typ, len) => {
// Flatten the array length to handle arrays of complex types
len * typ.len()
}
Type::Slice(typ) => {
// Fetch the true length of the slice from the array_set instruction
let length = length
.expect("ICE: array set on slice must have a length associated with the call");
let length_acir_var = self.convert_value(length, dfg).into_var()?;
let len = self.acir_context.var_to_expression(length_acir_var)?.to_const();
let len = len
.expect("ICE: slice length should be fully tracked and constant by ACIR gen");
len.to_u128() as usize
len.to_u128() as usize * typ.len()
}
_ => unreachable!("ICE - expected an array"),
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "dyn_index_fail_nested_array"
type = "bin"
authors = [""]
compiler_version = "0.11.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
y = "2"

[[x]]
a = "1"
b = "2"

[[x]]
a = "3"
b = "4"

[[x]]
a = "5"
b = "6"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
struct Foo {
a: Field,
b: Field,
}

fn main(mut x : [Foo; 3], y : pub Field) {
assert(x[y + 2].a == 5);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "nested_array_dynamic"
type = "bin"
authors = [""]
compiler_version = "0.11.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
y = "2"

[[x]]
a = "1"
b = "2"

[[x]]
a = "3"
b = "4"

[[x]]
a = "5"
b = "6"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

struct Foo {
a: Field,
b: Field,
}

fn main(mut x : [Foo; 3], y : pub Field) {
assert(x[y - 2].a == 1);
assert(x[y - 2].b == 2);
assert(x[y - 1].a == 3);
assert(x[y - 1].b == 4);
assert(x[y].a == 5);
assert(x[y].b == 6);

if y != 2 {
x[y].a = 50;
} else {
x[y].a = 100;
}

dep::std::println(x);
}