rust-anti-patterns
Identifies and fixes common Rust anti-patterns. Use during code review, when seeing excessive clones/unwraps/index loops, or when code fights the borrow checker instead of working with it.
rust-anti-patterns
Metadata
- Config Path
- License
- License Source
Description
Identifies and fixes common Rust anti-patterns. Use during code review, when seeing excessive clones/unwraps/index loops, or when code fights the borrow checker instead of working with it.
Source
- Docs Path
- Original Source
Stack Context
9 skills in stackrust-agent-friendly-cli
Designs Rust command-line interfaces that are reliable for agents, scripts, and humans. Use when building or reviewing Rust binaries, clap command trees, diagnostics commands, codegen tools, or automation-facing workflows.
rust-anti-patterns
Identifies and fixes common Rust anti-patterns. Use during code review, when seeing excessive clones/unwraps/index loops, or when code fights the borrow checker instead of working with it.
rust-coding-guidelines
50 core Rust coding conventions covering naming, data types, strings, error handling, memory, concurrency, async, and modern crate recommendations. Use when reviewing code style or setting up project conventions.
rust-concurrency
Guides concurrency and async decisions in Rust. Use when encountering Send/Sync errors (E0277), choosing between threads vs async, designing shared state, or debugging deadlocks.
rust-error-handling
Guides Rust error handling strategy. Use when choosing between Result/Option/panic, using anyhow vs thiserror, propagating errors with ?, or designing custom error types.
rust-ownership
Guides ownership, borrowing, and lifetime decisions in Rust. Use when encountering E0382, E0597, E0506, E0507, move errors, or when designing data ownership.
rust-performance
Guides Rust performance optimization. Use when profiling, benchmarking, reducing allocations, improving cache locality, choosing between rayon/async/threads, or applying SIMD/parallelism.
rust-type-driven-design
Guides type-driven design in Rust. Use when encoding invariants in types, applying newtype pattern, implementing type state machines, using PhantomData, or making invalid states unrepresentable.
rust-zero-cost-abstractions
Guides generic vs trait object decisions in Rust. Use when choosing between static and dynamic dispatch, designing traits, handling E0277/E0038, or deciding between enum and dyn Trait.
Markdown
---
name: rust-anti-patterns
description: Identifies and fixes common Rust anti-patterns. Use during code review, when seeing excessive clones/unwraps/index loops, or when code fights the borrow checker instead of working with it.
license: MIT
origin_url: https://github.com/actionbook/rust-skills
---
# Anti-Patterns
> **Layer 2: Design Choices**
## Core Question
**Is this pattern hiding a design problem?**
When reviewing code:
- Is this solving the symptom or the cause?
- Is there a more idiomatic approach?
- Does this fight or flow with Rust?
---
## Top 5 Beginner Mistakes
| Rank | Mistake | Fix |
|------|---------|-----|
| 1 | Clone to escape borrow checker | Use references |
| 2 | Unwrap in production | Propagate with `?` |
| 3 | String for everything | Use `&str` |
| 4 | Index loops | Use iterators |
| 5 | Fighting lifetimes | Restructure to own data |
---
## Anti-Pattern Reference
| Anti-Pattern | Why Bad | Better |
|--------------|---------|--------|
| `.clone()` everywhere | Hides ownership issues | Proper references or ownership |
| `.unwrap()` in production | Runtime panics | `?`, `expect`, or matching |
| `Rc` when single owner | Unnecessary overhead | Simple ownership |
| `unsafe` for convenience | UB risk | Find safe pattern |
| OOP via `Deref` | Misleading API | Composition, traits |
| Giant match arms | Unmaintainable | Extract to methods |
| `String` everywhere | Allocation waste | `&str`, `Cow<str>` |
| Ignoring `#[must_use]` | Lost errors | Handle or `let _ =` |
---
## Code Smell → Refactoring
| Smell | Indicates | Refactoring |
|-------|-----------|-------------|
| Many `.clone()` | Ownership unclear | Clarify data flow |
| Many `.unwrap()` | Error handling missing | Add proper handling |
| Many `pub` fields | Encapsulation broken | Private + accessors |
| Deep nesting | Complex logic | Extract methods |
| Long functions | Multiple responsibilities | Split |
| Giant enums | Missing abstraction | Trait + types |
---
## Quick Review Checklist
- [ ] No `.clone()` without justification
- [ ] No `.unwrap()` in library code
- [ ] No `pub` fields with invariants
- [ ] No index loops when iterator works
- [ ] No `String` where `&str` suffices
- [ ] No ignored `#[must_use]` warnings
- [ ] No `unsafe` without `// SAFETY:` comment
- [ ] No giant functions (>50 lines)
---
## Deprecated → Better
| Deprecated | Better |
|------------|--------|
| Index-based loops | `.iter()`, `.enumerate()` |
| `collect::<Vec<_>>()` then iterate | Chain iterators |
| Manual unsafe cell | `Cell`, `RefCell` |
| `mem::transmute` for casts | `as` or `TryFrom` |
| Custom linked list | `Vec`, `VecDeque` |
| `lazy_static!` | `std::sync::OnceLock` |
| `once_cell::Lazy` | `std::sync::LazyLock` |
---
## Related Skills
- `ownership` — fixing ownership anti-patterns
- `error-handling` — replacing unwrap chains
- `performance` — fixing allocation anti-patterns
- `type-driven-design` — fixing primitive obsession