Skip to content
La3 Docs
Browse docs

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 let becomes 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.