diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index c473ac7f8a6..07da3398593 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -62,8 +62,6 @@ impl<'a> Interpreter<'a> { arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let previous_state = self.enter_function(); - let meta = self.interner.function_meta(&function); if meta.parameters.len() != arguments.len() { return Err(InterpreterError::ArgumentCountMismatch { @@ -78,6 +76,8 @@ impl<'a> Interpreter<'a> { } let parameters = meta.parameters.0.clone(); + let previous_state = self.enter_function(); + for ((parameter, typ, _), (argument, arg_location)) in parameters.iter().zip(arguments) { self.define_pattern(parameter, typ, argument, arg_location)?; } @@ -102,6 +102,7 @@ impl<'a> Interpreter<'a> { if let Some(builtin) = func_attrs.builtin() { match builtin.as_str() { "array_len" => builtin::array_len(&arguments), + "as_slice" => builtin::as_slice(arguments), _ => { let item = format!("Evaluation for builtin function {builtin}"); Err(InterpreterError::Unimplemented { item, location }) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 3e5ad207719..9216ba271c1 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -1,6 +1,9 @@ use noirc_errors::Location; -use crate::hir::comptime::{errors::IResult, Value}; +use crate::{ + hir::comptime::{errors::IResult, Value}, + Type, +}; pub(super) fn array_len(arguments: &[(Value, Location)]) -> IResult { assert_eq!(arguments.len(), 1, "ICE: `array_len` should only receive a single argument"); @@ -10,3 +13,13 @@ pub(super) fn array_len(arguments: &[(Value, Location)]) -> IResult { _ => unreachable!("ICE: Cannot query length of types other than arrays or slices"), } } + +pub(super) fn as_slice(mut arguments: Vec<(Value, Location)>) -> IResult { + assert_eq!(arguments.len(), 1, "ICE: `as_slice` should only receive a single argument"); + let (array, _) = arguments.pop().unwrap(); + match array { + Value::Array(values, Type::Array(_, typ)) => Ok(Value::Slice(values, Type::Slice(typ))), + // Type checking should prevent this branch being taken. + _ => unreachable!("ICE: Cannot convert types other than arrays into slices"), + } +} diff --git a/test_programs/compile_success_empty/comptime_as_slice/Nargo.toml b/test_programs/compile_success_empty/comptime_as_slice/Nargo.toml new file mode 100644 index 00000000000..90c67b07b2b --- /dev/null +++ b/test_programs/compile_success_empty/comptime_as_slice/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "array_to_slice" +type = "bin" +authors = [""] +compiler_version = ">=0.24.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_success_empty/comptime_as_slice/src/main.nr b/test_programs/compile_success_empty/comptime_as_slice/src/main.nr new file mode 100644 index 00000000000..07c5e344cc2 --- /dev/null +++ b/test_programs/compile_success_empty/comptime_as_slice/src/main.nr @@ -0,0 +1,9 @@ +fn main() { + comptime + { + let ws: [Field; 3] = [1; 3]; + let ws_as_slice: [Field] = ws.as_slice(); + + assert_eq(ws[0], ws_as_slice[0]); + } +}