Contenido del repositorio de origen con títulos, ejemplos, código, tablas, enlaces e imágenes preservados.
Rust Best Practices
Comprehensive guide for writing high-quality, idiomatic, and highly optimized Rust code. Contains 265 rules across 26 categories, prioritized by impact to guide LLMs in code generation and refactoring. Current for Rust 1.96 (2024 edition).
When to Apply
Reference these guidelines when:
- Writing new Rust functions, structs, or modules
- Implementing error handling or async code
- Writing concurrent, parallel, or
unsafecode - Designing public APIs for libraries
- Reviewing code for ownership/borrowing issues
- Optimizing memory usage or reducing allocations
- Tuning performance for hot paths
- Refactoring existing Rust code
Rule Categories by Priority
| Priority | Category | Impact | Prefix | Rules |
|---|---|---|---|---|
| 1 | Ownership & Borrowing | CRITICAL | own- | 12 |
| 2 | Error Handling | CRITICAL | err- | 12 |
| 3 | Memory Optimization | CRITICAL | mem- | 17 |
| 4 | Unsafe Code | CRITICAL | unsafe- | 7 |
| 5 | API Design | HIGH | api- | 17 |
| 6 | Async/Await | HIGH | async- | 18 |
| 7 | Concurrency | HIGH | conc- | 4 |
| 8 | Compiler Optimization | HIGH | opt- | 12 |
| 9 | Numeric & Arithmetic Safety | HIGH | num- | 5 |
| 10 | Type Safety | MEDIUM | type- | 13 |
| 11 | Trait & Generics Design | MEDIUM | trait- | 6 |
| 12 | Conversions | MEDIUM | conv- | 3 |
| 13 | Const & Compile-Time | MEDIUM | const- | 4 |
| 14 | Serde | MEDIUM | serde- | 8 |
| 15 | Pattern Matching | MEDIUM | pat- | 5 |
| 16 | Macros | MEDIUM | macro- | 8 |
| 17 | Closures | MEDIUM | closure- | 5 |
| 18 | Collections | MEDIUM | coll- | 4 |
| 19 | Naming Conventions | MEDIUM | name- | 16 |
| 20 | Testing | MEDIUM | test- | 15 |
| 21 | Documentation | MEDIUM | doc- | 12 |
| 22 | Observability | MEDIUM | obs- | 7 |
| 23 | Performance Patterns | MEDIUM | perf- | 13 |
| 24 | Project Structure | LOW | proj- | 14 |
| 25 | Clippy & Linting | LOW | lint- | 13 |
| 26 | Anti-patterns | REFERENCE | anti- | 15 |
Quick Reference
1. Ownership & Borrowing (CRITICAL)
- `own-borrow-over-clone` - Prefer
&Tborrowing over.clone() - `own-slice-over-vec` - Accept
&[T]not&Vec<T>,&strnot&String - `own-cow-conditional` - Use
Cow<'a, T>for conditional ownership - `own-arc-shared` - Use
Arc<T>for thread-safe shared ownership - `own-rc-single-thread` - Use
Rc<T>for shared ownership in single-threaded contexts - `own-refcell-interior` - Use
RefCell<T>for interior mutability in single-threaded code - `own-mutex-interior` - Use
Mutex<T>for interior mutability across threads - `own-rwlock-readers` - Use
RwLock<T>when reads significantly outnumber writes - `own-copy-small` - Implement
Copyfor small, simple types - `own-clone-explicit` - Use explicit
Clonefor types where copying has meaningful cost - `own-move-large` - Move large types instead of copying; use
Boxif moves are expensive - `own-lifetime-elision` - Rely on lifetime elision rules; add explicit lifetimes only when required
2. Error Handling (CRITICAL)
- `err-thiserror-lib` - Use
thiserrorfor library error types - `err-anyhow-app` - Use
anyhowfor application error handling - `err-result-over-panic` - Return
Result<T, E>instead of panicking for recoverable errors - `err-context-chain` - Add context with
.context()or.with_context() - `err-no-unwrap-prod` - Avoid
unwrap()in production code; use?,expect(), or handle errors - `err-expect-bugs-only` - Use
expect()only for invariants that indicate bugs, not user errors - `err-question-mark` - Use
?operator for clean propagation - `err-from-impl` - Implement
From<E>for error conversions to enable?operator - `err-source-chain` - Preserve error chains with
#[source]orsource()method - `err-lowercase-msg` - Start error messages lowercase, no trailing punctuation
- `err-doc-errors` - Document error conditions with
# Errorssection in doc comments - `err-custom-type` - Define custom error types for domain-specific failures
3. Memory Optimization (CRITICAL)
- `mem-with-capacity` - Use
with_capacity()when size is known - `mem-smallvec` - Use
SmallVecfor usually-small collections - `mem-arrayvec` - Use
ArrayVec<T, N>for fixed-capacity collections that never heap-allocate - `mem-box-large-variant` - Box large enum variants to reduce overall enum size
- `mem-boxed-slice` - Use
Box<[T]>instead ofVec<T>for fixed-size heap data - `mem-thinvec` - Use
ThinVec<T>for nullable collections with minimal overhead - `mem-clone-from` - Use
clone_from()to reuse allocations when repeatedly cloning - `mem-reuse-collections` - Clear and reuse collections instead of creating new ones in loops
- `mem-avoid-format` - Avoid
format!()when string literals work - `mem-write-over-format` - Use
write!()into existing buffers instead offormat!()allocations - `mem-arena-allocator` - Use arena allocators for batch allocations
- `mem-zero-copy` - Use zero-copy patterns with slices and
Bytes - `mem-compact-string` - Use compact string types for memory-constrained string storage
- `mem-smaller-integers` - Use appropriately-sized integers to reduce memory footprint
- `mem-assert-type-size` - Use static assertions to guard against accidental type size growth
- `mem-take-replace` - Use
mem::take/mem::replaceto move a value out of a&mutwithout cloning - `mem-drop-order` - Know and control drop order: struct fields drop top-to-bottom, locals in reverse
4. Unsafe Code (CRITICAL)
- `unsafe-safety-comment` - Write a
// SAFETY:comment above everyunsafeblock and a# Safetysection in everyunsafe fn. - `unsafe-minimize-scope` - Keep
unsafeblocks as small as possible — mark only the operation that requires unsafety, not the surrounding safe code. - `unsafe-miri-ci` - Run
cargo miri testin CI for every crate that containsunsafecode. - `unsafe-maybeuninit` - Use
MaybeUninit<T>for uninitialized memory; never usemem::uninitialized()ormem::zeroed()for types with validity invariants. - `unsafe-extern-block` - In Rust 2024, wrap
externblocks inunsafe extern { }and annotate each item assafeorunsafe. - `unsafe-send-sync-manual` - Document the invariants when manually implementing
SendorSync; prefer letting the compiler derive them automatically. - `unsafe-no-mangle-unsafe` - In Rust 2024, write
#[unsafe(no_mangle)],#[unsafe(export_name = "...")], and#[unsafe(link_section = "...")]— not the bare attribute forms.
5. API Design (HIGH)
- `api-builder-pattern` - Use Builder pattern for complex construction
- `api-builder-must-use` - Mark builder methods with
#[must_use]to prevent silent drops - `api-newtype-safety` - Use newtypes to prevent mixing semantically different values
- `api-typestate` - Use typestate pattern to encode state machine invariants in the type system
- `api-sealed-trait` - Use sealed traits to prevent external implementations while allowing use
- `api-extension-trait` - Use extension traits to add methods to external types
- `api-parse-dont-validate` - Parse into validated types at boundaries
- `api-impl-into` - Accept
impl Into<T>for flexible APIs, implementFrom<T>for conversions - `api-impl-asref` - Use
AsRef<T>when you only need to borrow the inner data - `api-must-use` - Mark types and functions with
#[must_use]when ignoring results is likely a bug - `api-non-exhaustive` - Use
#[non_exhaustive]on public enums and structs for forward compatibility - `api-from-not-into` - Implement
From<T>, notInto<U>- From gives you Into for free - `api-default-impl` - Implement
Defaultfor types with sensible default values - `api-common-traits` - Implement standard traits (Debug, Clone, PartialEq, etc.) for public types
- `api-serde-optional` - Make serde a feature flag, not a hard dependency for library crates
- `api-impl-fromiterator` - Implement
FromIteratorandExtendfor collection types, andIntoIteratorfor all three reference forms - `api-operator-overload` - Overload operators only when the semantics are natural and unsurprising
6. Async/Await (HIGH)
- `async-tokio-runtime` - Configure Tokio runtime appropriately for your workload
- `async-no-lock-await` - Never hold
Mutex/RwLockacross.await - `async-spawn-blocking` - Use
spawn_blockingfor CPU-intensive work - `async-tokio-fs` - Use
tokio::fsinstead ofstd::fsin async code - `async-cancellation-token` - Use
CancellationTokenfor graceful shutdown and task cancellation - `async-join-parallel` - Use
join!ortry_join!for concurrent independent futures - `async-try-join` - Use
try_join!for concurrent fallible operations with early return on error - `async-select-racing` - Use
select!to race futures and handle the first to complete - `async-bounded-channel` - Use bounded channels to apply backpressure and prevent unbounded memory growth
- `async-mpsc-queue` - Use
mpscchannels for async message queues between tasks - `async-broadcast-pubsub` - Use
broadcastchannel for pub/sub where all subscribers receive all messages - `async-watch-latest` - Use
watchchannel for sharing the latest value with multiple observers - `async-oneshot-response` - Use
oneshotchannel for request-response patterns - `async-joinset-structured` - Use
JoinSetfor managing dynamic collections of spawned tasks - `async-clone-before-await` - Clone Arc/Rc data before await points to avoid holding references across suspension
- `async-fn-in-trait` - Use native
async fnin traits (stable 1.75) instead of theasync_traitmacro - `async-async-fn-bounds` - Use
AsyncFn/AsyncFnMut/AsyncFnOncebounds instead ofF: Fn() -> Fut, Fut: Future - `async-cancel-safety` - Ensure futures used in
tokio::select!branches are cancellation-safe
7. Concurrency (HIGH)
- `conc-rayon-par-iter` - Use rayon's
par_iter()for CPU-bound data parallelism - `conc-scoped-threads` - Use
std::thread::scopeto borrow stack data across threads - `conc-atomic-ordering` - Use the weakest correct memory
Orderingfor every atomic operation - `conc-thread-local` - Prefer
thread_local!withCell/RefCelloverstatic mut
8. Compiler Optimization (HIGH)
- `opt-inline-small` - Use
#[inline]for small hot functions - `opt-inline-always-rare` - Use
#[inline(always)]sparingly—only for critical hot paths proven by profiling - `opt-inline-never-cold` - Use
#[inline(never)]and#[cold]for error paths and rarely-executed code - `opt-cold-unlikely` - Mark unlikely code paths with
#[cold]to help compiler optimization - `opt-likely-hint` - Use code structure to hint at likely branches; use intrinsics on nightly
- `opt-lto-release` - Enable LTO in release builds
- `opt-codegen-units` - Set
codegen-units = 1for maximum optimization in release builds - `opt-pgo-profile` - Use Profile-Guided Optimization (PGO) for maximum performance
- `opt-target-cpu` - Use
target-cpu=nativefor maximum performance on known deployment targets - `opt-bounds-check` - Use iterators and patterns that eliminate bounds checks in hot paths
- `opt-simd-portable` - Use portable SIMD for vectorized operations across architectures
- `opt-cache-friendly` - Organize data for cache-efficient access patterns
9. Numeric & Arithmetic Safety (HIGH)
- `num-overflow-explicit` - Handle integer overflow explicitly:
checked_/saturating_/wrapping_/overflowing_ - `num-cast-try-from` - Avoid
asfor narrowing casts; useFromfor widening andTryFromfor narrowing - `num-float-compare` - Don't compare floats with
==; use a tolerance, andtotal_cmpfor ordering - `num-saturating-clamp` - Bound values with
clampand saturating arithmetic - `num-nonzero` - Use
NonZero*types to forbid zero and unlock the niche optimization
10. Type Safety (MEDIUM)
- `type-newtype-ids` - Wrap IDs in newtypes:
UserId(u64) - `type-newtype-validated` - Use newtypes to enforce validation at construction time
- `type-enum-states` - Use enums for mutually exclusive states
- `type-option-nullable` - Use
Option<T>for values that might not exist - `type-result-fallible` - Use
Result<T, E>for operations that can fail - `type-phantom-marker` - Use
PhantomDatato express type relationships without runtime cost - `type-never-diverge` - Use
!(never type) for functions that never return - `type-generic-bounds` - Add trait bounds only where needed, prefer where clauses for readability
- `type-no-stringly` - Avoid stringly-typed APIs; use enums, newtypes, or validated types
- `type-repr-transparent` - Use
#[repr(transparent)]for newtypes in FFI contexts - `type-deref-coercion` - Implement
Deref/DerefMutonly for smart-pointer and transparent wrapper types - `type-display-vs-debug` - Use
Displayfor user-facing output andDebugfor diagnostics; never swap them - `type-numeric-fmt` - Implement
LowerHex,UpperHex,Octal, andBinaryfor numeric newtypes
11. Trait & Generics Design (MEDIUM)
- `trait-associated-type-vs-generic` - Use an associated type when each impl has exactly one output type; use a generic parameter when a type can implement the trait for many input types
- `trait-blanket-impl` - Use a blanket impl
impl<T: Bound> Trait for Tto give behaviour to every type that satisfies a bound - `trait-coherence-newtype` - Respect the orphan rule; wrap a foreign type in a newtype to implement a foreign trait on it
- `trait-default-methods` - Define a trait in terms of a few required methods plus defaulted ones built on top of them
- `trait-dyn-vs-generic` - Choose static dispatch (generics /
impl Trait) vs dynamic dispatch (dyn Trait) deliberately - `trait-object-safety` - Keep a trait dyn-compatible (object-safe) when you need
dyn Trait
12. Conversions (MEDIUM)
- `conv-tryfrom-fallible` - Implement
TryFromfor fallible conversions instead of ad-hoc conversion functions - `conv-fromstr-parsing` - Implement
FromStrto enablestr::parsefor string-to-type conversions - `conv-asmut-mutable` - Accept
impl AsMut<T>for flexible mutable borrowed inputs instead of concrete mutable references
13. Const & Compile-Time (MEDIUM)
- `const-block` - Use inline
const { }blocks for compile-time evaluation and assertions - `const-fn` - Make functions
const fnwhen they can run at compile time - `const-generics` - Parameterize over values with const generics
<const N: usize> - `const-vs-static` - Use
constfor an inlined value andstaticfor a single addressed instance
14. Serde (MEDIUM)
- `serde-rename-all` - Match the external naming convention with
#[serde(rename_all = ...)] - `serde-default-compat` - Use
#[serde(default)]for optional and backward-compatible fields - `serde-skip-empty` - Omit empty fields with
skip_serializing_if - `serde-flatten` - Inline nested structs or capture extra keys with
#[serde(flatten)] - `serde-enum-representation` - Choose enum tagging deliberately: externally, internally, adjacently tagged, or untagged
- `serde-deny-unknown-fields` - Reject unexpected keys with
#[serde(deny_unknown_fields)] - `serde-custom-with` - Customize a field's (de)serialization with
with/serialize_with/deserialize_with - `serde-try-from-validate` - Validate while deserializing with
#[serde(try_from = "Raw")]
15. Pattern Matching (MEDIUM)
- `pat-let-else` - Use
let ... elsefor early-return pattern extraction - `pat-matches-macro` - Use
matches!()for boolean pattern tests - `pat-if-let-chains` - Use
if letchains to combine pattern bindings and conditions - `pat-exhaustive-enum` - Match owned enums exhaustively; avoid catch-all
_that hides new variants - `pat-at-bindings` - Use
@bindings to capture a value while matching it against a pattern
16. Macros (MEDIUM)
- `macro-prefer-functions` - Reach for a macro only when a function or generic cannot express it
- `macro-rules-hygiene` - Rely on
macro_rules!hygiene and use$cratefor paths to your crate's items - `macro-fragment-specifiers` - Capture with precise fragment specifiers, not raw
:tt, where you can - `macro-export-crate-path` - Export declarative macros with
#[macro_export]and a clean import path - `macro-private-helpers` - Hide macro-generated helper items behind a
#[doc(hidden)] pub mod __private - `macro-proc-two-crate` - Put procedural macros in a dedicated
proc-macro = truecrate and re-export from the facade - `macro-proc-syn-quote` - Build procedural macros with
syn,quote, andproc-macro2 - `macro-proc-error-spans` - Report proc-macro errors as spanned compile errors, never by panicking
17. Closures (MEDIUM)
- `closure-fn-trait-bounds` - Require the least restrictive
Fntrait a callback needs (FnOnce⊇FnMut⊇Fn) - `closure-impl-fn-return` - Return closures as
impl Fn/FnMut/FnOnce, notBox<dyn Fn> - `closure-move-capture` - Use
movefor closures that outlive the current scope; clone beforemoveto keep the original - `closure-static-vs-dyn` - Accept
impl Fn(generic) for hot callbacks; use&dyn Fn/Box<dyn Fn>to cut code size or to store them - `closure-disjoint-capture` - Capture only what you use; lean on edition-2021 disjoint closure captures
18. Collections (MEDIUM)
- `coll-binaryheap` - Use
BinaryHeapfor a priority queue or repeated max-extraction - `coll-map-choice` - Pick the map by access pattern:
HashMap(fast, unordered),BTreeMap(sorted / range queries),IndexMap(insertion order) - `coll-seq-choice` - Default to
Vec; useVecDequefor queue/deque behaviour; avoidLinkedList - `coll-set-membership` - Use
HashSet/BTreeSetfor membership tests and dedup, not linearVec::contains
19. Naming Conventions (MEDIUM)
- `name-types-camel` - Use
UpperCamelCasefor types, traits, and enum names - `name-variants-camel` - Use
UpperCamelCasefor enum variants - `name-funcs-snake` - Use
snake_casefor functions, methods, variables, and modules - `name-consts-screaming` - Use
SCREAMING_SNAKE_CASEfor constants and statics - `name-lifetime-short` - Use short, conventional lifetime names:
'a,'b,'de,'src - `name-type-param-single` - Use single uppercase letters for type parameters:
T,E,K,V - `name-as-free` -
as_prefix: free reference conversion - `name-to-expensive` - Use
to_prefix for expensive conversions that allocate or compute - `name-into-ownership` - Use
into_prefix for ownership-consuming conversions - `name-no-get-prefix` - Omit get_ prefix for simple getters
- `name-is-has-bool` - Use
is_,has_,can_,should_prefixes for boolean-returning methods - `name-iter-convention` - Use iter/itermut/intoiter for iterator methods
- `name-iter-method` - Name iterator methods
iter(),iter_mut(), andinto_iter()consistently - `name-iter-type-match` - Name iterator types after their source method
- `name-acronym-word` - Treat acronyms as words in identifiers:
HttpServer, notHTTPServer - `name-crate-no-rs` - Don't suffix crate names with
-rsor-rust
20. Testing (MEDIUM)
- `test-cfg-test-module` - Put unit tests in
#[cfg(test)] mod tests { }within each module - `test-use-super` - Use
use super::*;in test modules to access parent module items - `test-integration-dir` - Put integration tests in the
tests/directory - `test-descriptive-names` - Use descriptive test names that explain what is being tested
- `test-arrange-act-assert` - Structure tests with clear Arrange, Act, Assert sections
- `test-proptest-properties` - Use proptest for property-based testing
- `test-mockall-mocking` - Use mockall for trait mocking
- `test-mock-traits` - Use traits for dependencies to enable mocking in tests
- `test-fixture-raii` - Use RAII pattern (Drop trait) for automatic test cleanup
- `test-tokio-async` - Use
#[tokio::test]for async tests - `test-should-panic` - Use
#[should_panic]to test that code panics as expected - `test-criterion-bench` - Use
criterionfor benchmarking - `test-doctest-examples` - Keep documentation examples as executable doctests
- `test-loom-concurrency` - Use
loomto exhaustively test lock-free and concurrent code - `test-snapshot-testing` - Use snapshot testing (insta) for complex or serialized output
21. Documentation (MEDIUM)
- `doc-all-public` - Document all public items with
///doc comments - `doc-module-inner` - Use
//!for module-level documentation - `doc-examples-section` - Include
# Exampleswith runnable code - `doc-errors-section` - Include
# Errorssection for fallible functions - `doc-panics-section` - Include
# Panicssection for functions that can panic - `doc-safety-section` - Include
# Safetysection for unsafe functions - `doc-question-mark` - Use
?in examples, not.unwrap() - `doc-hidden-setup` - Use
#prefix to hide example setup code - `doc-intra-links` - Use intra-doc links to reference types and items
- `doc-link-types` - Use intra-doc links to connect related types and functions
- `doc-cargo-metadata` - Fill
Cargo.tomlmetadata for published crates - `doc-crate-readme` - Unify the README and crate root docs with
#![doc = include_str!("../README.md")]
22. Observability (MEDIUM)
- `obs-tracing-over-log` - Use
tracingfor structured, span-aware diagnostics instead ofprintln!or barelog - `obs-library-facade` - Libraries emit through the tracing/log facade and never install a subscriber
- `obs-structured-fields` - Record structured key-value fields, not values interpolated into the message string
- `obs-instrument-spans` - Use
#[tracing::instrument]and spans to attach context to async tasks and requests - `obs-levels-filter` - Use log levels meaningfully and filter with
EnvFilter/RUST_LOG - `obs-error-chain` - Log errors with their full source chain, and log each error exactly once
- `obs-no-sensitive-data` - Never log secrets or PII; redact or skip them
23. Performance Patterns (MEDIUM)
- `perf-iter-over-index` - Prefer iterators over manual indexing
- `perf-iter-lazy` - Keep iterators lazy, collect only when needed
- `perf-collect-once` - Don't collect intermediate iterators
- `perf-entry-api` - Use entry API for map insert-or-update
- `perf-drain-reuse` - Use drain to reuse allocations
- `perf-extend-batch` - Use extend for batch insertions
- `perf-chain-avoid` - Avoid chain in hot loops
- `perf-collect-into` - Use collect_into for reusing containers
- `perf-black-box-bench` - Use black_box in benchmarks
- `perf-release-profile` - Optimize release profile settings
- `perf-profile-first` - Profile before optimizing
- `perf-ahash` - Use a faster hasher (
ahash/FxHashMap) when DoS resistance is not needed - `perf-io-buffering` - Wrap
Read/WriteinBufReader/BufWriterfor many small operations
24. Project Structure (LOW)
- `proj-lib-main-split` - Keep
main.rsminimal, logic inlib.rs - `proj-mod-by-feature` - Organize modules by feature, not type
- `proj-flat-small` - Keep small projects flat
- `proj-mod-rs-dir` - Use mod.rs for multi-file modules
- `proj-pub-crate-internal` - Use pub(crate) for internal APIs
- `proj-pub-super-parent` - Use pub(super) for parent-only visibility
- `proj-pub-use-reexport` - Use pub use for clean public API
- `proj-prelude-module` - Create prelude module for common imports
- `proj-bin-dir` - Put multiple binaries in src/bin/
- `proj-workspace-large` - Use workspaces for large projects
- `proj-workspace-deps` - Use workspace dependency inheritance for consistent versions across crates
- `proj-feature-additive` - Design Cargo features to be strictly additive
- `proj-msrv-declare` - Declare
rust-version(MSRV) in Cargo.toml and test it in CI - `proj-build-rs-minimal` - Keep
build.rsminimal, deterministic, and idempotent
25. Clippy & Linting (LOW)
- `lint-deny-correctness` -
#![deny(clippy::correctness)] - `lint-warn-suspicious` - Enable clippy::suspicious for likely bugs
- `lint-warn-style` - Enable clippy::style for idiomatic code
- `lint-warn-complexity` - Enable clippy::complexity for simpler code
- `lint-warn-perf` - Enable clippy::perf for performance improvements
- `lint-pedantic-selective` - Enable clippy::pedantic selectively
- `lint-missing-docs` - Warn on missing documentation for public items
- `lint-unsafe-doc` - Require documentation for unsafe blocks
- `lint-cargo-metadata` - Enable clippy::cargo for published crates
- `lint-rustfmt-check` - Run cargo fmt --check in CI
- `lint-workspace-lints` - Configure lints at workspace level for consistent enforcement
- `lint-cfg-check` - Enable
unexpected_cfgsand declare known cfgs to catch feature-gate typos - `lint-clippy-nursery-selected` - Enable high-value
clippy::nurserylints selectively, not the whole group
26. Anti-patterns (REFERENCE)
- `anti-unwrap-abuse` - Don't use
.unwrap()in production code - `anti-expect-lazy` - Don't use expect for recoverable errors
- `anti-clone-excessive` - Don't clone when borrowing works
- `anti-lock-across-await` - Don't hold locks across await points
- `anti-string-for-str` - Don't accept &String when &str works
- `anti-vec-for-slice` - Don't accept &Vec<T> when &[T] works
- `anti-index-over-iter` - Don't use indexing when iterators work
- `anti-panic-expected` - Don't panic on expected or recoverable errors
- `anti-empty-catch` - Don't silently ignore errors
- `anti-over-abstraction` - Don't over-abstract with excessive generics
- `anti-premature-optimize` - Don't optimize before profiling
- `anti-type-erasure` - Don't use Box<dyn Trait> when impl Trait works
- `anti-format-hot-path` - Don't use format! in hot paths
- `anti-collect-intermediate` - Don't collect intermediate iterators
- `anti-stringly-typed` - Don't use strings where enums or newtypes would provide type safety
Recommended Cargo.toml Settings
[profile.release]
opt-level = 3
lto = "fat"
codegen-units = 1
panic = "abort"
strip = true
[profile.bench]
inherits = "release"
debug = true
strip = false
[profile.dev]
opt-level = 0
debug = true
[profile.dev.package."*"]
opt-level = 3 # Optimize dependencies in devHow to Use
This skill provides rule identifiers for quick reference. When generating or reviewing Rust code:
- Check relevant category based on task type
- Apply rules with matching prefix
- Prioritize CRITICAL > HIGH > MEDIUM > LOW
- Read rule files in
rules/for detailed examples
Rule Application by Task
| Task | Primary Categories |
|---|---|
| New function | own-, err-, name-, pat- |
| New struct/API | api-, type-, conv-, doc- |
| Async code | async-, own- |
| Concurrency / parallelism | conc-, async-, own- |
| Unsafe code | unsafe-, type-, test- |
| Error handling | err-, api-, pat- |
| Type conversions | conv-, api- |
| Serialization (serde) | serde-, type-, api- |
| Numeric / arithmetic | num-, type- |
| Macros / code generation | macro-, anti- |
| Closures / callbacks | closure-, type- |
| Logging / observability | obs-, err- |
| Memory optimization | mem-, own-, perf- |
| Performance tuning | opt-, mem-, perf- |
| Code review | anti-, lint- |
Sources & Attribution
This skill is an independent synthesis of official Rust guidance, well-known books, and patterns from widely-used crates. It is not affiliated with or endorsed by the Rust project or any crate author; the text and code examples are original.
Official Rust documentation
- The Rust Reference
- Rust API Guidelines
- The Rustonomicon (unsafe code)
- Rust 2024 Edition Guide
- The Cargo Book
- Standard library docs and release notes
Books & guides
- The Rust Performance Book — Nicholas Nethercote
- Rust Design Patterns — rust-unofficial
- Rust Atomics and Locks — Mara Bos
- Effective Rust — David Drysdale
Tooling
Real-world codebases studied for idioms
- ripgrep, tokio, serde, clap, polars, axum, cargo, hyper, bevy, rayon, and dtolnay's crates (thiserror, anyhow, syn)
This project is MIT-licensed. Referenced upstream materials remain under their own licenses (the official Rust docs and API Guidelines are dual MIT / Apache-2.0).
