Refactor AST substitution logic

This commit refactors the AST substitution logic to correctly handle
nested expansions and improve the inlining of lambda expressions.

The changes include:
- Extracting the core value from potentially expanded AST nodes before
  checking their kind.
- Ensuring that lambda expressions with empty upvalues are correctly
  substituted.
- Adding support for inlining global get expressions as AST
  substitutions.
- Improving the `UsageInfo` collection to correctly track assigned
  values.
This commit is contained in:
Michael Schimmel
2026-03-13 19:51:56 +01:00
parent e5d82ee2b6
commit 0dfcfac7b3
3 changed files with 41 additions and 17 deletions
+10 -5
View File
@@ -112,18 +112,23 @@ impl<'a> Inliner<'a> {
if let Some(arg) = args.get(*offset)
&& !body_usage.is_assigned(addr)
{
if let BoundKind::Constant(val) = &arg.kind {
let mut core_arg = arg.as_ref();
while let BoundKind::Expansion { bound_expanded, .. } = &core_arg.kind {
core_arg = bound_expanded.as_ref();
}
if let BoundKind::Constant(val) = &core_arg.kind {
sub.add_value(*addr, val.clone());
} else if let BoundKind::Lambda { upvalues, .. } = &arg.kind
} else if let BoundKind::Lambda { upvalues, .. } = &core_arg.kind
&& upvalues.is_empty()
{
sub.add_ast_substitution(*addr, (**arg).clone());
sub.add_ast_substitution(*addr, core_arg.clone());
} else if let BoundKind::Get {
addr: Address::Global(_),
..
} = &arg.kind
} = &core_arg.kind
{
sub.add_ast_substitution(*addr, (**arg).clone());
sub.add_ast_substitution(*addr, core_arg.clone());
}
}