Refactor: Use Value::Closure enum variant

Previously, compiled closures were stored as `Value::Object` and then
downcasted. This commit introduces a dedicated `Value::Closure` enum
variant to represent compiled closures. This improves type safety and
simplifies handling of closures throughout the compiler and VM.

This change involves:
- Updating type definitions to use `Value::Closure`.
- Adjusting downcasting logic to directly access the `Closure` struct.
- Modifying `run_with_args` and `run_with_args_observed` to expect
  `Value::Closure` for tail-call targets.
- Refining the handling of closures in the `Optimizer` and `Inliner` for
  better type clarity.
This commit is contained in:
2026-03-22 19:41:23 +01:00
parent 6c37b0c64f
commit 843ee7dfed
7 changed files with 134 additions and 141 deletions
+3 -3
View File
@@ -3,7 +3,7 @@ use crate::ast::nodes::{
IdentifierBinding, LambdaBinding, Node, NodeKind, UpvalueIdx, VirtualId,
};
use crate::ast::types::{Purity, Value};
use crate::ast::closure::Closure;
use std::cell::RefCell;
use std::rc::Rc;
@@ -343,9 +343,9 @@ impl Optimizer {
}
}
if let NodeKind::Constant(Value::Object(ref obj)) = callee_opt.kind
if let NodeKind::Constant(Value::Closure(ref closure_rc)) = callee_opt.kind
&& path.inlining_depth < 5
&& let Some(closure) = obj.as_any().downcast_ref::<Closure>()
&& let closure = closure_rc.as_ref()
&& (closure.upvalues.is_empty()
|| closure.function_node.ty.purity >= Purity::SideEffectFree)
&& !closure.function_node.ty.is_recursive
+3 -7
View File
@@ -2,7 +2,7 @@ use crate::ast::nodes::{
Address, AnalyzedNode, IdentifierBinding, NodeKind, VirtualId,
};
use crate::ast::types::{Purity, Value};
use crate::ast::closure::Closure;
use std::cell::RefCell;
use std::collections::HashSet;
use std::rc::Rc;
@@ -35,12 +35,8 @@ impl<'a> Inliner<'a> {
| Value::Keyword(_)
| Value::Record(_, _)
| Value::DateTime(_) => true,
Value::Object(obj) => {
if let Some(closure) = obj.as_any().downcast_ref::<Closure>() {
closure.upvalues.is_empty() && !closure.function_node.ty.is_recursive
} else {
false
}
Value::Closure(closure_rc) => {
closure_rc.upvalues.is_empty() && !closure_rc.function_node.ty.is_recursive
}
_ => false,
};
+4 -6
View File
@@ -3,7 +3,7 @@ use crate::ast::nodes::{
NodeKind, VirtualId,
};
use crate::ast::types::{Identity, Value};
use crate::ast::closure::Closure;
use std::collections::HashSet;
// --- PathTracker ---
@@ -56,12 +56,10 @@ impl UsageInfo {
self.collect(value);
}
NodeKind::Constant(v) => {
if let Value::Object(obj) = v
&& let Some(closure) = obj.as_any().downcast_ref::<Closure>()
{
if let Value::Closure(closure_rc) = v {
self.used_identities
.insert(closure.function_node.identity.clone());
self.collect(&closure.function_node);
.insert(closure_rc.function_node.identity.clone());
self.collect(&closure_rc.function_node);
}
}
NodeKind::Identifier { binding, .. } => {