From 966be8ed4095b3316f392aa724de0127dd3828d4 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Mon, 5 Aug 2024 13:06:22 -0500 Subject: [PATCH] Comptime closures --- .../src/hir/comptime/interpreter.rs | 7 +++- .../comptime_closures/Nargo.toml | 7 ++++ .../comptime_closures/src/main.nr | 39 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test_programs/compile_success_empty/comptime_closures/Nargo.toml create mode 100644 test_programs/compile_success_empty/comptime_closures/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 0bb53432b78..72b92e288c7 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -226,8 +226,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn call_closure( &mut self, closure: HirLambda, - // TODO: How to define environment here? - _environment: Vec, + environment: Vec, arguments: Vec<(Value, Location)>, call_location: Location, ) -> IResult { @@ -246,6 +245,10 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { self.define_pattern(parameter, typ, argument, arg_location)?; } + for (param, arg) in closure.captures.into_iter().zip(environment) { + self.define(param.ident.id, arg); + } + let result = self.evaluate(closure.body)?; self.exit_function(previous_state); diff --git a/test_programs/compile_success_empty/comptime_closures/Nargo.toml b/test_programs/compile_success_empty/comptime_closures/Nargo.toml new file mode 100644 index 00000000000..50cde2ec2dd --- /dev/null +++ b/test_programs/compile_success_empty/comptime_closures/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "comptime_closures" +type = "bin" +authors = [""] +compiler_version = ">=0.32.0" + +[dependencies] diff --git a/test_programs/compile_success_empty/comptime_closures/src/main.nr b/test_programs/compile_success_empty/comptime_closures/src/main.nr new file mode 100644 index 00000000000..95f602e04bf --- /dev/null +++ b/test_programs/compile_success_empty/comptime_closures/src/main.nr @@ -0,0 +1,39 @@ +fn main() { + comptime + { + closure_test(0); + } +} + +fn closure_test(mut x: Field) { + let one = 1; + let add1 = |z| { + (|| { + *z += one; + })() + }; + + let two = 2; + let add2 = |z| { + *z = *z + two; + }; + + add1(&mut x); + assert(x == 1); + + add2(&mut x); + assert(x == 3); + + issue_2120(); +} + +fn issue_2120() { + let x1 = &mut 42; + let set_x1 = |y| { *x1 = y; }; + + assert(*x1 == 42); + set_x1(44); + assert(*x1 == 44); + set_x1(*x1); + assert(*x1 == 44); +}