agy-superpowers 5.2.2 → 5.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -150
- package/package.json +1 -1
- package/template/agent/rules/scratch-scripts.md +37 -0
- package/template/agent/rules/superpowers.md +4 -51
- package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
- package/template/agent/skills/analytics-setup/SKILL.md +0 -51
- package/template/agent/skills/api-design/SKILL.md +0 -193
- package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
- package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
- package/template/agent/skills/backend-developer/SKILL.md +0 -148
- package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
- package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
- package/template/agent/skills/community-manager/SKILL.md +0 -115
- package/template/agent/skills/content-marketer/SKILL.md +0 -111
- package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
- package/template/agent/skills/cto-architect/SKILL.md +0 -133
- package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
- package/template/agent/skills/data-analyst/SKILL.md +0 -147
- package/template/agent/skills/devops-engineer/SKILL.md +0 -117
- package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
- package/template/agent/skills/game-design/SKILL.md +0 -194
- package/template/agent/skills/game-developer/SKILL.md +0 -175
- package/template/agent/skills/growth-hacker/SKILL.md +0 -122
- package/template/agent/skills/idea-validator/SKILL.md +0 -55
- package/template/agent/skills/indie-legal/SKILL.md +0 -53
- package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
- package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
- package/template/agent/skills/launch-strategist/SKILL.md +0 -62
- package/template/agent/skills/market-researcher/SKILL.md +0 -53
- package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
- package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
- package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
- package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
- package/template/agent/skills/real-time-features/SKILL.md +0 -194
- package/template/agent/skills/retention-specialist/SKILL.md +0 -123
- package/template/agent/skills/rust-developer/SKILL.md +0 -281
- package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
- package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
- package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
- package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
- package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
- package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
- package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
- package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
- package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
- package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
- package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
- package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
- package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
- package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
- package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
- package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
- package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
- package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
- package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
- package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
- package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
- package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
- package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
- package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
- package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
- package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
- package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
- package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
- package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
- package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
- package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
- package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
- package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
- package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
- package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
- package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
- package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
- package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
- package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
- package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
- package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
- package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
- package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
- package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
- package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
- package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
- package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
- package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
- package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
- package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
- package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
- package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
- package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
- package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
- package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
- package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
- package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
- package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
- package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
- package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
- package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
- package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
- package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
- package/template/agent/skills/saas-architect/SKILL.md +0 -139
- package/template/agent/skills/security-engineer/SKILL.md +0 -133
- package/template/agent/skills/seo-specialist/SKILL.md +0 -130
- package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
# lint-workspace-lints
|
|
2
|
-
|
|
3
|
-
> Configure lints at workspace level for consistent enforcement
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Without centralized lint configuration, each crate develops its own standards (or none). Workspace-level lints (Rust 1.74+) ensure consistent code quality across all crates. Denied lints catch issues in CI before they reach production.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```toml
|
|
12
|
-
# crate-a/Cargo.toml - strict
|
|
13
|
-
[lints.clippy]
|
|
14
|
-
unwrap_used = "deny"
|
|
15
|
-
|
|
16
|
-
# crate-b/Cargo.toml - lenient
|
|
17
|
-
# No lint config
|
|
18
|
-
|
|
19
|
-
# crate-c/Cargo.toml - different
|
|
20
|
-
[lints.clippy]
|
|
21
|
-
unwrap_used = "warn"
|
|
22
|
-
|
|
23
|
-
# Inconsistent enforcement, some issues slip through
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Good
|
|
27
|
-
|
|
28
|
-
```toml
|
|
29
|
-
# Root Cargo.toml
|
|
30
|
-
[workspace.lints.rust]
|
|
31
|
-
unsafe_code = "deny"
|
|
32
|
-
missing_docs = "warn"
|
|
33
|
-
|
|
34
|
-
[workspace.lints.clippy]
|
|
35
|
-
# Correctness
|
|
36
|
-
unwrap_used = "deny"
|
|
37
|
-
expect_used = "warn"
|
|
38
|
-
panic = "deny"
|
|
39
|
-
|
|
40
|
-
# Style
|
|
41
|
-
needless_pass_by_value = "warn"
|
|
42
|
-
redundant_clone = "warn"
|
|
43
|
-
|
|
44
|
-
# Complexity
|
|
45
|
-
cognitive_complexity = "warn"
|
|
46
|
-
|
|
47
|
-
[workspace.lints.rustdoc]
|
|
48
|
-
broken_intra_doc_links = "deny"
|
|
49
|
-
|
|
50
|
-
# crate-a/Cargo.toml
|
|
51
|
-
[lints]
|
|
52
|
-
workspace = true
|
|
53
|
-
|
|
54
|
-
# crate-b/Cargo.toml
|
|
55
|
-
[lints]
|
|
56
|
-
workspace = true
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Recommended Lint Configuration
|
|
60
|
-
|
|
61
|
-
```toml
|
|
62
|
-
# Root Cargo.toml
|
|
63
|
-
[workspace.lints.rust]
|
|
64
|
-
# Safety
|
|
65
|
-
unsafe_code = "deny"
|
|
66
|
-
missing_debug_implementations = "warn"
|
|
67
|
-
|
|
68
|
-
# Quality
|
|
69
|
-
unused_results = "warn"
|
|
70
|
-
unused_qualifications = "warn"
|
|
71
|
-
|
|
72
|
-
[workspace.lints.clippy]
|
|
73
|
-
# === Correctness (deny) ===
|
|
74
|
-
correctness = { level = "deny", priority = -1 }
|
|
75
|
-
|
|
76
|
-
# === Suspicious (deny) ===
|
|
77
|
-
suspicious = { level = "deny", priority = -1 }
|
|
78
|
-
|
|
79
|
-
# === Style (warn) ===
|
|
80
|
-
style = { level = "warn", priority = -1 }
|
|
81
|
-
|
|
82
|
-
# === Complexity (warn) ===
|
|
83
|
-
complexity = { level = "warn", priority = -1 }
|
|
84
|
-
|
|
85
|
-
# === Perf (warn) ===
|
|
86
|
-
perf = { level = "warn", priority = -1 }
|
|
87
|
-
|
|
88
|
-
# === Pedantic (selective) ===
|
|
89
|
-
# Not all pedantic lints are useful
|
|
90
|
-
doc_markdown = "warn"
|
|
91
|
-
needless_pass_by_value = "warn"
|
|
92
|
-
redundant_closure_for_method_calls = "warn"
|
|
93
|
-
semicolon_if_nothing_returned = "warn"
|
|
94
|
-
|
|
95
|
-
# === Nursery (selective) ===
|
|
96
|
-
cognitive_complexity = "warn"
|
|
97
|
-
useless_let_if_seq = "warn"
|
|
98
|
-
|
|
99
|
-
# === Restriction (selective) ===
|
|
100
|
-
unwrap_used = "deny"
|
|
101
|
-
expect_used = "warn"
|
|
102
|
-
dbg_macro = "warn"
|
|
103
|
-
print_stdout = "warn" # Use logging instead
|
|
104
|
-
todo = "warn"
|
|
105
|
-
|
|
106
|
-
[workspace.lints.rustdoc]
|
|
107
|
-
broken_intra_doc_links = "deny"
|
|
108
|
-
private_intra_doc_links = "warn"
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## Per-Crate Overrides
|
|
112
|
-
|
|
113
|
-
```toml
|
|
114
|
-
# crate-with-binary/Cargo.toml
|
|
115
|
-
[lints]
|
|
116
|
-
workspace = true
|
|
117
|
-
|
|
118
|
-
# Binary entry point can use unwrap
|
|
119
|
-
[lints.clippy]
|
|
120
|
-
unwrap_used = "allow"
|
|
121
|
-
|
|
122
|
-
# test-utils/Cargo.toml
|
|
123
|
-
[lints]
|
|
124
|
-
workspace = true
|
|
125
|
-
|
|
126
|
-
# Test utilities can print
|
|
127
|
-
[lints.clippy]
|
|
128
|
-
print_stdout = "allow"
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## CI Integration
|
|
132
|
-
|
|
133
|
-
```yaml
|
|
134
|
-
# .github/workflows/ci.yml
|
|
135
|
-
jobs:
|
|
136
|
-
lint:
|
|
137
|
-
runs-on: ubuntu-latest
|
|
138
|
-
steps:
|
|
139
|
-
- uses: actions/checkout@v4
|
|
140
|
-
- uses: dtolnay/rust-toolchain@stable
|
|
141
|
-
with:
|
|
142
|
-
components: clippy
|
|
143
|
-
|
|
144
|
-
- name: Clippy
|
|
145
|
-
run: cargo clippy --workspace --all-targets -- -D warnings
|
|
146
|
-
|
|
147
|
-
- name: Rustdoc
|
|
148
|
-
run: RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## Lint Categories
|
|
152
|
-
|
|
153
|
-
```toml
|
|
154
|
-
# Category-level configuration
|
|
155
|
-
[workspace.lints.clippy]
|
|
156
|
-
# All lints in category at once
|
|
157
|
-
correctness = { level = "deny", priority = -1 }
|
|
158
|
-
suspicious = { level = "deny", priority = -1 }
|
|
159
|
-
style = { level = "warn", priority = -1 }
|
|
160
|
-
complexity = { level = "warn", priority = -1 }
|
|
161
|
-
perf = { level = "warn", priority = -1 }
|
|
162
|
-
pedantic = { level = "warn", priority = -1 }
|
|
163
|
-
|
|
164
|
-
# Then override specific lints (higher priority)
|
|
165
|
-
missing_errors_doc = "allow" # Override pedantic
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## See Also
|
|
169
|
-
|
|
170
|
-
- [lint-deny-correctness](./lint-deny-correctness.md) - Critical lints
|
|
171
|
-
- [proj-workspace-deps](./proj-workspace-deps.md) - Workspace configuration
|
|
172
|
-
- [anti-unwrap-abuse](./anti-unwrap-abuse.md) - unwrap lints
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
# mem-arena-allocator
|
|
2
|
-
|
|
3
|
-
> Use arena allocators for batch allocations
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Arena allocators (bump allocators) allocate memory from a contiguous region, making allocation extremely fast (just bump a pointer). All allocations are freed at once when the arena is dropped. Perfect for request-scoped or parse-tree allocations.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Many small allocations during parsing
|
|
13
|
-
fn parse(input: &str) -> Vec<Node> {
|
|
14
|
-
let mut nodes = Vec::new();
|
|
15
|
-
for token in tokenize(input) {
|
|
16
|
-
nodes.push(Box::new(Node::new(token))); // Heap alloc per node!
|
|
17
|
-
}
|
|
18
|
-
nodes
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Per-request allocations add up
|
|
22
|
-
fn handle_request(req: Request) -> Response {
|
|
23
|
-
let headers = parse_headers(&req); // Allocates
|
|
24
|
-
let body = parse_body(&req); // Allocates
|
|
25
|
-
let response = generate_response(); // Allocates
|
|
26
|
-
// All freed individually at end
|
|
27
|
-
response
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Good
|
|
32
|
-
|
|
33
|
-
```rust
|
|
34
|
-
use bumpalo::Bump;
|
|
35
|
-
|
|
36
|
-
// All nodes allocated from same arena
|
|
37
|
-
fn parse<'a>(input: &str, arena: &'a Bump) -> Vec<&'a Node> {
|
|
38
|
-
let mut nodes = Vec::new();
|
|
39
|
-
for token in tokenize(input) {
|
|
40
|
-
let node = arena.alloc(Node::new(token)); // Fast bump!
|
|
41
|
-
nodes.push(node);
|
|
42
|
-
}
|
|
43
|
-
nodes
|
|
44
|
-
} // Arena freed all at once
|
|
45
|
-
|
|
46
|
-
// Per-request arena
|
|
47
|
-
fn handle_request(req: Request) -> Response {
|
|
48
|
-
let arena = Bump::new();
|
|
49
|
-
|
|
50
|
-
let headers = parse_headers(&req, &arena);
|
|
51
|
-
let body = parse_body(&req, &arena);
|
|
52
|
-
let response = generate_response(&arena);
|
|
53
|
-
|
|
54
|
-
// Convert to owned response before arena drops
|
|
55
|
-
response.to_owned()
|
|
56
|
-
} // All request memory freed instantly
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Thread-Local Scratch Arena Pattern
|
|
60
|
-
|
|
61
|
-
```rust
|
|
62
|
-
use bumpalo::Bump;
|
|
63
|
-
use std::cell::RefCell;
|
|
64
|
-
|
|
65
|
-
thread_local! {
|
|
66
|
-
static SCRATCH: RefCell<Bump> = RefCell::new(Bump::with_capacity(4 * 1024));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
fn with_scratch<T>(f: impl FnOnce(&Bump) -> T) -> T {
|
|
70
|
-
SCRATCH.with(|scratch| {
|
|
71
|
-
let arena = scratch.borrow();
|
|
72
|
-
let result = f(&arena);
|
|
73
|
-
result
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
fn reset_scratch() {
|
|
78
|
-
SCRATCH.with(|scratch| {
|
|
79
|
-
scratch.borrow_mut().reset();
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Usage
|
|
84
|
-
fn process_batch(items: &[Item]) -> Vec<Output> {
|
|
85
|
-
with_scratch(|arena| {
|
|
86
|
-
let temp_data: Vec<&TempData> = items
|
|
87
|
-
.iter()
|
|
88
|
-
.map(|item| arena.alloc(compute_temp(item)))
|
|
89
|
-
.collect();
|
|
90
|
-
|
|
91
|
-
// Use temp_data...
|
|
92
|
-
let result = finalize(&temp_data);
|
|
93
|
-
|
|
94
|
-
reset_scratch(); // Reuse arena memory
|
|
95
|
-
result
|
|
96
|
-
})
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## Evidence from ROC Compiler
|
|
101
|
-
|
|
102
|
-
```rust
|
|
103
|
-
// https://github.com/roc-lang/roc/blob/main/crates/compiler/solve/src/to_var.rs
|
|
104
|
-
std::thread_local! {
|
|
105
|
-
static SCRATCHPAD: RefCell<Option<bumpalo::Bump>> =
|
|
106
|
-
RefCell::new(Some(bumpalo::Bump::with_capacity(4 * 1024)));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
fn take_scratchpad() -> bumpalo::Bump {
|
|
110
|
-
SCRATCHPAD.with(|f| f.take().unwrap())
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
fn put_scratchpad(scratchpad: bumpalo::Bump) {
|
|
114
|
-
SCRATCHPAD.with(|f| {
|
|
115
|
-
f.replace(Some(scratchpad));
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Bumpalo Collections
|
|
121
|
-
|
|
122
|
-
```rust
|
|
123
|
-
use bumpalo::Bump;
|
|
124
|
-
use bumpalo::collections::{Vec, String};
|
|
125
|
-
|
|
126
|
-
fn process<'a>(arena: &'a Bump, input: &str) -> Vec<'a, String<'a>> {
|
|
127
|
-
let mut results = Vec::new_in(arena);
|
|
128
|
-
|
|
129
|
-
for word in input.split_whitespace() {
|
|
130
|
-
let mut s = String::new_in(arena);
|
|
131
|
-
s.push_str(word);
|
|
132
|
-
s.push_str("_processed");
|
|
133
|
-
results.push(s);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
results // All allocated in arena
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## When to Use Arenas
|
|
141
|
-
|
|
142
|
-
| Situation | Use Arena? |
|
|
143
|
-
|-----------|-----------|
|
|
144
|
-
| Parsing (AST nodes) | Yes |
|
|
145
|
-
| Request handling | Yes |
|
|
146
|
-
| Batch processing | Yes |
|
|
147
|
-
| Long-lived data | No |
|
|
148
|
-
| Data escaping scope | No (or copy out) |
|
|
149
|
-
| Simple programs | Overkill |
|
|
150
|
-
|
|
151
|
-
## Performance Impact
|
|
152
|
-
|
|
153
|
-
```rust
|
|
154
|
-
// Benchmarks from production systems:
|
|
155
|
-
// - Individual allocations: ~25-50ns each
|
|
156
|
-
// - Arena bump: ~1-2ns each (20-50x faster)
|
|
157
|
-
// - Arena reset: O(1) regardless of allocation count
|
|
158
|
-
|
|
159
|
-
// Memory overhead:
|
|
160
|
-
// - Arena wastes some memory (unused capacity)
|
|
161
|
-
// - But eliminates per-allocation metadata overhead
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## See Also
|
|
165
|
-
|
|
166
|
-
- [mem-with-capacity](mem-with-capacity.md) - Pre-allocate when size is known
|
|
167
|
-
- [mem-reuse-collections](mem-reuse-collections.md) - Reuse collections with clear()
|
|
168
|
-
- [opt-profile-first](perf-profile-first.md) - Profile to verify benefit
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# mem-arrayvec
|
|
2
|
-
|
|
3
|
-
> Use `ArrayVec<T, N>` for fixed-capacity collections that never heap-allocate
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
`ArrayVec` from the `arrayvec` crate provides Vec-like API with a compile-time maximum capacity, storing all elements inline on the stack. Unlike `SmallVec` which can spill to heap, `ArrayVec` guarantees no heap allocation—if you exceed capacity, it returns an error or panics. This is ideal for embedded systems, real-time code, or when you have a hard upper bound.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Vec always heap-allocates, even for small collections
|
|
13
|
-
fn parse_options(input: &str) -> Vec<Option> {
|
|
14
|
-
let mut options = Vec::new(); // Heap allocation
|
|
15
|
-
for part in input.split(',').take(8) { // Know we never exceed 8
|
|
16
|
-
options.push(parse_option(part));
|
|
17
|
-
}
|
|
18
|
-
options
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Or SmallVec when you truly can't exceed capacity
|
|
22
|
-
use smallvec::SmallVec;
|
|
23
|
-
fn get_flags() -> SmallVec<[Flag; 4]> {
|
|
24
|
-
// SmallVec CAN heap-allocate if pushed beyond 4
|
|
25
|
-
// That might be unexpected in no-alloc contexts
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Good
|
|
30
|
-
|
|
31
|
-
```rust
|
|
32
|
-
use arrayvec::ArrayVec;
|
|
33
|
-
|
|
34
|
-
// Guaranteed no heap allocation
|
|
35
|
-
fn parse_options(input: &str) -> ArrayVec<Option, 8> {
|
|
36
|
-
let mut options = ArrayVec::new();
|
|
37
|
-
for part in input.split(',') {
|
|
38
|
-
if options.try_push(parse_option(part)).is_err() {
|
|
39
|
-
break; // Capacity reached, stop
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
options
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// For embedded/no_std contexts
|
|
46
|
-
#[no_std]
|
|
47
|
-
fn collect_readings() -> ArrayVec<SensorReading, 16> {
|
|
48
|
-
let mut readings = ArrayVec::new();
|
|
49
|
-
for sensor in SENSORS.iter() {
|
|
50
|
-
readings.push(sensor.read()); // Panics if > 16
|
|
51
|
-
}
|
|
52
|
-
readings
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## ArrayVec vs SmallVec vs Vec
|
|
57
|
-
|
|
58
|
-
| Type | Stack | Heap | Use When |
|
|
59
|
-
|------|-------|------|----------|
|
|
60
|
-
| `Vec<T>` | Never | Always | Unknown size, may grow indefinitely |
|
|
61
|
-
| `SmallVec<[T; N]>` | Up to N | Beyond N | Usually small, occasionally large |
|
|
62
|
-
| `ArrayVec<T, N>` | Always | Never | Hard limit, no heap allowed |
|
|
63
|
-
|
|
64
|
-
## API Patterns
|
|
65
|
-
|
|
66
|
-
```rust
|
|
67
|
-
use arrayvec::ArrayVec;
|
|
68
|
-
|
|
69
|
-
let mut arr: ArrayVec<i32, 4> = ArrayVec::new();
|
|
70
|
-
|
|
71
|
-
// Push with potential panic (like Vec)
|
|
72
|
-
arr.push(1);
|
|
73
|
-
arr.push(2);
|
|
74
|
-
|
|
75
|
-
// Safe push - returns Err if full
|
|
76
|
-
match arr.try_push(3) {
|
|
77
|
-
Ok(()) => println!("Added"),
|
|
78
|
-
Err(err) => println!("Full, couldn't add {}", err.element()),
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Check capacity
|
|
82
|
-
assert!(arr.len() < arr.capacity());
|
|
83
|
-
|
|
84
|
-
// Remaining capacity
|
|
85
|
-
let remaining = arr.remaining_capacity();
|
|
86
|
-
|
|
87
|
-
// Is it full?
|
|
88
|
-
if arr.is_full() {
|
|
89
|
-
arr.pop();
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// From iterator with limit
|
|
93
|
-
let arr: ArrayVec<_, 10> = (0..100)
|
|
94
|
-
.filter(|x| x % 2 == 0)
|
|
95
|
-
.take(10) // Important: don't exceed capacity
|
|
96
|
-
.collect();
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## ArrayString for Stack Strings
|
|
100
|
-
|
|
101
|
-
```rust
|
|
102
|
-
use arrayvec::ArrayString;
|
|
103
|
-
|
|
104
|
-
// Stack-allocated string with max capacity
|
|
105
|
-
let mut s: ArrayString<64> = ArrayString::new();
|
|
106
|
-
s.push_str("Hello, ");
|
|
107
|
-
s.push_str("world!");
|
|
108
|
-
|
|
109
|
-
// No heap allocation for small strings
|
|
110
|
-
fn format_code(code: u32) -> ArrayString<16> {
|
|
111
|
-
let mut s = ArrayString::new();
|
|
112
|
-
write!(&mut s, "CODE-{:04}", code).unwrap();
|
|
113
|
-
s
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## When NOT to Use ArrayVec
|
|
118
|
-
|
|
119
|
-
```rust
|
|
120
|
-
// ❌ When size varies widely
|
|
121
|
-
fn parse_json_array(json: &str) -> ArrayVec<Value, ???> {
|
|
122
|
-
// What capacity? JSON arrays can be any size
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// ❌ When capacity is very large
|
|
126
|
-
let big: ArrayVec<u8, 1_000_000> = ArrayVec::new(); // 1MB on stack = bad
|
|
127
|
-
|
|
128
|
-
// ✅ Use SmallVec or Vec instead for these cases
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Cargo.toml
|
|
132
|
-
|
|
133
|
-
```toml
|
|
134
|
-
[dependencies]
|
|
135
|
-
arrayvec = "0.7"
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## See Also
|
|
139
|
-
|
|
140
|
-
- [mem-smallvec](./mem-smallvec.md) - When heap fallback is acceptable
|
|
141
|
-
- [mem-with-capacity](./mem-with-capacity.md) - Pre-allocating Vec capacity
|
|
142
|
-
- [own-move-large](./own-move-large.md) - Large stack types considerations
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
# mem-assert-type-size
|
|
2
|
-
|
|
3
|
-
> Use static assertions to guard against accidental type size growth
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Adding a field to a frequently-instantiated struct can silently bloat memory usage. Static size assertions catch this at compile time, making size changes intentional rather than accidental. This is especially important for types stored in large collections or passed frequently by value.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
struct Event {
|
|
13
|
-
timestamp: u64,
|
|
14
|
-
kind: EventKind,
|
|
15
|
-
payload: [u8; 32],
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Later, someone adds a field without realizing the impact
|
|
19
|
-
struct Event {
|
|
20
|
-
timestamp: u64,
|
|
21
|
-
kind: EventKind,
|
|
22
|
-
payload: [u8; 32],
|
|
23
|
-
metadata: String, // Silently adds 24 bytes!
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// 10 million events now use 240MB more memory
|
|
27
|
-
// No warning, no review trigger
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Good
|
|
31
|
-
|
|
32
|
-
```rust
|
|
33
|
-
struct Event {
|
|
34
|
-
timestamp: u64,
|
|
35
|
-
kind: EventKind,
|
|
36
|
-
payload: [u8; 32],
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Static assertion - breaks compile if size changes
|
|
40
|
-
const _: () = assert!(std::mem::size_of::<Event>() == 48);
|
|
41
|
-
|
|
42
|
-
// Or with static_assertions crate
|
|
43
|
-
use static_assertions::assert_eq_size;
|
|
44
|
-
assert_eq_size!(Event, [u8; 48]);
|
|
45
|
-
|
|
46
|
-
// Now adding metadata triggers compile error:
|
|
47
|
-
// error: assertion failed: std::mem::size_of::<Event>() == 48
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## static_assertions Crate
|
|
51
|
-
|
|
52
|
-
```rust
|
|
53
|
-
use static_assertions::{assert_eq_size, const_assert};
|
|
54
|
-
|
|
55
|
-
struct Critical {
|
|
56
|
-
id: u64,
|
|
57
|
-
flags: u32,
|
|
58
|
-
data: [u8; 16],
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Exact size assertion
|
|
62
|
-
assert_eq_size!(Critical, [u8; 32]);
|
|
63
|
-
|
|
64
|
-
// Maximum size assertion
|
|
65
|
-
const_assert!(std::mem::size_of::<Critical>() <= 64);
|
|
66
|
-
|
|
67
|
-
// Alignment assertion
|
|
68
|
-
const_assert!(std::mem::align_of::<Critical>() == 8);
|
|
69
|
-
|
|
70
|
-
// Compare sizes
|
|
71
|
-
assert_eq_size!(Critical, [u64; 4]);
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Built-in Const Assertions
|
|
75
|
-
|
|
76
|
-
```rust
|
|
77
|
-
// No external crate needed (Rust 1.57+)
|
|
78
|
-
struct Packet {
|
|
79
|
-
header: u32,
|
|
80
|
-
payload: [u8; 60],
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const _: () = assert!(
|
|
84
|
-
std::mem::size_of::<Packet>() == 64,
|
|
85
|
-
"Packet must be exactly 64 bytes for protocol compliance"
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
// Compile error shows custom message if assertion fails
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Documenting Size Constraints
|
|
92
|
-
|
|
93
|
-
```rust
|
|
94
|
-
/// Network protocol packet header.
|
|
95
|
-
///
|
|
96
|
-
/// # Size
|
|
97
|
-
///
|
|
98
|
-
/// This struct is guaranteed to be exactly 32 bytes to match
|
|
99
|
-
/// the network protocol specification. Any changes to fields
|
|
100
|
-
/// must maintain this size constraint.
|
|
101
|
-
#[repr(C)] // Predictable layout for FFI
|
|
102
|
-
struct Header {
|
|
103
|
-
version: u16,
|
|
104
|
-
flags: u16,
|
|
105
|
-
length: u32,
|
|
106
|
-
checksum: u64,
|
|
107
|
-
reserved: [u8; 16],
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const _: () = assert!(std::mem::size_of::<Header>() == 32);
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## Testing Size Stability
|
|
114
|
-
|
|
115
|
-
```rust
|
|
116
|
-
#[cfg(test)]
|
|
117
|
-
mod tests {
|
|
118
|
-
use super::*;
|
|
119
|
-
|
|
120
|
-
#[test]
|
|
121
|
-
fn critical_types_have_expected_sizes() {
|
|
122
|
-
// Document expected sizes in tests too
|
|
123
|
-
assert_eq!(std::mem::size_of::<Event>(), 48);
|
|
124
|
-
assert_eq!(std::mem::size_of::<Message>(), 64);
|
|
125
|
-
assert_eq!(std::mem::size_of::<Header>(), 32);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
#[test]
|
|
129
|
-
fn cache_line_aligned() {
|
|
130
|
-
// Verify cache-friendly sizing
|
|
131
|
-
assert!(std::mem::size_of::<HotData>() <= 64);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## When to Assert
|
|
137
|
-
|
|
138
|
-
```rust
|
|
139
|
-
// ✅ Types stored in large collections
|
|
140
|
-
struct Node { /* ... */ }
|
|
141
|
-
const _: () = assert!(std::mem::size_of::<Node>() <= 64);
|
|
142
|
-
|
|
143
|
-
// ✅ Types used in FFI / binary protocols
|
|
144
|
-
#[repr(C)]
|
|
145
|
-
struct WireFormat { /* ... */ }
|
|
146
|
-
const _: () = assert!(std::mem::size_of::<WireFormat>() == 256);
|
|
147
|
-
|
|
148
|
-
// ✅ Performance-critical types
|
|
149
|
-
struct HotPath { /* ... */ }
|
|
150
|
-
const _: () = assert!(std::mem::size_of::<HotPath>() <= 128);
|
|
151
|
-
|
|
152
|
-
// ❌ Skip for rarely-instantiated types
|
|
153
|
-
struct AppConfig { /* many fields */ }
|
|
154
|
-
// Size doesn't matter, only one instance
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Cargo.toml
|
|
158
|
-
|
|
159
|
-
```toml
|
|
160
|
-
[dependencies]
|
|
161
|
-
static_assertions = "1.1"
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## See Also
|
|
165
|
-
|
|
166
|
-
- [mem-smaller-integers](./mem-smaller-integers.md) - Choosing appropriate integer sizes
|
|
167
|
-
- [mem-box-large-variant](./mem-box-large-variant.md) - Managing enum variant sizes
|
|
168
|
-
- [opt-cache-friendly](./opt-cache-friendly.md) - Cache line considerations
|