Rust¶
Rust's zen is the compiler's bargain: fight with the borrow checker at compile time, and your code won't segfault at runtime. These 12 principles encode the idiomatic patterns that experienced Rustaceans follow — patterns that go beyond "it compiles" into "it's well-designed."
Optional External Tool Augmentation¶
Consent-first external tooling
External tool execution is optional and disabled by default. Use
--enable-external-tools (CLI) or enable_external_tools=true (MCP)
to opt in. Missing tools should return recommendations; no automatic
installs occur during analysis.
| Tool | Default invocation | Output |
|---|---|---|
cargo |
cargo clippy --message-format=json |
JSON |
Zen Principles¶
17 principles across 11 categories, drawn from Rust API Guidelines.
Concurrency · 1 principle Correctness · 1 principle Debugging · 1 principle Design · 3 principles Error Handling · 2 principles Idioms · 4 principles Ownership · 1 principle Performance · 1 principle Readability · 1 principle Safety · 1 principle Type Safety · 1 principle
| Rule ID | Principle | Category | Severity | Dogma |
|---|---|---|---|---|
rust-001 |
Avoid unwrap() and expect() in production code | Error Handling | 9 | ZEN-FAIL-FAST |
rust-002 |
Use the type system to prevent bugs | Type Safety | 8 | ZEN-EXPLICIT-INTENT, ZEN-VISIBLE-STATE |
rust-003 |
Prefer iterators over loops | Idioms | 7 | ZEN-RIGHT-ABSTRACTION |
rust-004 |
Clone sparingly | Performance | 7 | ZEN-PROPORTIONATE-COMPLEXITY |
rust-005 |
Use #[must_use] for important return types | Correctness | 6 | ZEN-EXPLICIT-INTENT |
rust-006 |
Implement Debug for all public types | Debugging | 6 | ZEN-EXPLICIT-INTENT |
rust-007 |
Use newtype pattern for type safety | Design | 7 | ZEN-RIGHT-ABSTRACTION |
rust-008 |
Avoid unsafe unless necessary | Safety | 9 | ZEN-FAIL-FAST |
rust-009 |
Use std traits appropriately | Idioms | 7 | ZEN-RIGHT-ABSTRACTION |
rust-010 |
Prefer enums over booleans for state | Design | 7 | ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT, ZEN-VISIBLE-STATE |
rust-011 |
Use lifetimes judiciously | Ownership | 6 | ZEN-VISIBLE-STATE, ZEN-EXPLICIT-INTENT |
rust-012 |
Avoid Rc |
Design | 7 | ZEN-RIGHT-ABSTRACTION, ZEN-VISIBLE-STATE |
rust-013 |
Send + Sync should be implemented when types allow | Concurrency | 7 | ZEN-VISIBLE-STATE |
rust-014 |
Error types should implement standard error traits | Error Handling | 8 | ZEN-FAIL-FAST |
rust-015 |
Follow Rust naming conventions (RFC 430) | Readability | 6 | ZEN-UNAMBIGUOUS-NAME |
rust-016 |
Implement Default when there is an obvious default value | Idioms | 5 | ZEN-RIGHT-ABSTRACTION, ZEN-VISIBLE-STATE |
rust-017 |
Use From/Into for type conversions | Idioms | 6 | ZEN-RIGHT-ABSTRACTION |
rust-001 — Avoid unwrap() and expect() in production code
Use proper error handling with Result and Option
Universal Dogmas: ZEN-FAIL-FAST
Common Violations:
- unwrap() in library code
- expect() without clear justification
- Ignoring Result types
- Excessive panic usage
Detectable Patterns:
.unwrap().expect(
Recommended Fix
match, if let, ?, or unwrap_or
rust-002 — Use the type system to prevent bugs
Leverage Rust's type system for compile-time guarantees
Universal Dogmas: ZEN-EXPLICIT-INTENT, ZEN-VISIBLE-STATE
Common Violations:
- Using primitive types when newtype would be safer
- Stringly-typed APIs
- Not using enums for state machines
- Overuse of Option
instead of proper types
Detectable Patterns:
Stringi32u32
rust-003 — Prefer iterators over loops
Use iterator methods for functional, zero-cost abstractions
Universal Dogmas: ZEN-RIGHT-ABSTRACTION
Common Violations:
- Manual for loops over collections
- Index-based iteration
- Mutable accumulator patterns
- Not using map/filter/fold
Detectable Patterns:
for i in 0..vec.len()manual mutation in loops
rust-004 — Clone sparingly
Avoid unnecessary cloning, prefer borrowing
Universal Dogmas: ZEN-PROPORTIONATE-COMPLEXITY
Common Violations:
- Cloning when references work
- Excessive .clone() calls
- Not using Cow
- Cloning in hot paths
rust-005 — Use #[must_use] for important return types
Mark Result and critical types as must_use
Universal Dogmas: ZEN-EXPLICIT-INTENT
Common Violations:
- Result types without must_use
- Ignoring function return values
- Not annotating important builders
Detectable Patterns:
!#[must_use]
rust-006 — Implement Debug for all public types
Derive or implement Debug for better debugging
Universal Dogmas: ZEN-EXPLICIT-INTENT
Common Violations:
- Public structs without Debug
- Complex types without Debug
- Not using #[derive(Debug)]
Detectable Patterns:
!#[derive(Debug)]
rust-007 — Use newtype pattern for type safety
Wrap primitives in newtypes for semantic clarity
Universal Dogmas: ZEN-RIGHT-ABSTRACTION
Common Violations:
- Using raw integers for IDs
- String for typed values
- Not distinguishing similar types (UserId vs ProductId)
Detectable Patterns:
!struct
rust-008 — Avoid unsafe unless necessary
Minimize unsafe code and document invariants
Universal Dogmas: ZEN-FAIL-FAST
Common Violations:
- Unnecessary unsafe blocks
- Unsafe without safety comments
- Large unsafe blocks
- Unsafe in public APIs without documentation
Detectable Patterns:
unsafe {unsafe fn
rust-009 — Use std traits appropriately
Implement standard traits (Display, From, Into, etc.)
Universal Dogmas: ZEN-RIGHT-ABSTRACTION
Common Violations:
- Custom conversion instead of From/Into
- String formatting without Display
- Not implementing Default when appropriate
- Manual iteration instead of IntoIterator
Detectable Patterns:
!impl From!impl Default
rust-010 — Prefer enums over booleans for state
Use enums to make state explicit
Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT, ZEN-VISIBLE-STATE
Common Violations:
- Boolean flags for state
- Multiple related booleans
- State represented by Option<()>
Detectable Patterns:
bool
rust-011 — Use lifetimes judiciously
Let the compiler infer when possible, be explicit when needed
Universal Dogmas: ZEN-VISIBLE-STATE, ZEN-EXPLICIT-INTENT
Common Violations:
- Unnecessary lifetime annotations
- Overly complex lifetime bounds
- Fighting the borrow checker instead of redesigning
Detectable Patterns:
<'a><'static>
rust-012 — Avoid Rc> unless necessary
Prefer ownership or references over runtime borrowing
Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-VISIBLE-STATE
Common Violations:
- Overuse of Rc
> - Interior mutability when not needed
- Arc
> in single-threaded code
Detectable Patterns:
Rc<RefCellArc<Mutex
rust-013 — Send + Sync should be implemented when types allow
Public types that can safely be Send/Sync should be, and unsafe impls need SAFETY comments
Universal Dogmas: ZEN-VISIBLE-STATE
Common Violations:
- unsafe impl Send without SAFETY comment
- unsafe impl Sync without SAFETY comment
- Public types missing Send/Sync bounds
Detectable Patterns:
unsafe impl Sendunsafe impl Sync
rust-014 — Error types should implement standard error traits
Custom error types must implement std::error::Error, Display, and Debug
Universal Dogmas: ZEN-FAIL-FAST
Common Violations:
- Error type without std::error::Error impl
- Missing Display for error types
- Error types without Debug
Detectable Patterns:
struct Error without impl Errorenum Error without Display
Recommended Fix
Use thiserror derive macros or manual Display + Error impls
rust-015 — Follow Rust naming conventions (RFC 430)
Use snake_case for functions, CamelCase for types, SCREAMING_SNAKE_CASE for constants
Universal Dogmas: ZEN-UNAMBIGUOUS-NAME
Common Violations:
- camelCase function names
- snake_case type names
- Lowercase constants
- Non-standard lifetime names
Detectable Patterns:
fn camelCasestruct snake_caseconst lowercase
rust-016 — Implement Default when there is an obvious default value
Types with meaningful zero/empty states should derive or implement Default
Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-VISIBLE-STATE
Common Violations:
- Public structs with obvious defaults missing Default
- Builder patterns without Default
- Option/Vec fields without derive Default
Detectable Patterns:
pub struct without derive(Default)
rust-017 — Use From/Into for type conversions
Prefer From/Into trait implementations over manual conversion functions
Universal Dogmas: ZEN-RIGHT-ABSTRACTION
Common Violations:
- Manual from_xxx() without From impl
- Manual to_xxx() without Into impl
- Clone-into chains suggesting missing From
Detectable Patterns:
fn from_string(fn into_vec(fn to_string(
Recommended Fix
impl From
Detector Catalog¶
Concurrency¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustSendSyncDetector | Flags unsafe Send/Sync implementations without SAFETY comments | rust-013 |
Correctness¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustMustUseDetector | Detects Result-returning code that omits the #[must_use] attribute |
rust-005 |
Debugging¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustDebugDeriveDetector | Ensures public structs derive Debug for ergonomic logging and diagnostics |
rust-006 |
Design¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustNewtypePatternDetector | Flags type aliases to primitives that should be tuple-struct newtypes | rust-007 |
| RustEnumOverBoolDetector | Flags structs with too many boolean fields that should be expressed as enums | rust-010 |
| RustInteriorMutabilityDetector | Detects Rc<RefCell<T>> and Arc<Mutex<T>> patterns that signal design issues |
rust-012 |
Error Handling¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustErrorHandlingDetector | Flags functions that use Result without propagating errors and detects panic! abuse |
rust-001 |
| RustErrorTraitsDetector | Flags error types that do not implement std::error::Error |
rust-014 |
| RustUnwrapUsageDetector | Flags excessive unwrap() and expect() calls that bypass Rust's error model |
rust-001 |
Idioms¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustIteratorPreferenceDetector | Flags excessive manual loops where iterator adapters would be more idiomatic | rust-003 |
| RustStdTraitsDetector | Detects structs that lack standard trait implementations like From or Display |
rust-009 |
| RustDefaultImplDetector | Flags public structs that lack a Default implementation |
rust-016 |
| RustFromIntoDetector | Flags ad-hoc conversion functions that should use From/Into traits |
rust-017 |
Ownership¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustLifetimeUsageDetector | Flags excessive explicit lifetime annotations where elision would suffice | rust-011 |
Performance¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustCloneOverheadDetector | Detects excessive .clone() calls that undermine Rust's zero-cost abstraction goal |
rust-004 |
Readability¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustNamingDetector | Flags functions using camelCase instead of snake_case | rust-015 |
Safety¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustUnsafeBlocksDetector | Ensures every unsafe block is preceded by a // SAFETY: comment |
rust-008 |
Type Safety¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| RustTypeSafetyDetector | Flags structs that use raw primitive types instead of domain-specific newtypes | rust-002 |
Principle → Detector Wiring
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 40, "rankSpacing": 60}}}%%
graph TD
rust_001["rust-001<br/>Avoid unwrap() and expect..."]
rust_002["rust-002<br/>Use the type system to pr..."]
rust_003["rust-003<br/>Prefer iterators over loo..."]
rust_004["rust-004<br/>Clone sparingly"]
rust_005["rust-005<br/>Use #[must_use] for impor..."]
rust_006["rust-006<br/>Implement Debug for all p..."]
rust_007["rust-007<br/>Use newtype pattern for t..."]
rust_008["rust-008<br/>Avoid unsafe unless neces..."]
rust_009["rust-009<br/>Use std traits appropriat..."]
rust_010["rust-010<br/>Prefer enums over boolean..."]
rust_011["rust-011<br/>Use lifetimes judiciously"]
rust_012["rust-012<br/>Avoid Rc<RefCell<T>> unle..."]
rust_013["rust-013<br/>Send + Sync should be imp..."]
rust_014["rust-014<br/>Error types should implem..."]
rust_015["rust-015<br/>Follow Rust naming conven..."]
rust_016["rust-016<br/>Implement Default when th..."]
rust_017["rust-017<br/>Use From/Into for type co..."]
det_RustCloneOverheadDetector["Rust Clone<br/>Overhead"]
rust_004 --> det_RustCloneOverheadDetector
det_RustDebugDeriveDetector["Rust Debug<br/>Derive"]
rust_006 --> det_RustDebugDeriveDetector
det_RustDefaultImplDetector["Rust Default<br/>Impl"]
rust_016 --> det_RustDefaultImplDetector
det_RustEnumOverBoolDetector["Rust Enum<br/>Over Bool"]
rust_010 --> det_RustEnumOverBoolDetector
det_RustErrorHandlingDetector["Rust Error<br/>Handling"]
rust_001 --> det_RustErrorHandlingDetector
det_RustErrorTraitsDetector["Rust Error<br/>Traits"]
rust_014 --> det_RustErrorTraitsDetector
det_RustFromIntoDetector["Rust From<br/>Into"]
rust_017 --> det_RustFromIntoDetector
det_RustInteriorMutabilityDetector["Rust Interior<br/>Mutability"]
rust_012 --> det_RustInteriorMutabilityDetector
det_RustIteratorPreferenceDetector["Rust Iterator<br/>Preference"]
rust_003 --> det_RustIteratorPreferenceDetector
det_RustLifetimeUsageDetector["Rust Lifetime<br/>Usage"]
rust_011 --> det_RustLifetimeUsageDetector
det_RustMustUseDetector["Rust Must<br/>Use"]
rust_005 --> det_RustMustUseDetector
det_RustNamingDetector["Rust Naming"]
rust_015 --> det_RustNamingDetector
det_RustNewtypePatternDetector["Rust Newtype<br/>Pattern"]
rust_007 --> det_RustNewtypePatternDetector
det_RustSendSyncDetector["Rust Send<br/>Sync"]
rust_013 --> det_RustSendSyncDetector
det_RustStdTraitsDetector["Rust Std<br/>Traits"]
rust_009 --> det_RustStdTraitsDetector
det_RustTypeSafetyDetector["Rust Type<br/>Safety"]
rust_002 --> det_RustTypeSafetyDetector
det_RustUnsafeBlocksDetector["Rust Unsafe<br/>Blocks"]
rust_008 --> det_RustUnsafeBlocksDetector
det_RustUnwrapUsageDetector["Rust Unwrap<br/>Usage"]
rust_001 --> det_RustUnwrapUsageDetector
Detector Class Hierarchy
%%{init: {"theme": "base"}}%%
classDiagram
direction TB
class ViolationDetector {
<<abstract>>
+detect(context, config)
}
class det_01["Rust Clone Overhead"]
ViolationDetector <|-- det_01
class det_02["Rust Debug Derive"]
ViolationDetector <|-- det_02
class det_03["Rust Default Impl"]
ViolationDetector <|-- det_03
class det_04["Rust Enum Over Bool"]
ViolationDetector <|-- det_04
class det_05["Rust Error Handling"]
ViolationDetector <|-- det_05
class det_06["Rust Error Traits"]
ViolationDetector <|-- det_06
class det_07["Rust From Into"]
ViolationDetector <|-- det_07
class det_08["Rust Interior Mutability"]
ViolationDetector <|-- det_08
class det_09["Rust Iterator Preference"]
ViolationDetector <|-- det_09
class det_10["Rust Lifetime Usage"]
ViolationDetector <|-- det_10
class det_11["Rust Must Use"]
ViolationDetector <|-- det_11
class det_12["Rust Naming"]
ViolationDetector <|-- det_12
class det_13["Rust Newtype Pattern"]
ViolationDetector <|-- det_13
class det_14["Rust Send Sync"]
ViolationDetector <|-- det_14
class det_15["Rust Std Traits"]
ViolationDetector <|-- det_15
class det_16["Rust Type Safety"]
ViolationDetector <|-- det_16
class det_17["Rust Unsafe Blocks"]
ViolationDetector <|-- det_17
class det_18["Rust Unwrap Usage"]
ViolationDetector <|-- det_18
Analysis Pipeline
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 50, "rankSpacing": 70}}}%%
flowchart TD
Source(["Source Code"]) --> Parse["Parse & Tokenize"]
Parse --> Metrics["Compute Metrics"]
Metrics --> Pipeline{"18 Detectors"}
Pipeline --> Collect["Aggregate Violations"]
Collect --> Result(["AnalysisResult<br/>17 principles"])
Analysis States
%%{init: {"theme": "base"}}%%
stateDiagram-v2
[*] --> Ready
Ready --> Parsing : analyze(code)
Parsing --> Computing : AST ready
Computing --> Detecting : metrics ready
Detecting --> Reporting : 18 detectors run
Reporting --> [*] : AnalysisResult
Parsing --> Reporting : parse error (best-effort)
Configuration¶
languages:
rust:
enabled: true
pipeline:
- type: rust-002
primitive_types: ['String', 'i32', 'u32', 'i64', 'u64', 'bool']
- type: rust-003
max_loops: 0
- type: rust-007
primitive_types: ['String', 'i32', 'u32', 'i64', 'u64', 'bool']
- type: rust-010
max_bool_fields: 0
- type: rust-011
max_explicit_lifetimes: 0
- type: rust_clone_overhead
max_clone_calls: 0
- type: rust_error_handling
detect_unhandled_results: True
max_panics: 0
- type: rust_unsafe_blocks
detect_unsafe_blocks: True
- type: rust_unwrap_usage
max_unwraps: 0
See Also¶
- C++ — Systems programming counterpart with different safety models
- Configuration — Per-language pipeline overrides
- Understanding Violations — Severity scale reference