HIR
Typed tree lowering, binding ids, desugaring, closure captures, and why HIR exists.
Purpose
HIR removes reader-friendly surface syntax before the compiler starts doing backend work.
HIR is still a tree, but it is a typed tree with stable binding identities and less syntactic sugar. That makes it the right layer for semantic normalization before MIR turns control flow into blocks.
- Every expression carries a type.
- Local uses point to binding ids instead of names.
- Surface sugar is converted into smaller core forms.
- Closure captures are explicit.
Binding ids
Names are resolved once, then later passes use ids instead of redoing scope lookup.
- Each parameter, let binding, closure parameter, and pattern binding receives an id.
- Shadowing becomes harmless because two bindings with the same spelling still have different ids.
- Global names and builtins can stay name-based where they are not local bindings.
Desugarings
HIR makes convenient syntax explicit before MIR sees it.
- F-strings become format primitives and concatenation.
??and?.become matches over absence.?becomes a match with early return.- Compound assignment becomes an ordinary assignment.
while letbecomes a loop containing a match.
Closure captures
Closures list what they capture and whether each capture is by reference or by value.
Capture analysis is id-based, so nested scopes and shadowing do not require later passes to reason about names. A non-move closure captures by reference; a move closure captures owned values by value.