diff --git a/compiler/noirc_evaluator/src/acir/call/intrinsics/mod.rs b/compiler/noirc_evaluator/src/acir/call/intrinsics/mod.rs index cc117669689..95faec1a569 100644 --- a/compiler/noirc_evaluator/src/acir/call/intrinsics/mod.rs +++ b/compiler/noirc_evaluator/src/acir/call/intrinsics/mod.rs @@ -107,7 +107,15 @@ impl Context<'_> { let slice_typ = dfg.type_of_value(slice_contents); assert!(!slice_typ.is_nested_slice(), "ICE: Nested slice used in ACIR generation"); + let flattened_length = + slice_typ.element_types().iter().map(|typ| typ.flattened_size()).sum::(); let slice_length = self.flattened_size(slice_contents, dfg); + let slice_length = if flattened_length == 0 { + 0 + } else { + slice_length / flattened_length as usize + }; + let slice_length = self.acir_context.add_constant(slice_length); let acir_value = self.convert_value(slice_contents, dfg); diff --git a/compiler/noirc_evaluator/src/acir/tests/intrinsics.rs b/compiler/noirc_evaluator/src/acir/tests/intrinsics.rs index 05f2b9669e9..4134b464767 100644 --- a/compiler/noirc_evaluator/src/acir/tests/intrinsics.rs +++ b/compiler/noirc_evaluator/src/acir/tests/intrinsics.rs @@ -523,3 +523,29 @@ fn slice_remove_affected_by_predicate() { let program_no_side_effects = ssa_to_acir_program(src_no_side_effects); assert_ne!(program_side_effects, program_no_side_effects); } + +#[test] +fn as_slice_for_composite_slice() { + let src = " + acir(inline) predicate_pure fn main f0 { + b0(): + v3 = make_array [Field 10, Field 20, Field 30, Field 40] : [(Field, Field); 2] + v4, v5 = call as_slice(v3) -> (u32, [(Field, Field)]) + return v4 + } + "; + let program = ssa_to_acir_program(src); + + // Note that 2 is returned, not 4 (as there are two `(Field, Field)` elements) + assert_circuit_snapshot!(program, @r" + func 0 + private parameters: [] + public parameters: [] + return values: [w0] + ASSERT w1 = 10 + ASSERT w2 = 20 + ASSERT w3 = 30 + ASSERT w4 = 40 + ASSERT w0 = 2 + "); +}