cargo check
cargo check (aliased as cargo c) runs all of the Rust compiler's validation passes—syntax parsing, macro expansion, type inference, trait resolution, and borrow checking—without spending time generating LLVM machine code or linking an executable binary.
Why cargo check Is Much Faster Than cargo build
In a typical Rust build, generating and optimizing native machine instructions in LLVM and running the system linker (ld / cc) accounts for the majority of total compilation time.
cargo check tells rustc to stop immediately after Mid-Level IR (MIR) borrow checking and emit only lightweight type metadata (.rmeta files) instead of object files (.o) and binaries:
Full `cargo build` Pipeline:
[Parse & Expand] -> [Type Check (HIR)] -> [Borrow Check (MIR)] -> [LLVM Codegen & Opt] -> [System Linker]
|______________________ ~30% of build time __________________| |_________ ~70% of build time _________|
Fast `cargo check` Pipeline:
[Parse & Expand] -> [Type Check (HIR)] -> [Borrow Check (MIR)] -> Writes `.rmeta` (Done!)
Because it skips LLVM codegen and linking completely, cargo check is often 2× to 5× faster than cargo build while catching the exact same syntax, type, trait, and borrow-checker errors!
Basic Usage and Output
While editing code and refactoring types or lifetimes, run cargo check in a tight loop to verify that your project compiles cleanly:
cargo check
Checking my_project v0.1.0 (/Users/username/my_project)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s
Notice that Cargo prints Checking my_project rather than Compiling my_project, and no executable binary is created in target/debug/my_project.
Useful cargo check Flags
By default, cargo check checks only your library (src/lib.rs) and binary (src/main.rs, src/bin/*.rs) targets—it does not check #[test] functions or integration tests in tests/ unless you pass --tests or --all-targets:
| Command | What It Checks |
|---|---|
cargo check (or cargo c) |
Library (src/lib.rs) and binary (src/main.rs, src/bin/) targets |
cargo check --tests |
Also checks unit tests (#[cfg(test)]) and integration tests (tests/*.rs) |
cargo check --examples |
Checks standalone example programs in examples/*.rs |
cargo check --all-targets |
Checks libraries, binaries, unit tests, integration tests, and examples together |
cargo check --workspace |
Checks every package in a multi-crate Cargo workspace |
cargo check --target <triple> |
Type-checks platform-specific #[cfg(target_os = "...")] code for another OS/architecture |
# Verify that both application code AND all unit/integration tests type-check cleanly:
cargo check --all-targets
Rare Errors Caught Only by cargo build, Not cargo check
Because cargo check stops before final monomorphization codegen and linking, a small handful of late-stage errors only surface during cargo build, cargo test, or cargo run:
| Late-Stage Issue | Detected by cargo check? |
Detected by cargo build? |
|---|---|---|
Syntax, type (E0308), trait (E0277), and borrow (E0502) errors |
Yes | Yes |
Const evaluation panics in const items and array lengths (E0080) |
Yes | Yes |
Post-monomorphization const { ... } block errors inside generic functions |
Only when instantiated & codegen'd | Yes |
Missing external C library or unresolved extern "C" linker symbol |
No (linker is skipped) | Yes (linking with cc failed) |
Inline assembly (asm!) register allocation constraints |
Partially | Yes |
Typical Development Loop
In day-to-day Rust development:
- Run
cargo check --all-targets(or letrust-analyzerruncargo checkautomatically in the background on every file save) while iterating on code structure and fixing compiler errors. - Run
cargo testorcargo runoncecargo checksucceeds with zero errors and you are ready to execute the program.