Rust
// Write idiomatic Rust avoiding ownership pitfalls, lifetime confusion, and common borrow checker battles.
$ git log --oneline --stat
stars:1,933
forks:367
updated:March 4, 2026
SKILL.mdreadonly
SKILL.md Frontmatter
nameRust
slugrust
version1.0.1
descriptionWrite idiomatic Rust avoiding ownership pitfalls, lifetime confusion, and common borrow checker battles.
metadata[object Object]
Quick Reference
| Topic | File | Key Trap |
|---|---|---|
| Ownership & Borrowing | ownership-borrowing.md | Move semantics catch everyone |
| Strings & Types | types-strings.md | String vs &str, UTF-8 indexing |
| Errors & Iteration | errors-iteration.md | unwrap() in production, lazy iterators |
| Concurrency & Memory | concurrency-memory.md | Rc not Send, RefCell panics |
| Advanced Traps | advanced-traps.md | unsafe, macros, FFI, performance |
Critical Traps (High-Frequency Failures)
Ownership — #1 Source of Compiler Errors
- Variable moved after use — clone explicitly or borrow with
& for item in vecmoves vec — use&vecor.iter()to borrowStringmoved into function — pass&strfor read-only access
Borrowing — The Borrow Checker Always Wins
- Can't have
&mutand&simultaneously — restructure or interior mutability - Returning reference to local fails — return owned value instead
- Mutable borrow through
&mut selfblocks all access — split struct orRefCell
Lifetimes — When Compiler Can't Infer
'staticmeans CAN live forever, not DOES —Stringis 'static capable- Struct with reference needs
<'a>—struct Foo<'a> { bar: &'a str } - Function returning ref must tie to input —
fn get<'a>(s: &'a str) -> &'a str
Strings — UTF-8 Surprises
s[0]doesn't compile — use.chars().nth(0)or.bytes().len()returns bytes, not chars — use.chars().count()s1 + &s2moves s1 — useformat!("{}{}", s1, s2)to keep both
Error Handling — Production Code
unwrap()panics — use?ormatchin production?needsResult/Optionreturn type — main needs-> Result<()>expect("context")>unwrap()— shows why it panicked
Iterators — Lazy Evaluation
.iter()borrows,.into_iter()moves — choose carefully.collect()needs type —collect::<Vec<_>>()or typed binding- Iterators are lazy — nothing runs until consumed
Concurrency — Thread Safety
Rcis NOTSend— useArcfor threadsMutexlock returns guard — auto-unlocks on drop, don't hold across awaitRwLockdeadlock — reader upgrading to writer blocks forever
Memory — Smart Pointers
RefCellpanics at runtime — if borrow rules violatedBoxfor recursive types — compiler needs known size- Avoid
Rc<RefCell<T>>spaghetti — rethink ownership
Common Compiler Errors (NEW)
| Error | Cause | Fix |
|---|---|---|
value moved here | Used after move | Clone or borrow |
cannot borrow as mutable | Already borrowed | Restructure or RefCell |
missing lifetime specifier | Ambiguous reference | Add <'a> |
the trait bound X is not satisfied | Missing impl | Check trait bounds |
type annotations needed | Can't infer | Turbofish or explicit type |
cannot move out of borrowed content | Deref moves | Clone or pattern match |
Cargo Traps (NEW)
cargo updateupdates Cargo.lock, not Cargo.toml — manual version bump needed- Features are additive — can't disable a feature a dependency enables
[dev-dependencies]not in release binary — but in tests/examplescargo build --releasemuch faster — debug builds are slow intentionally