/rustc-basics
Rust compiler skill for systems programming. Use when selecting RUSTFLAGS, configuring Cargo profiles, tuning release builds, reading assembly or MIR output, understanding monomorphization, or diagnosing compilation errors. Activates on queries about rustc flags, Cargo.toml
$ npx -y skills add mohitmishra786/low-level-dev-skills --skill rustc-basics --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/rustc-basics
Context preview
The summary Claude sees to decide when to auto-load this skill.
Rust compiler skill for systems programming. Use when selecting RUSTFLAGS, configuring Cargo profiles, tuning release builds, reading assembly or MIR output, understanding monomorphization, or diagnosing compilation errors. Activates on queries about rustc flags, Cargo.toml
SKILL.md
rustc-basics.SKILL.mdname: rustc-basics
description: Rust compiler skill for systems programming. Use when selecting RUSTFLAGS, configuring Cargo profiles, tuning release builds, reading assembly or MIR output, understanding monomorphization, or diagnosing compilation errors. Activates on queries about rustc flags, Cargo.toml profiles, opt-level, LTO, codegen-units, target-cpu, emit asm, MIR, or Rust build performance.
rustc Basics
Purpose
Guide agents through Rust compiler invocation: RUSTFLAGS, Cargo profile configuration, build modes, MIR and assembly inspection, monomorphization, and common compilation error patterns.
Triggers
- "How do I configure a release build in Rust for maximum performance?"
- "How do I see the assembly output for a Rust function?"
- "What is monomorphization and why is it making my compile slow?"
- "How do I enable LTO in Rust?"
- "My Rust binary is too large — how do I shrink it?"
- "How do I read Rust MIR output?"
Workflow
1. Choose a build mode
# Debug (default) — fast compile, no optimization, debug info
cargo build
# Release — optimized, no debug info by default
cargo build --release
# Check only (fastest, no codegen)
cargo check
# Build for specific target
cargo build --release --target aarch64-unknown-linux-gnu
2. Cargo.toml profile configuration
[profile.release]
opt-level = 3 # 0-3, "s" (size), "z" (aggressive size)
debug = false # true = full, 1 = line tables only, 0 = none
lto = "thin" # false | "thin" | true (fat LTO)
codegen-units = 1 # 1 = max optimization, higher = faster compile
panic = "abort" # "unwind" (default) | "abort" (smaller binary)
strip = "symbols" # "none" | "debuginfo" | "symbols"
overflow-checks = false # default true in debug, false in release
[profile.release-with-debug]
inherits = "release"
debug = true # release build with debug symbols
strip = "none"
[profile.dev]
opt-level = 1 # Speed up debug builds slightly
| Setting | Impact | |---------|--------| | `lto = true` (fat) | Best optimization, slowest link | | `lto = "thin"` | Good optimization, parallel link | | `codegen-units = 1` | Best inlining, slower compile | | `panic = "abort"` | Removes unwind tables, smaller binary | | `opt-level = "z"` | Aggressive size reduction |
3. RUSTFLAGS
# Set for a single build
RUSTFLAGS="-C target-cpu=native" cargo build --release
# Enable all target CPU features
RUSTFLAGS="-C target-cpu=native -C target-feature=+avx2,+bmi2" cargo build --release
# Control codegen at invocation level
RUSTFLAGS="-C opt-level=3 -C codegen-units=1 -C lto=on" cargo build --release
Persistent in `.cargo/config.toml`:
[build]
rustflags = ["-C", "target-cpu=native"]
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "target-cpu=native", "-C", "link-arg=-fuse-ld=lld"]
4. Inspect assembly output
# Using cargo-show-asm (recommended)
cargo install cargo-show-asm
cargo asm --release 'myapp::module::function_name'
# Using rustc directly
rustc --emit=asm -C opt-level=3 -C target-cpu=native src/lib.rs
cat lib.s
# View MIR (mid-level IR, before codegen)
rustc --emit=mir -C opt-level=3 src/lib.rs
cat lib.mir
# View LLVM IR
rustc --emit=llvm-ir -C opt-level=3 src/lib.rs
cat lib.ll
# Use Compiler Explorer (Godbolt) patterns locally
RUSTFLAGS="--emit=asm" cargo build --release
find target/ -name "*.s"
5. Understand monomorphization
Rust generics are monomorphized — each concrete type instantiation produces separate code. This causes:
- Binary size bloat
- Longer compile times
- Potential i-cache pressure
# Measure monomorphization bloat
cargo install cargo-llvm-lines
cargo llvm-lines --release | head -30
# Shows: lines of LLVM IR per function (monomorphized copies visible)
Mitigation strategies:
// 1. Type erasure with dyn Trait (trades monomorphization for dispatch)
fn process(iter: &mut dyn Iterator<Item = i32>) { ... }
// 2. Non-generic inner function pattern
fn my_generic<T: AsRef<str>>(s: T) {
fn inner(s: &str) { /* actual work */ }
inner(s.as_ref()) // monomorphization only in thin wrapper
}6. Binary size reduction
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = "symbols"
# Check binary size breakdown
cargo install cargo-bloat
cargo bloat --release --crates # per-crate size
cargo bloat --release -n 20 # top 20 largest functions
# Compress executable (at cost of startup time)
upx --best --lzma target/release/myapp
7. Common error triage
| Error | Cause | Fix | |-------|-------|-----| | `cannot find function in this scope` | Missing `use` or wrong module path | Add `use crate::module::fn_name` | | `the trait X is not implemented for Y` | Missing impl or wrong generic bound | Implement trait or adjust bounds | | `lifetime may not live long enough` | Borrow checker lifetime issue | Add explicit lifetime annotations | | `cannot borrow as mutable because also borrowed as immutable` | Aliasing violation | Restructure borrows to not overlap | | `use of moved value` | Value used after `move` into closure or function | Use `.clone()` or borrow instead | | `mismatched types: expected &str found String` | String vs &str confusion | Use `.as_str()` or `&my_string` |
8. Useful rustc flags
# Show all enabled features at a given opt level
rustc -C opt-level=3 --print cfg
# List available targets
rustc --print target-list
# Show target-specific features
rustc --print target-features --target x86_64-unknown-linux-gnu
# Explain an error code
rustc --explain E0382
For RUSTFLAGS reference and Cargo profile patterns, see [references/rustflags-profiles.md](references/rustflags-profiles.md).
Related skills
- Use `skills/rust/cargo-workflows` for workspace management and Cargo tooling
- Use `skills/rust/rust-debugging` for debugging Rust binaries with GDB/LLDB
- Use `skill
Read more
name: rustc-basics description: Rust compiler skill for systems programming. Use when selecting RUSTFLAGS, configuring Cargo profiles, tuning release builds, reading assembly or MIR output, understanding monomorphization, or diagnosing compilation errors. Activates on queries about rustc flags, Cargo.toml profiles, opt-level, LTO, codegen-units, target-cpu, emit asm, MIR, or Rust build performance.
rustc Basics
Purpose
Guide agents through Rust compiler invocation: RUSTFLAGS, Cargo profile configuration, build modes, MIR and assembly inspection, monomorphization, and common compilation error patterns.
Triggers
- "How do I configure a release build in Rust for maximum performance?"
- "How do I see the assembly output for a Rust function?"
- "What is monomorphization and why is it making my compile slow?"
- "How do I enable LTO in Rust?"
- "My Rust binary is too large — how do I shrink it?"
- "How do I read Rust MIR output?"
Workflow
1. Choose a build mode
# Debug (default) — fast compile, no optimization, debug info cargo build # Release — optimized, no debug info by default cargo build --release # Check only (fastest, no codegen) cargo check # Build for specific target cargo build --release --target aarch64-unknown-linux-gnu
2. Cargo.toml profile configuration
[profile.release] opt-level = 3 # 0-3, "s" (size), "z" (aggressive size) debug = false # true = full, 1 = line tables only, 0 = none lto = "thin" # false | "thin" | true (fat LTO) codegen-units = 1 # 1 = max optimization, higher = faster compile panic = "abort" # "unwind" (default) | "abort" (smaller binary) strip = "symbols" # "none" | "debuginfo" | "symbols" overflow-checks = false # default true in debug, false in release [profile.release-with-debug] inherits = "release" debug = true # release build with debug symbols strip = "none" [profile.dev] opt-level = 1 # Speed up debug builds slightly
| Setting | Impact | |---------|--------| | `lto = true` (fat) | Best optimization, slowest link | | `lto = "thin"` | Good optimization, parallel link | | `codegen-units = 1` | Best inlining, slower compile | | `panic = "abort"` | Removes unwind tables, smaller binary | | `opt-level = "z"` | Aggressive size reduction |
3. RUSTFLAGS
# Set for a single build RUSTFLAGS="-C target-cpu=native" cargo build --release # Enable all target CPU features RUSTFLAGS="-C target-cpu=native -C target-feature=+avx2,+bmi2" cargo build --release # Control codegen at invocation level RUSTFLAGS="-C opt-level=3 -C codegen-units=1 -C lto=on" cargo build --release
Persistent in `.cargo/config.toml`:
[build] rustflags = ["-C", "target-cpu=native"] [target.x86_64-unknown-linux-gnu] rustflags = ["-C", "target-cpu=native", "-C", "link-arg=-fuse-ld=lld"]
4. Inspect assembly output
# Using cargo-show-asm (recommended) cargo install cargo-show-asm cargo asm --release 'myapp::module::function_name' # Using rustc directly rustc --emit=asm -C opt-level=3 -C target-cpu=native src/lib.rs cat lib.s # View MIR (mid-level IR, before codegen) rustc --emit=mir -C opt-level=3 src/lib.rs cat lib.mir # View LLVM IR rustc --emit=llvm-ir -C opt-level=3 src/lib.rs cat lib.ll # Use Compiler Explorer (Godbolt) patterns locally RUSTFLAGS="--emit=asm" cargo build --release find target/ -name "*.s"
5. Understand monomorphization
Rust generics are monomorphized — each concrete type instantiation produces separate code. This causes:
- Binary size bloat
- Longer compile times
- Potential i-cache pressure
# Measure monomorphization bloat cargo install cargo-llvm-lines cargo llvm-lines --release | head -30 # Shows: lines of LLVM IR per function (monomorphized copies visible)
Mitigation strategies:
// 1. Type erasure with dyn Trait (trades monomorphization for dispatch)
fn process(iter: &mut dyn Iterator<Item = i32>) { ... }
// 2. Non-generic inner function pattern
fn my_generic<T: AsRef<str>>(s: T) {
fn inner(s: &str) { /* actual work */ }
inner(s.as_ref()) // monomorphization only in thin wrapper
}6. Binary size reduction
[profile.release] opt-level = "z" lto = true codegen-units = 1 panic = "abort" strip = "symbols"
# Check binary size breakdown cargo install cargo-bloat cargo bloat --release --crates # per-crate size cargo bloat --release -n 20 # top 20 largest functions # Compress executable (at cost of startup time) upx --best --lzma target/release/myapp
7. Common error triage
| Error | Cause | Fix | |-------|-------|-----| | `cannot find function in this scope` | Missing `use` or wrong module path | Add `use crate::module::fn_name` | | `the trait X is not implemented for Y` | Missing impl or wrong generic bound | Implement trait or adjust bounds | | `lifetime may not live long enough` | Borrow checker lifetime issue | Add explicit lifetime annotations | | `cannot borrow as mutable because also borrowed as immutable` | Aliasing violation | Restructure borrows to not overlap | | `use of moved value` | Value used after `move` into closure or function | Use `.clone()` or borrow instead | | `mismatched types: expected &str found String` | String vs &str confusion | Use `.as_str()` or `&my_string` |
8. Useful rustc flags
# Show all enabled features at a given opt level rustc -C opt-level=3 --print cfg # List available targets rustc --print target-list # Show target-specific features rustc --print target-features --target x86_64-unknown-linux-gnu # Explain an error code rustc --explain E0382
For RUSTFLAGS reference and Cargo profile patterns, see [references/rustflags-profiles.md](references/rustflags-profiles.md).
Related skills
- Use `skills/rust/cargo-workflows` for workspace management and Cargo tooling
- Use `skills/rust/rust-debugging` for debugging Rust binaries with GDB/LLDB
- Use `skill
A curated suite of AI agent skills for systems and low-level programming — C/C++, Rust, Zig, GPU, bare-metal firmware, Linux kernel/driver development, computer architecture, compiler internals, HPC, and more.
Repo: mohitmishra786/low-level-dev-skills
Other skills on low-level-dev-skills.
- /custom-allocators
Custom allocator skill for memory allocation strategies. Use when implementing pool/slab/arena allocators, tuning jemalloc/mimalloc, writing Rust GlobalAlloc, or benchmarking allocator performance. Activates on queries about jemalloc, mimalloc, tcmalloc, arena allocator,
Open skill - /numa-programming
NUMA programming skill for multi-socket memory locality. Use when detecting NUMA topology, binding processes with numactl, using libnuma API, building NUMA-aware data structures, or measuring remote access penalties. Activates on queries about numactl, libnuma, NUMA topology,
Open skill - /af-xdp
AF_XDP skill for high-performance XDP sockets. Use when creating AF_XDP sockets, configuring UMEM and XSK rings, XDP_REDIRECT programs, copy vs zero-copy mode, or comparing with DPDK. Activates on queries about AF_XDP, xsk_umem, XDP_REDIRECT, libbpf xsk, or zero-copy XDP.
Open skill - /dpdk
DPDK skill for userspace packet I/O. Use when initializing EAL, configuring PMD drivers, using mbuf pools and rte_ring, setting up huge pages, RSS, or testpmd validation. Activates on queries about DPDK, EAL, rte_eth_rx_burst, hugepages, PMD, or testpmd.
Open skill - /io-uring
io_uring skill for Linux async I/O. Use when building high-performance servers with liburing, multi-shot operations, provided buffers, fixed files, zero-copy send, or tokio-uring. Activates on queries about io_uring, SQE/CQE, liburing, IORING_OP_PROVIDE_BUFFERS, or io_uring vs
Open skill - /adc-dac-baremetal
Bare-metal ADC and DAC skill. Use when configuring analog sampling, DMA-driven ADC, calibration, or DAC output on MCUs. Activates on queries about ADC bare-metal, sampling time, DMA ADC, or DAC channel setup.
Open skill

