Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Rust handles generic code before LLVM sees it: rustc identifies the concrete generic instances the program needs, then translates those instances into code-generation intermediate representation. With the usual LLVM backend, that representation is LLVM IR. LLVM optimizes the IR and emits object code; it does not perform Rust’s monomorphization.
Where monomorphization fits in the compiler pipeline
This is a high-level model of the path to machine code, not a complete map of rustc’s query and correctness flow. Compiler work such as borrow checking and query dependencies does not fit neatly into one linear sequence. The Rust Compiler Development Guide’s compiler overview describes the broader architecture.
- Rust source becomes compiler representations. rustc builds MIR (Mid-level Intermediate Representation) from HIR. MIR is used for borrow checking, optimization, and code generation.
- rustc analyzes and optimizes MIR. Relevant MIR optimizations happen before code generation. At this stage, generic MIR has not yet been monomorphized, so applicable simplifications can benefit more than one eventual instance.
- rustc collects required codegen items. The monomorphization collector identifies the concrete items for which the program needs generated code, then partitions them into codegen units.
- rustc lowers instances for the backend. As MIR is translated for code generation, rustc substitutes concrete generic arguments and produces codegen IR. For the LLVM backend, this is LLVM IR.
- The backend and linker finish the build. LLVM optimizes LLVM IR and emits object code. The linker combines object files and any relevant metadata into the requested output. Depending on the link-time optimization configuration, some optimization can also happen during linking.
The code generation guide explains the codegen side of this flow, including the relationship between codegen units, LLVM, and linking.
Collection is not the same as concrete translation
It is useful to distinguish two related steps. First, the collector works at the MIR level and builds a list of the concrete items that need code generation. Then, as MIR lowering proceeds, rustc actually translates those items with their specific types and generic arguments. Monomorphization is therefore not best understood as one isolated pass that expands every generic function before LLVM starts.
#1 Best Overall
For example, if main calls banana, and banana calls peach::<u64>, the collector identifies main, banana, and peach::<u64> as items requiring machine code. The relevant generic instance is the one used by the program; rustc does not need to generate code for every imaginable type that could be substituted for peach. The monomorphization guide describes this collection and translation process.
What changes from generic MIR to LLVM IR
| Stage | What it represents | What happens next |
|---|---|---|
| Generic MIR | A Rust function or item expressed with generic parameters, before concrete instances are translated for code generation. | MIR analysis and applicable optimizations; the collector determines which concrete items are needed. |
| Collected mono items | The specific functions and other codegen items needed by the program, including generic items paired with concrete substitutions. | Partitioning into codegen units and lowering for code generation. |
| LLVM IR | Low-level codegen representation for the LLVM backend, with types and annotations that enable optimization and machine-code generation. | LLVM optimization and object-file emission, followed by linking. |
The first two rows describe rustc’s decisions about Rust code; the last is the backend-facing representation. This distinction explains why “LLVM monomorphizes Rust generics” is misleading: LLVM receives already-lowered, concrete instances as IR rather than Rust’s generic MIR.
Rank #2
Why optimize generic MIR before generating instances?
MIR optimization and monomorphization do different jobs. MIR optimization simplifies code before concrete instances are generated. Monomorphization supplies specific type arguments and creates the concrete codegen items that those arguments require. An applicable simplification to generic MIR can reduce work across the resulting instances, though not every optimization applies identically to every one.
Specializing code for concrete types can support fast execution, but generating many instances can increase compile time and binary size. The compiler guide describes these as trade-offs qualitatively; there is no single numeric cost that applies to every program.
Rank #3
Codegen units are build organization, not monomorphization
After rustc identifies the required items, it partitions them into codegen units. These units organize code generation and can let the compiler generate code in parallel; they are not another name for generic specialization. The codegen guide also discusses the partitioner in relation to incremental builds.
For the LLVM backend, codegen units are modules LLVM can process, potentially in parallel, before their object files are passed to the linker. Link-time optimization can change where some optimization work occurs, so the exact division between code generation and linking depends on the build configuration.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.LLVM is the usual backend, not the only one
LLVM is the backend in the pipeline described above, but rustc also supports Cranelift and GCC backends. The Rust-side work of identifying and translating concrete instances comes before the selected backend performs its work. The backend determines what happens to the resulting representation; LLVM-specific details such as LLVM IR apply when LLVM is selected.
The Rust Compiler Development Guide is living documentation, and compiler implementation details can change. The architectural distinction remains useful: rustc collects needed instances before lowering, concrete translation happens as code generation proceeds, and the selected backend operates on the lowered representation.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteQuick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




