rustc walkthrough

NOTE: the compiler is in a transition from being pass-based (sequential) to being query-based (on-demand).

steps

Assumes we are doing a normal build, which means taking Rust source code and transforming it into binary format (i.e. something a CPU will understand)

  1. process compiler flags, of which there's plenty

  2. lexing source code (converts Unicode characters into tokens)

  3. parsing (turns tokens into an AST)

  4. macro expansion and code elimination (i.e. cfg processing)

  5. lower to HIR (includes sugar removal)

    note: query-based compilation begins here

  6. type inference and type checking

  7. lower to MIR (a far more simple version of "rust" which is suitable for borrow checking)

  8. borrow checking (what makes Rust you-neek)

    Examples of what happens at this stage:

    • bindings can't be used uninitialised
    • values can't be accessed once moved
    • values can't be moved while still borrowed
    • values can't be accessed while still mutably borrowed
  9. some optimization happens, to reduce the input to the next stage, which helps with build times

  10. convert to LLVM IR

    Generics are expanded here (monomorphization)

  11. (optional) optimize

  12. convert to machine code (binary)

  13. (in case of executables) linking

more info