Refactor recursion checking

Introduces a `UsageInfo` struct to consolidate tracking of used and
assigned locals, globals, and identities.

Replaces multiple `HashSet` arguments in `collect_usage` with a single
`UsageInfo` struct.

Adds an `is_recursive` method to check for recursive calls within a
node, considering global indices, local slots, and identity.

Updates inlining logic to use `is_recursive` to prevent inlining of
recursive functions or closures. This includes:
- Checking for recursion when inlining a call to a lambda.
- Checking for recursion when inlining a global variable that is a
  lambda.
- Checking for recursion when inlining a closure.

Updates `is_inlinable_value` to also check for closure recursion.
This commit is contained in:
Michael Schimmel
2026-02-22 10:41:48 +01:00
parent bd506b1b17
commit 3142e64bbd
2 changed files with 135 additions and 213 deletions
@@ -1,12 +1,13 @@
---
source: src/ast/compiler/optimizer.rs
assertion_line: 727
assertion_line: 1333
expression: dump
---
Lambda (Upvalues: 0) <Metadata: Metadata { ty: Function(Signature { params: Tuple([]), ret: Function(Signature { params: Tuple([]), ret: Int }) }), is_tail: true }>
Parameters:
Tuple <Metadata: Metadata { ty: Tuple([]), is_tail: false }>
Lambda (Upvalues: 0) <Metadata: Metadata { ty: Function(Signature { params: Tuple([]), ret: Int }), is_tail: true }>
Lambda (Upvalues: 1) <Metadata: Metadata { ty: Function(Signature { params: Tuple([]), ret: Int }), is_tail: true }>
Parameters:
Tuple <Metadata: Metadata { ty: Tuple([]), is_tail: false }>
Constant: 10 <Metadata: Metadata { ty: Int, is_tail: true }>
Upvalues: [Local(0)]
Get: x (Upvalue(0)) <Metadata: Metadata { ty: Int, is_tail: true }>