Expand description
Expression resolution - transforms name references into indexed lookups.
Each expression variant is handled in Resolver::resolve_expression:
Identifier->ResolvedIdentifier { depth, slot }if found in scope, left asIdentifierif not (stdlib names, unresolved at this stage)Assign->ResolvedAssign { depth, slot, value }Lambda->ResolvedLambda { capture_depth, ... }with a fresh scope for its parameters;capture_depthis the scope stack length at the point of definition, used by the evaluator to capture the environmentCallwith a single-segment path ->CallExprwith aResolvedIdentifiercallee if the name is in scope; left asCallfor stdlib paths- All other variants recurse into their sub-expressions unchanged
All resolution mutates nodes in place via ExprId + Arena::get_mut.
The node’s ExprId never changes - only its kind does. Child ExprIds
embedded in a parent’s kind stay valid across the rewrite since resolving
a child mutates the arena slot it already occupies, not its address.