/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,
$ npx -y skills add zhanghandong/rust-skills --skill m15-anti-pattern --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
/m15-anti-pattern
Context preview
The summary Claude sees to decide when to auto-load this skill.
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,
SKILL.md
m15-anti-pattern.SKILL.mdname: m15-anti-pattern
description: "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, unwrap in production, should I refactor, 反模式, 常见错误, 代码异味, 最佳实践, 地道写法"
user-invocable: false
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:
"Why does my code have so many clones?"
↑ Ask: Is the ownership model correct?
↑ Check: m09-domain (data flow design)
↑ Check: m01-ownership (reference patterns)| 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):
"Replace clone with proper ownership"
↓ m01-ownership: Reference patterns
↓ m02-resource: Smart pointer if needed
"Replace unwrap with proper handling"
↓ m06-error-handling: ? operator
↓ m06-error-handling: expect with message---
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 |
Read more
name: m15-anti-pattern description: "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, unwrap in production, should I refactor, 反模式, 常见错误, 代码异味, 最佳实践, 地道写法" user-invocable: false
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:
"Why does my code have so many clones?"
↑ Ask: Is the ownership model correct?
↑ Check: m09-domain (data flow design)
↑ Check: m01-ownership (reference patterns)| 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):
"Replace clone with proper ownership"
↓ m01-ownership: Reference patterns
↓ m02-resource: Smart pointer if needed
"Replace unwrap with proper handling"
↓ m06-error-handling: ? operator
↓ m06-error-handling: expect with message---
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 |
AI-powered Rust development assistant with meta-cognition framework
Other skills on rust-skills.
- /coding-guidelines
Use when asking about Rust code style or best practices. Keywords: naming, formatting, comment, clippy, rustfmt, lint, code style, best practice, P.NAM, G.FMT, code review, naming convention, variable naming, function naming, type naming, 命名规范, 代码风格, 格式化, 最佳实践, 代码审查, 怎么命名
Open skill - /core-actionbook
Internal support skill for actionbook MCP selectors used by Rust documentation research workflows. Use only when another rust-skills workflow explicitly requests actionbook-backed selectors.
Open skill - /core-agent-browser
Internal support skill for agent-browser CLI workflows used by rust-learner, docs-researcher, and crate-researcher. Use only when browser automation is explicitly required.
Open skill - /core-dynamic-skills
Internal command support for dynamic Rust crate skill management. Use only when explicitly invoked by /sync-crate-skills, /clean-crate-skills, or /update-crate-skill.
Open skill - /core-fix-skill-docs
Internal maintenance support for checking and fixing generated Rust skill documentation references. Use only when explicitly invoked by /fix-skill-docs.
Open skill - /domain-cli
Use when building CLI tools. Keywords: CLI, command line, terminal, clap, structopt, argument parsing, subcommand, interactive, TUI, ratatui, crossterm, indicatif, progress bar, colored output, shell completion, config file, environment variable, 命令行, 终端应用, 参数解析
Open skill

