frontend 0.5.0

rustc's frontend with no LLVM and no std: parsing through MIR, as a library
# Working agreement: frontend

For any coding agent working here or calling this crate. `CLAUDE.md` imports this file; never
fork these rules into a per-vendor file.

## Rule zero: you are just parsing, and you do not need a standard library

**If you catch yourself writing "no usable standard library exists", or planning to clone
rust-lang/rust, build a sysroot, or search the disk for one, you are off track. Stop.**

This crate is a parser. It reads the source it is handed. `std` is not special and is parsed no
differently from `fmt` or anything else. With no sysroot named, a session runs as `no_core`:
no external crate is loaded, no prelude import is resolved, and no library is needed anywhere
on the machine. That is the default, deliberately.

The reasoning lives in `src/frontend_facts/mod.rs`, at the comment headed "The sysroot is an
optional parameter, because this is a parser", and in commit `b87daf4` ("Stop requiring a
library to read facts out of source"). A sysroot matters only to a caller who has deliberately
asked for paths to be resolved into a compiled library. It is never a blocker to report.

## House rules

- `std` is banned in this crate. Every module is `#![no_std]`; the operating system arrives
  through `ekostd`. The one exception is `src/rustc_data_structures/sync/pool.rs`, compiled only
  with the `parallel` feature, which takes nagoya's pool and `std`'s `catch_unwind` and
  `resume_unwind` from there; nothing else names `std` or `nagoya`.
- frontend creates no threads and owns no pool. A compile runs on the caller's thread. When a
  session asks for parallelism (`jobs.frontend` of two or more, with the `parallel` cargo
  feature, which is off by default) its internal stages (`rustc_data_structures::sync::stages`
  and `run_stage`) also run items on nagoya's pool, whose threads are nagoya's or the embedding
  program's; otherwise every stage runs serially, in order, on the caller's thread. Never call
  `eko::thread::spawn`, `std::thread` or anything else that starts a thread from this crate, and
  never bring back the `par_*` shims: new parallel work is a stage over frozen input.
- No Python. No em dashes. No AI attribution. Never `git stash`. Stage your own paths only,
  with `git commit --only <paths>`.

## Calling this crate from a program: two choices that are yours

Read `README.md`, "Integrating it: allocator and parallelism", before you ship or measure.
In short:

- **Declare mimalloc as your binary's global allocator.** frontend declares none. It is 8% of
  a serial check and 24% with files in parallel.
- **Run files in parallel, each at width 1** (2 to 4 when there are fewer files than workers),
  rather than one file wide. One file is about 45% serial, so its own stages stop paying at
  about width 4, while 200 files on 12 workers run 8.7x faster than one after another.