Rust Code Review Guidelines
This guide defines how the reviewer evaluates a Rust pull request.
Baseline Assumptions
- The code compiles.
- All tests pass.
Normative Words
- MUST: Mandatory. Not following this is a violation of the guide.
- MUST NOT: Forbidden.
- SHOULD: Recommended in almost all cases; exceptions need a strong reason.
- SHOULD NOT: Generally discouraged; only do it with clear justification.
- MAY: Optional; use judgment.
Scope and Priorities
The reviewer MUST:
- Focus on the actual diff and its impact.
- Prioritize in this order:
- Correctness and safety (including error handling policy).
- Public API and external behavior.
- Concurrency and performance issues with real impact.
- Readability, idioms, maintainability.
The reviewer MUST NOT:
- Invent business logic or protocol rules not implied by the code or docs.
- Demand large unrelated refactors unless there is a clear correctness or safety concern.
Review Process
- Read the PR description and understand the intent
- Review the diff file by file
- For each change, consider:
- Does this introduce bugs or security issues?
- Is the API appropriate?
- Are edge cases handled?
- Is error handling adequate?
- Provide actionable, specific feedback
- Distinguish blocking issues from suggestions
Feedback Format
Use clear prefixes:
- MUST FIX: Blocking issue that needs resolution
- SHOULD FIX: Strong recommendation
- CONSIDER: Optional improvement
- QUESTION: Clarification needed
Rust-Specific Rules
No unwrap in Non-test Code
The reviewer MUST:
- Flag every
unwrap(), unwrap_err(), or expect_err() outside tests.
Preferred alternatives:
- Use
? and propagate errors when the function returns Result.
- Handle errors explicitly (map to a domain error, log and fallback, or early return).
- Use
expect() only when failure is logically impossible or globally fatal, and the message explains why.
Bad:
let cfg = read_config().unwrap();
Better:
let cfg = read_config()?;
Acceptable only with proof:
let cfg = read_config().expect(
"config is validated and loaded at startup; reaching here means startup checks passed"
);
The reviewer MUST reject vague expect messages (e.g. "should not fail").
No panic! in Non-test Code
The reviewer MUST:
- Flag all
panic!, todo!, and unimplemented! outside tests.
The reviewer SHOULD:
- Prefer returning and propagating proper errors.
- Fail early at startup via error returns instead of panics deep in logic.
- Encourage tests to use panics and unwraps only with clear messages (e.g.
expect("reason")).
unreachable!() Usage
The reviewer MUST:
- Flag
unreachable!() unless a clear invariant explanation is provided.
It MAY be accepted if:
- The branch is genuinely impossible by construction.
- A comment documents the invariant (why this branch cannot be reached).
Otherwise, prefer returning a domain error instead of unreachable!().
No Silently Ignored Errors (Non-test Code)
The reviewer MUST:
- Flag any ignored
Result or Option unless the error is handled or logged, there is a clear comment explaining why ignoring is safe, or the error type is () and this is intentional.
Bad:
let _ = do_something_fallible();
do_something_fallible().ok();
Acceptable:
if let Err(e) = do_something_fallible() {
log::warn!("failed to do something: {}", e);
}
// Safe to ignore: telemetry failures do not affect correctness.
let _ = send_telemetry(&metrics);
Tests MAY ignore errors, but explicit assertions are encouraged.
Idiomatic Rust and Built-ins
The reviewer SHOULD:
- Suggest
? for simple error propagation instead of manual match.
- Use iterator methods (
map, filter, collect, etc.) when they simplify logic.
- Use
Option and Result combinators (map, and_then, ok_or, etc.) where they make code clearer.
The reviewer MUST NOT:
- Suggest overly clever refactors that hurt readability.
Performance
The reviewer SHOULD:
- Point out obvious waste such as repeated
to_string or clone in hot loops, or missing with_capacity for growing collections.
The reviewer MUST:
- Favor correctness and clarity over small micro-optimizations.
- Avoid speculative performance claims without a clear reason.
Documentation and Comments
The reviewer SHOULD:
- Ensure new or changed public APIs have basic
/// docs covering behavior, arguments, return values, and possible errors.
- Encourage comments where logic is non-obvious, especially around
unsafe code, concurrency and ordering assumptions, or invariants the type system does not enforce.
The reviewer SHOULD NOT:
- Request redundant "code-as-English" comments.
1---2name: code-review-rust-23description: Rust code review guidelines with prioritized focus on correctness, safety, and idiomatic patterns.4---56# Rust Code Review Guidelines78This guide defines how the reviewer evaluates a Rust pull request.910## Baseline Assumptions11- The code compiles.12- All tests pass.1314## Normative Words15- MUST: Mandatory. Not following this is a violation of the guide.16- MUST NOT: Forbidden.17- SHOULD: Recommended in almost all cases; exceptions need a strong reason.18- SHOULD NOT: Generally discouraged; only do it with clear justification.19- MAY: Optional; use judgment.2021## Scope and Priorities2223The reviewer MUST:24- Focus on the actual diff and its impact.25- Prioritize in this order:26 1. Correctness and safety (including error handling policy).27 2. Public API and external behavior.28 3. Concurrency and performance issues with real impact.29 4. Readability, idioms, maintainability.3031The reviewer MUST NOT:32- Invent business logic or protocol rules not implied by the code or docs.33- Demand large unrelated refactors unless there is a clear correctness or safety concern.3435## Review Process36371. Read the PR description and understand the intent382. Review the diff file by file393. For each change, consider:40 - Does this introduce bugs or security issues?41 - Is the API appropriate?42 - Are edge cases handled?43 - Is error handling adequate?444. Provide actionable, specific feedback455. Distinguish blocking issues from suggestions4647## Feedback Format4849Use clear prefixes:50- **MUST FIX**: Blocking issue that needs resolution51- **SHOULD FIX**: Strong recommendation52- **CONSIDER**: Optional improvement53- **QUESTION**: Clarification needed5455---5657## Rust-Specific Rules5859## No `unwrap` in Non-test Code6061The reviewer MUST:62- Flag every `unwrap()`, `unwrap_err()`, or `expect_err()` outside tests.6364Preferred alternatives:65- Use `?` and propagate errors when the function returns `Result`.66- Handle errors explicitly (map to a domain error, log and fallback, or early return).67- Use `expect()` only when failure is logically impossible or globally fatal, and the message explains why.6869Bad:70```rust71let cfg = read_config().unwrap();72```7374Better:75```rust76let cfg = read_config()?;77```7879Acceptable only with proof:80```rust81let cfg = read_config().expect(82 "config is validated and loaded at startup; reaching here means startup checks passed"83);84```8586The reviewer MUST reject vague `expect` messages (e.g. "should not fail").8788## No `panic!` in Non-test Code8990The reviewer MUST:91- Flag all `panic!`, `todo!`, and `unimplemented!` outside tests.9293The reviewer SHOULD:94- Prefer returning and propagating proper errors.95- Fail early at startup via error returns instead of panics deep in logic.96- Encourage tests to use panics and unwraps only with clear messages (e.g. `expect("reason")`).9798## `unreachable!()` Usage99100The reviewer MUST:101- Flag `unreachable!()` unless a clear invariant explanation is provided.102103It MAY be accepted if:104- The branch is genuinely impossible by construction.105- A comment documents the invariant (why this branch cannot be reached).106107Otherwise, prefer returning a domain error instead of `unreachable!()`.108109## No Silently Ignored Errors (Non-test Code)110111The reviewer MUST:112- Flag any ignored `Result` or `Option` unless the error is handled or logged, there is a clear comment explaining why ignoring is safe, or the error type is `()` and this is intentional.113114Bad:115```rust116let _ = do_something_fallible();117do_something_fallible().ok();118```119120Acceptable:121```rust122if let Err(e) = do_something_fallible() {123 log::warn!("failed to do something: {}", e);124}125126// Safe to ignore: telemetry failures do not affect correctness.127let _ = send_telemetry(&metrics);128```129130Tests MAY ignore errors, but explicit assertions are encouraged.131132## Idiomatic Rust and Built-ins133134The reviewer SHOULD:135- Suggest `?` for simple error propagation instead of manual `match`.136- Use iterator methods (`map`, `filter`, `collect`, etc.) when they simplify logic.137- Use `Option` and `Result` combinators (`map`, `and_then`, `ok_or`, etc.) where they make code clearer.138139The reviewer MUST NOT:140- Suggest overly clever refactors that hurt readability.141142## Performance143144The reviewer SHOULD:145- Point out obvious waste such as repeated `to_string` or `clone` in hot loops, or missing `with_capacity` for growing collections.146147The reviewer MUST:148- Favor correctness and clarity over small micro-optimizations.149- Avoid speculative performance claims without a clear reason.150151## Documentation and Comments152153The reviewer SHOULD:154- Ensure new or changed public APIs have basic `///` docs covering behavior, arguments, return values, and possible errors.155- Encourage comments where logic is non-obvious, especially around `unsafe` code, concurrency and ordering assumptions, or invariants the type system does not enforce.156157The reviewer SHOULD NOT:158- Request redundant "code-as-English" comments.