diff --git a/compiler/noirc_evaluator/src/ssa/opt/as_slice_length.rs b/compiler/noirc_evaluator/src/ssa/opt/as_slice_length.rs index 9a679a393b5..9ab5fae53f7 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/as_slice_length.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/as_slice_length.rs @@ -41,7 +41,8 @@ impl Function { return; }; - let first_argument = arguments.first().unwrap(); + let first_argument = + arguments.first().expect("AsSlice should always have one argument"); let array_typ = context.dfg.type_of_value(*first_argument); let Type::Array(_, length) = array_typ else { unreachable!("AsSlice called with non-array {}", array_typ); @@ -66,12 +67,12 @@ mod test { // In this code we expect `return v2` to be replaced with `return u32 3` because // that's the length of the v0 array. let src = " - acir(inline) fn main f0 { - b0(v0: [Field; 3]): - v2, v3 = call as_slice(v0) -> (u32, [Field]) - return v2 - } - "; + acir(inline) fn main f0 { + b0(v0: [Field; 3]): + v2, v3 = call as_slice(v0) -> (u32, [Field]) + return v2 + } + "; let ssa = Ssa::from_str(src).unwrap(); let ssa = ssa.as_slice_optimization(); @@ -83,4 +84,81 @@ mod test { } "); } + + #[test] + fn as_slice_length_multiple_different_arrays() { + let src = " + acir(inline) fn main f0 { + b0(v0: [Field; 3], v1: [Field; 5]): + v3, v4 = call as_slice(v0) -> (u32, [Field]) + v5, v6 = call as_slice(v1) -> (u32, [Field]) + return v3, v5 + } + "; + let ssa = Ssa::from_str(src).unwrap(); + let ssa = ssa.as_slice_optimization(); + assert_ssa_snapshot!(ssa, @r" + acir(inline) fn main f0 { + b0(v0: [Field; 3], v1: [Field; 5]): + v3, v4 = call as_slice(v0) -> (u32, [Field]) + v5, v6 = call as_slice(v1) -> (u32, [Field]) + return u32 3, u32 5 + } + "); + } + + /// TODO(https://github.com/noir-lang/noir/issues/9416): This test should be prevented during SSA validation + /// Once type checking of intrinsic function calls is supported this test will have to be run against non-validated SSA. + #[test] + #[should_panic(expected = "AsSlice called with non-array [Field]")] + fn as_slice_length_on_slice_type() { + let src = " + acir(inline) fn main f0 { + b0(): + v3 = make_array [Field 1, Field 2, Field 3] : [Field] + v4 = call f1(v3) -> u32 + return v4 + } + + acir(inline) fn foo f1 { + b0(v0: [Field]): + v2, v3 = call as_slice(v0) -> (u32, [Field]) + return v2 + } + "; + let ssa = Ssa::from_str(src).unwrap(); + let _ = ssa.as_slice_optimization(); + } + + /// TODO(https://github.com/noir-lang/noir/issues/9416): This test should be prevented during SSA validation + /// Once type checking of intrinsic function calls is supported this test will have to be run against non-validated SSA. + #[test] + #[should_panic(expected = "AsSlice called with non-array Field")] + fn as_slice_length_on_numeric_type() { + let src = " + acir(inline) fn main f0 { + b0(v0: Field): + v2, v3 = call as_slice(v0) -> (u32, [Field]) + return v2 + } + "; + let ssa = Ssa::from_str(src).unwrap(); + let _ = ssa.as_slice_optimization(); + } + + /// TODO(https://github.com/noir-lang/noir/issues/9416): This test should be prevented during SSA validation + /// Once type checking of intrinsic function calls is supported this test will have to be run against non-validated SSA. + #[test] + #[should_panic(expected = "AsSlice should always have one argument")] + fn as_slice_wrong_number_of_arguments() { + let src = " + acir(inline) fn main f0 { + b0(): + v1, v2 = call as_slice() -> (u32, [Field]) + return v1 + } + "; + let ssa = Ssa::from_str(src).unwrap(); + let _ = ssa.as_slice_optimization(); + } }