m15-anti-pattern
Use when reviewing code for anti-patterns. Keywords: anti-pattern, common mistake, pitfall, code smell, bad practice, code review, is this an anti-pattern, better way to do this, common mistake to avoid, why is this bad, idiomatic way, beginner mistake, fighting borrow checker, clone everywhere, unw
By actionbook · 7,724 installs
npx skills add actionbook/rust-skills --skill m15-anti-pattern
Source repository · Upstream listing
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?
Anti Pattern → Better Pattern
Anti Pattern Why Bad Better
.clone() everywhere Hides ownership issues Proper references or ownership
.unwrap() in production Runtime panics ? , expect , or handling
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 =
Thinking Prompt
When seeing suspicious code:
1. Is this symptom or cause?
Clone to avoid borrow? → Ownership design issue
Unwrap "because it won't fail"? → Unhandled case
2. What would idiomatic code look like?
References instead of clones
Iterators instead of index loops
Pattern matching instead of flags
3. Does this fight Rust?
Fighting borrow checker → restructure
Excessive unsafe → find safe pattern
Trace Up ↑
To design understanding:
Anti Pattern Trace To Question
Clone everywhere m01 ownership Who should own this data?
Unwrap everywhere m06 error handling What's the error strategy?
Rc everywhere m09 domain Is ownership clear?
Fighting lifetimes m09 domain Should data structure change?
Trace Down ↓
To implementation (Layer 1):
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
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
Common Error Patterns
Error Anti Pattern Cause Fix
E0382 use after move Cloning vs ownership Proper references
Panic in production Unwrap everywhere ?, matching
Slow performance String for all text &str, Cow
Borrow checker fights Wrong structure Restructure
Memory bloat Rc/Arc everywhere Simple ownership
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
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)
Related Skills
When See
Ownership patterns m01 ownership
Error handling m06 error handling
Mental models m14 mental model
Performance m10 performance