From c0e2c095356142342cdd20553b4beb7cd818fa87 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Fri, 14 Feb 2025 15:14:42 -0300 Subject: [PATCH] chore: box `Closure` in `comptime::Value` enum --- .../src/hir/comptime/interpreter.rs | 25 ++++++++++++------- .../noirc_frontend/src/hir/comptime/value.rs | 17 +++++++++---- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 5f001192dac..1096835ae5e 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -42,7 +42,7 @@ use crate::{ }; use super::errors::{IResult, InterpreterError}; -use super::value::{unwrap_rc, Value}; +use super::value::{unwrap_rc, Closure, Value}; mod builtin; mod foreign; @@ -264,7 +264,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn call_closure( &mut self, - closure: HirLambda, + lambda: HirLambda, environment: Vec, arguments: Vec<(Value, Location)>, function_scope: Option, @@ -275,7 +275,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { let old_module = self.elaborator.replace_module(module_scope); let old_function = std::mem::replace(&mut self.current_function, function_scope); - let result = self.call_closure_inner(closure, environment, arguments, call_location); + let result = self.call_closure_inner(lambda, environment, arguments, call_location); self.current_function = old_function; self.elaborator.replace_module(old_module); @@ -1359,9 +1359,14 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { } Ok(result) } - Value::Closure(closure, env, _, function_scope, module_scope) => { - self.call_closure(closure, env, arguments, function_scope, module_scope, location) - } + Value::Closure(closure) => self.call_closure( + closure.lambda, + closure.env, + arguments, + closure.function_scope, + closure.module_scope, + location, + ), value => { let typ = value.get_type().into_owned(); Err(InterpreterError::NonFunctionCalled { typ, location }) @@ -1544,12 +1549,14 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn evaluate_lambda(&mut self, lambda: HirLambda, id: ExprId) -> IResult { let location = self.elaborator.interner.expr_location(&id); - let environment = + let env = try_vecmap(&lambda.captures, |capture| self.lookup_id(capture.ident.id, location))?; let typ = self.elaborator.interner.id_type(id).follow_bindings(); - let module = self.elaborator.module_id(); - Ok(Value::Closure(lambda, environment, typ, self.current_function, module)) + let module_scope = self.elaborator.module_id(); + let closure = + Closure { lambda, env, typ, function_scope: self.current_function, module_scope }; + Ok(Value::Closure(Box::new(closure))) } fn evaluate_quote(&mut self, mut tokens: Tokens, expr_id: ExprId) -> IResult { diff --git a/compiler/noirc_frontend/src/hir/comptime/value.rs b/compiler/noirc_frontend/src/hir/comptime/value.rs index 7b85861cb7b..f947cd761fc 100644 --- a/compiler/noirc_frontend/src/hir/comptime/value.rs +++ b/compiler/noirc_frontend/src/hir/comptime/value.rs @@ -51,7 +51,7 @@ pub enum Value { // Closures also store their original scope (function & module) // in case they use functions such as `Quoted::as_type` which require them. - Closure(HirLambda, Vec, Type, Option, ModuleId), + Closure(Box), Tuple(Vec), Struct(HashMap, Value>, Type), @@ -76,6 +76,15 @@ pub enum Value { UnresolvedType(UnresolvedTypeData), } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Closure { + pub lambda: HirLambda, + pub env: Vec, + pub typ: Type, + pub function_scope: Option, + pub module_scope: ModuleId, +} + #[derive(Debug, Clone, PartialEq, Eq, Display)] pub enum ExprValue { Expression(ExpressionKind), @@ -127,7 +136,7 @@ impl Value { } Value::FormatString(_, typ) => return Cow::Borrowed(typ), Value::Function(_, typ, _) => return Cow::Borrowed(typ), - Value::Closure(_, _, typ, ..) => return Cow::Borrowed(typ), + Value::Closure(closure) => return Cow::Borrowed(&closure.typ), Value::Tuple(fields) => { Type::Tuple(vecmap(fields, |field| field.get_type().into_owned())) } @@ -456,9 +465,7 @@ impl Value { Value::Pointer(element, true) => { return element.unwrap_or_clone().into_hir_expression(interner, location); } - Value::Closure(hir_lambda, _args, _typ, _opt_func_id, _module_id) => { - HirExpression::Lambda(hir_lambda) - } + Value::Closure(closure) => HirExpression::Lambda(closure.lambda.clone()), Value::TypedExpr(TypedExpr::StmtId(..)) | Value::Expr(..) | Value::Pointer(..)