diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index 8b800e0db54..5b268de239d 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -85,10 +85,11 @@ pub(super) fn simplify_call( } } Intrinsic::AsSlice => { - let slice = dfg.get_array_constant(arguments[0]); - if let Some((slice, element_type)) = slice { - let slice_length = dfg.make_constant(slice.len().into(), Type::length_type()); - let new_slice = dfg.make_array(slice, element_type); + let array = dfg.get_array_constant(arguments[0]); + if let Some((array, array_type)) = array { + let slice_length = dfg.make_constant(array.len().into(), Type::length_type()); + let inner_element_types = array_type.element_types(); + let new_slice = dfg.make_array(array, Type::Slice(inner_element_types)); SimplifyResult::SimplifiedToMultiple(vec![slice_length, new_slice]) } else { SimplifyResult::None diff --git a/compiler/noirc_evaluator/src/ssa/ir/types.rs b/compiler/noirc_evaluator/src/ssa/ir/types.rs index ea3f5393245..48036580d29 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/types.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/types.rs @@ -159,6 +159,13 @@ impl Type { Type::Reference(element) => element.contains_an_array(), } } + + pub(crate) fn element_types(self) -> Rc> { + match self { + Type::Array(element_types, _) | Type::Slice(element_types) => element_types, + other => panic!("element_types: Expected array or slice, found {other}"), + } + } } /// Composite Types are essentially flattened struct or tuple types. diff --git a/test_programs/execution_success/array_to_slice/src/main.nr b/test_programs/execution_success/array_to_slice/src/main.nr index b97f68fc280..0d0f9562d7b 100644 --- a/test_programs/execution_success/array_to_slice/src/main.nr +++ b/test_programs/execution_success/array_to_slice/src/main.nr @@ -7,6 +7,7 @@ fn as_slice_push(xs: [T; N]) -> [T] { slice } +// Expected that x == 0 and y == 1 fn main(x: Field, y: pub Field) { let xs: [Field; 0] = []; let ys: [Field; 1] = [1]; @@ -30,4 +31,26 @@ fn main(x: Field, y: pub Field) { assert(dynamic.as_slice()[2] == dynamic_expected[2]); assert(dynamic.as_slice()[3] == dynamic_expected[3]); assert(dynamic.as_slice().len() == 4); + + regression_4609_append_slices(x, y); + regression_4609_append_dynamic_slices(x, y); +} + +fn regression_4609_append_slices(x: Field, y: Field) { + let sl = [x, 1, 2, 3].as_slice(); + let sl2 = [y, 5, 6].as_slice(); + let sl3 = sl.append(sl2); + assert(sl3[0] == x); + assert(sl3[4] == y); +} + +fn regression_4609_append_dynamic_slices(x: Field, y: Field) { + let mut sl = [x, 1, 2, 3].as_slice(); + sl[x] = x + 10; + let mut sl2 = [y, 5, 6].as_slice(); + sl2[y] = y + 5; + let sl3 = sl.append(sl2); + assert(sl3[0] == 10); + assert(sl3[4] == y); + assert(sl3[5] == 6); }