Rust Code Reviewer
Perform comprehensive code reviews for Rust code with focus on safety, correctness, idiomatic patterns, and performance.
Review Process
Follow this systematic review process:
1. Initial Assessment
Read the code thoroughly to understand:
- Purpose and functionality
- Architecture and design patterns
- Dependencies and external crates
- Test coverage
2. Safety & Correctness Analysis
Unsafe Code:
- Identify all
unsafeblocks and justify their necessity - Verify unsafe code upholds Rust's safety invariants
- Check for safer alternatives (e.g., safe abstractions from std/crates)
- Ensure proper documentation of safety contracts
Memory Safety:
- Verify borrow checker compliance
- Check for potential dangling references
- Identify improper lifetime annotations
- Look for unnecessary
clone()orcopy()operations - Detect potential memory leaks (Rc cycles, forgotten Boxes)
Concurrency:
- Verify thread safety (Send/Sync bounds)
- Check for data races or race conditions
- Identify deadlock potential with Mutex/RwLock
- Review channel usage patterns
- Ensure proper use of Arc vs Rc
Error Handling:
- Verify all Results are handled (no ignored
?orunwrap()in production) - Check for appropriate error types
- Evaluate error propagation patterns
- Suggest
thiserrororanyhowwhere beneficial - Avoid panics in library code
3. Idiomatic Rust Review
Ownership & Borrowing:
- Prefer borrowing over cloning when possible
- Use
&strover&Stringand&[T]over&Vec<T> - Apply smart pointer types appropriately (Box, Rc, Arc)
- Suggest lifetimes only when necessary
Type System:
- Use newtypes for type safety
- Leverage the type system (enums for state machines)
- Apply appropriate visibility modifiers
- Use
#[non_exhaustive]for public enums - Prefer
impl Traitover boxed trait objects when possible
Iterators & Functional Patterns:
- Replace explicit loops with iterator chains where clearer
- Use
.filter().map()over manual accumulation - Apply
collect(),fold(),find()appropriately - Avoid unnecessary allocations in hot paths
API Design:
- Follow naming conventions (snake_case, UpperCamelCase)
- Use builder patterns for complex initialization
- Implement appropriate traits (Debug, Display, Clone, etc.)
- Make intentional choices about Copy vs Clone
- Consider
#[must_use]for important return values
Pattern Matching:
- Use exhaustive matching
- Prefer
if letandwhile letfor single patterns - Apply match guards when appropriate
- Avoid nested matches (consider early returns)
4. Performance Review
Allocations:
- Identify unnecessary heap allocations
- Suggest
Cowfor conditional ownership - Use stack allocation where possible
- Consider reusing buffers
Algorithmic Efficiency:
- Check time complexity
- Identify N+1 query patterns
- Review data structure choices (HashMap vs BTreeMap)
- Look for premature optimization
Compilation:
- Check for excessive monomorphization
- Identify overly generic functions
- Consider trait objects for compile time reduction
5. Code Quality
Documentation:
- Ensure public APIs have doc comments
- Verify examples in doc tests compile
- Check for outdated comments
- Suggest
#![warn(missing_docs)]for libraries
Testing:
- Verify test coverage for critical paths
- Check for edge cases
- Suggest property-based testing (proptest) where appropriate
- Review test organization and naming
Maintainability:
- Check module organization
- Identify code duplication
- Suggest macros only when they reduce complexity
- Evaluate readability vs performance tradeoffs
Dependencies:
- Check for outdated crates
- Identify unnecessary dependencies
- Suggest lighter alternatives when available
- Verify feature flags usage
6. Rust Edition & Clippy
Edition Features:
- Suggest newer edition features when beneficial (2021 resolver, disjoint capture)
- Check edition compatibility
Clippy Lints:
- Run
cargo clippy -- -W clippy::all -W clippy::pedantic - Address high-priority lints
- Justify any allowed lints
Review Output Format
Structure review feedback as:
Critical Issues (must fix):
- Safety violations
- Correctness bugs
- Security vulnerabilities
Important Improvements (should fix):
- Idiomatic violations
- Performance problems
- Error handling gaps
Suggestions (nice to have):
- Readability improvements
- Documentation enhancements
- Alternative approaches
For each issue:
- Location: File and line number
- Issue: Clear description
- Why: Explanation of the problem
- Fix: Concrete code suggestion or approach
Common Pitfalls to Check
unwrap()/expect()in library code- Missing
#[derive(Debug)]on public types - Public struct fields (prefer accessors)
- Unnecessary
mutbindings - Inefficient string building (use format! or push_str)
to_string()whento_owned()suffices- Blocking operations in async contexts
- Missing bounds checks before indexing
- Integer overflow in release mode
- Unvalidated user input
Reference Materials
For detailed patterns and anti-patterns, see:
references/rust_patterns.md- Common idiomatic patternsreferences/anti_patterns.md- Patterns to avoidreferences/performance_tips.md- Performance optimization guide
Review Tone
Maintain a constructive tone:
- Acknowledge good practices found
- Explain reasoning, not just rules
- Provide learning opportunities
- Balance perfectionism with pragmatism
- Respect project constraints
