rustc
By the Rust Project
rustc is the official compiler for the Rust programming language, translating Rust source code into optimized native machine code for a target platform. It performs borrow checking and type inference to enforce Rust's memory-safety…
Definition
rustc is the official compiler for the Rust programming language, translating Rust source code into optimized native machine code for a target platform. It performs borrow checking and type inference to enforce Rust's memory-safety guarantees entirely at compile time, then lowers the verified program through several intermediate representations before handing it to the LLVM backend for optimization and final code generation.
Overview
rustc exists to turn Rust source into an executable while enforcing the language's central promise: memory safety without a garbage collector, verified entirely at compile time. Most of what makes Rust distinctive as a language lives inside this compiler rather than at run time, which is why rustc's compilation process is heavier and more analysis-driven than compilers for languages that defer safety checks to a runtime. Internally, rustc processes a program through several stages and intermediate representations. Source text is parsed into an abstract syntax tree, then lowered to the High-level Intermediate Representation (HIR) for type checking and trait resolution, and further lowered to the Mid-level Intermediate Representation (MIR), which is where the borrow checker runs. The borrow checker analyzes MIR to verify that references never outlive the data they point to and that mutable and immutable borrows never overlap, catching entire classes of use-after-free and data-race bugs before the program ever runs. Only after these checks pass does rustc lower MIR further and hand the result to LLVM, which performs the low-level optimization and machine-code generation, the same backend used by Clang for C and C++. Because rustc leans on LLVM for code generation, its final output is comparable in performance to optimized C and C++, which places Rust in a different category from garbage-collected languages like Go or Java that trade some raw performance and determinism for a simpler runtime. Where rustc differs sharply from those compilers is in how much work happens before code generation: type inference, trait resolution, and especially borrow checking add compile-time cost in exchange for eliminating a category of bugs those other languages catch only at run time or not at all. Developers rarely invoke rustc directly; in practice it is called by Cargo, which supplies the correct include paths, dependency artifacts, and optimization flags for debug or release builds. Compiler diagnostics are a distinguishing feature of rustc: error messages are designed to explain not just what rule was violated but why, often suggesting a specific code change, which is frequently cited as easing Rust's otherwise steep learning curve around ownership and borrowing. The principal trade-off is compile time: the extra analysis passes, together with LLVM's optimization pipeline and Rust's heavy use of generics (which are monomorphized into separate code per concrete type), make full release builds of large Rust codebases noticeably slower to compile than equivalent C or Go builds. Incremental compilation and Cargo's build caching mitigate this for iterative development, but large dependency trees and generic-heavy code remain a known pain point, and alternative or experimental backends (such as a Cranelift-based backend for faster debug builds) exist specifically to address it.
Key Features
- Performs compile-time borrow checking to enforce memory safety without a GC
- Lowers source through AST, HIR, and MIR intermediate representations
- Uses LLVM as its backend for optimization and native code generation
- Provides detailed, suggestion-driven compiler diagnostics for common errors
- Monomorphizes generics into specialized code per concrete type
- Supports incremental compilation to speed up iterative development
- Targets multiple platforms and architectures through LLVM's backend support
- Integrates with Cargo, which supplies build configuration and dependencies