agy-superpowers 5.2.1 → 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/patches/skills-patches.md +23 -0
- package/template/agent/rules/scratch-scripts.md +37 -0
- package/template/agent/rules/superpowers.md +6 -50
- package/template/agent/skills/brainstorming/SKILL.md +4 -3
- package/template/agent/skills/brainstorming/visual-companion.md +2 -3
- package/template/agent/skills/finishing-a-development-branch/SKILL.md +11 -16
- package/template/agent/skills/subagent-driven-development/SKILL.md +16 -0
- package/template/agent/skills/subagent-driven-development/implementer-prompt.md +4 -3
- package/template/agent/skills/using-git-worktrees/SKILL.md +3 -2
- package/template/agent/skills/using-superpowers/SKILL.md +8 -6
- package/template/agent/skills/using-superpowers/references/copilot-tools.md +52 -0
- package/template/agent/skills/writing-plans/SKILL.md +5 -3
- package/template/agent/skills/writing-skills/SKILL.md +1 -1
- package/template/agent/superpowers-version.json +2 -2
- package/template/agent/tmp/agent-config-backup.yml +9 -0
- 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,146 +0,0 @@
|
|
|
1
|
-
# api-from-not-into
|
|
2
|
-
|
|
3
|
-
> Implement `From<T>`, not `Into<U>` - From gives you Into for free
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
The standard library has a blanket implementation: `impl<T, U> Into<U> for T where U: From<T>`. This means implementing `From<T> for U` automatically gives you `Into<U> for T`. Implementing `Into` directly bypasses this and is considered non-idiomatic. Always implement `From`.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
struct UserId(u64);
|
|
13
|
-
|
|
14
|
-
// Non-idiomatic: implementing Into directly
|
|
15
|
-
impl Into<UserId> for u64 {
|
|
16
|
-
fn into(self) -> UserId {
|
|
17
|
-
UserId(self)
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Works, but now you can't use From syntax
|
|
22
|
-
let id = UserId::from(42); // Error: From not implemented
|
|
23
|
-
let id: UserId = 42.into(); // Works, but limited
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Good
|
|
27
|
-
|
|
28
|
-
```rust
|
|
29
|
-
struct UserId(u64);
|
|
30
|
-
|
|
31
|
-
// Idiomatic: implement From
|
|
32
|
-
impl From<u64> for UserId {
|
|
33
|
-
fn from(id: u64) -> Self {
|
|
34
|
-
UserId(id)
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Now both work automatically
|
|
39
|
-
let id = UserId::from(42); // From syntax
|
|
40
|
-
let id: UserId = 42.into(); // Into syntax (via blanket impl)
|
|
41
|
-
|
|
42
|
-
// And Into bound works in generics
|
|
43
|
-
fn process(id: impl Into<UserId>) {
|
|
44
|
-
let id: UserId = id.into();
|
|
45
|
-
}
|
|
46
|
-
process(42u64); // Works!
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Blanket Implementation
|
|
50
|
-
|
|
51
|
-
```rust
|
|
52
|
-
// This is in std, you don't write it
|
|
53
|
-
impl<T, U> Into<U> for T
|
|
54
|
-
where
|
|
55
|
-
U: From<T>,
|
|
56
|
-
{
|
|
57
|
-
fn into(self) -> U {
|
|
58
|
-
U::from(self)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// So when you implement From:
|
|
63
|
-
impl From<String> for MyType { ... }
|
|
64
|
-
|
|
65
|
-
// You automatically get:
|
|
66
|
-
// impl Into<MyType> for String { ... }
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Multiple From Implementations
|
|
70
|
-
|
|
71
|
-
```rust
|
|
72
|
-
struct Email(String);
|
|
73
|
-
|
|
74
|
-
impl From<String> for Email {
|
|
75
|
-
fn from(s: String) -> Self {
|
|
76
|
-
Email(s)
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
impl From<&str> for Email {
|
|
81
|
-
fn from(s: &str) -> Self {
|
|
82
|
-
Email(s.to_string())
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// All of these work
|
|
87
|
-
let e1 = Email::from("test@example.com");
|
|
88
|
-
let e2 = Email::from(String::from("test@example.com"));
|
|
89
|
-
let e3: Email = "test@example.com".into();
|
|
90
|
-
let e4: Email = String::from("test@example.com").into();
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## TryFrom for Fallible Conversions
|
|
94
|
-
|
|
95
|
-
```rust
|
|
96
|
-
use std::convert::TryFrom;
|
|
97
|
-
|
|
98
|
-
struct PositiveInt(u32);
|
|
99
|
-
|
|
100
|
-
// Fallible conversion
|
|
101
|
-
impl TryFrom<i32> for PositiveInt {
|
|
102
|
-
type Error = &'static str;
|
|
103
|
-
|
|
104
|
-
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
|
105
|
-
if value > 0 {
|
|
106
|
-
Ok(PositiveInt(value as u32))
|
|
107
|
-
} else {
|
|
108
|
-
Err("value must be positive")
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Usage
|
|
114
|
-
let pos = PositiveInt::try_from(42)?; // From-style
|
|
115
|
-
let pos: PositiveInt = 42.try_into()?; // Into-style (via blanket)
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Clippy Lint
|
|
119
|
-
|
|
120
|
-
```toml
|
|
121
|
-
[lints.clippy]
|
|
122
|
-
from_over_into = "warn" # Warns when implementing Into instead of From
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
```rust
|
|
126
|
-
// Clippy will warn:
|
|
127
|
-
impl Into<Bar> for Foo { // Warning: prefer From
|
|
128
|
-
fn into(self) -> Bar { ... }
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## When Into IS Needed (Rare)
|
|
133
|
-
|
|
134
|
-
```rust
|
|
135
|
-
// Only when implementing for external types in specific trait bounds
|
|
136
|
-
// This is very rare and usually indicates a design issue
|
|
137
|
-
|
|
138
|
-
// Example: you can't implement From<ExternalA> for ExternalB
|
|
139
|
-
// because of orphan rules. But you usually shouldn't need to.
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## See Also
|
|
143
|
-
|
|
144
|
-
- [api-impl-into](./api-impl-into.md) - Using Into in function parameters
|
|
145
|
-
- [err-from-impl](./err-from-impl.md) - From for error types
|
|
146
|
-
- [api-newtype-safety](./api-newtype-safety.md) - Newtype conversions
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# api-impl-asref
|
|
2
|
-
|
|
3
|
-
> Use `AsRef<T>` when you only need to borrow the inner data
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
`AsRef<T>` provides a cheap borrowed view of data without taking ownership or copying. Functions accepting `impl AsRef<T>` can work with multiple types that contain or represent `T`, making APIs flexible while avoiding unnecessary allocations. Use `AsRef` when you only need to read, `Into` when you need to own.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Forces callers to provide exact types
|
|
13
|
-
fn process_text(text: &str) { ... }
|
|
14
|
-
fn read_file(path: &Path) { ... }
|
|
15
|
-
|
|
16
|
-
// Can't call directly with owned types
|
|
17
|
-
let s = String::from("hello");
|
|
18
|
-
process_text(&s); // Works but verbose
|
|
19
|
-
|
|
20
|
-
let p = PathBuf::from("/file");
|
|
21
|
-
read_file(&p); // Works but verbose
|
|
22
|
-
read_file("/file"); // Error! &str != &Path
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Good
|
|
26
|
-
|
|
27
|
-
```rust
|
|
28
|
-
// Accept anything that can be viewed as the target type
|
|
29
|
-
fn process_text(text: impl AsRef<str>) {
|
|
30
|
-
let s: &str = text.as_ref();
|
|
31
|
-
println!("{}", s);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
fn read_file(path: impl AsRef<Path>) -> io::Result<Vec<u8>> {
|
|
35
|
-
std::fs::read(path.as_ref())
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// All of these work:
|
|
39
|
-
process_text("literal"); // &str
|
|
40
|
-
process_text(String::from("owned")); // String
|
|
41
|
-
process_text(Cow::from("cow")); // Cow<str>
|
|
42
|
-
|
|
43
|
-
read_file("/path/to/file"); // &str
|
|
44
|
-
read_file(Path::new("/path")); // &Path
|
|
45
|
-
read_file(PathBuf::from("/path")); // PathBuf
|
|
46
|
-
read_file(OsStr::new("/path")); // &OsStr
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## AsRef vs Into vs Borrow
|
|
50
|
-
|
|
51
|
-
```rust
|
|
52
|
-
// AsRef<T>: cheap borrow, no ownership transfer
|
|
53
|
-
fn read(p: impl AsRef<Path>) {
|
|
54
|
-
let path: &Path = p.as_ref();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Into<T>: ownership transfer, may allocate
|
|
58
|
-
fn store(p: impl Into<PathBuf>) {
|
|
59
|
-
let owned: PathBuf = p.into();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Borrow<T>: like AsRef but with Eq/Hash consistency guarantee
|
|
63
|
-
use std::borrow::Borrow;
|
|
64
|
-
fn lookup<Q: ?Sized>(map: &HashMap<String, V>, key: &Q) -> Option<&V>
|
|
65
|
-
where
|
|
66
|
-
String: Borrow<Q>,
|
|
67
|
-
Q: Hash + Eq,
|
|
68
|
-
{
|
|
69
|
-
map.get(key)
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Implement AsRef for Custom Types
|
|
74
|
-
|
|
75
|
-
```rust
|
|
76
|
-
struct Name(String);
|
|
77
|
-
|
|
78
|
-
impl AsRef<str> for Name {
|
|
79
|
-
fn as_ref(&self) -> &str {
|
|
80
|
-
&self.0
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
impl AsRef<[u8]> for Name {
|
|
85
|
-
fn as_ref(&self) -> &[u8] {
|
|
86
|
-
self.0.as_bytes()
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Now Name works with functions expecting AsRef<str>
|
|
91
|
-
fn greet(name: impl AsRef<str>) {
|
|
92
|
-
println!("Hello, {}!", name.as_ref());
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
greet(Name("Alice".into()));
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Common AsRef Implementations
|
|
99
|
-
|
|
100
|
-
```rust
|
|
101
|
-
// Standard library provides many
|
|
102
|
-
impl AsRef<str> for String { ... }
|
|
103
|
-
impl AsRef<str> for str { ... }
|
|
104
|
-
impl AsRef<[u8]> for str { ... }
|
|
105
|
-
impl AsRef<[u8]> for String { ... }
|
|
106
|
-
impl AsRef<[u8]> for Vec<u8> { ... }
|
|
107
|
-
impl AsRef<Path> for str { ... }
|
|
108
|
-
impl AsRef<Path> for String { ... }
|
|
109
|
-
impl AsRef<Path> for PathBuf { ... }
|
|
110
|
-
impl AsRef<Path> for OsStr { ... }
|
|
111
|
-
impl AsRef<OsStr> for str { ... }
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## When to Use Which
|
|
115
|
-
|
|
116
|
-
| Trait | Use When |
|
|
117
|
-
|-------|----------|
|
|
118
|
-
| `&T` | Single type, simple API |
|
|
119
|
-
| `AsRef<T>` | Read-only access, multiple input types |
|
|
120
|
-
| `Into<T>` | Need to store/own the value |
|
|
121
|
-
| `Borrow<T>` | HashMap/HashSet keys, Eq/Hash needed |
|
|
122
|
-
| `Deref<Target=T>` | Smart pointer semantics |
|
|
123
|
-
|
|
124
|
-
## Pattern: Optional AsRef Bound
|
|
125
|
-
|
|
126
|
-
```rust
|
|
127
|
-
// When T itself might be passed
|
|
128
|
-
fn process<T: AsRef<U>, U>(value: T) {
|
|
129
|
-
let inner: &U = value.as_ref();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// More flexible: accept T or &T
|
|
133
|
-
fn process<T: AsRef<U> + ?Sized, U: ?Sized>(value: &T) {
|
|
134
|
-
let inner: &U = value.as_ref();
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## See Also
|
|
139
|
-
|
|
140
|
-
- [api-impl-into](./api-impl-into.md) - When to use Into instead
|
|
141
|
-
- [own-slice-over-vec](./own-slice-over-vec.md) - Using slices for flexibility
|
|
142
|
-
- [own-borrow-over-clone](./own-borrow-over-clone.md) - Preferring borrows
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
# api-impl-into
|
|
2
|
-
|
|
3
|
-
> Accept `impl Into<T>` for flexible APIs, implement `From<T>` for conversions
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
APIs that accept `impl Into<T>` are ergonomic—callers can pass the target type directly or any type that converts to it. This reduces boilerplate `.into()` calls at call sites. Implement `From<T>` rather than `Into<T>` because `From` implies `Into` through a blanket implementation.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Requires exact type - forces callers to convert
|
|
13
|
-
fn process_path(path: PathBuf) { ... }
|
|
14
|
-
fn set_name(name: String) { ... }
|
|
15
|
-
|
|
16
|
-
// Caller must convert explicitly
|
|
17
|
-
process_path(PathBuf::from("/path/to/file"));
|
|
18
|
-
process_path("/path/to/file".to_path_buf()); // Verbose
|
|
19
|
-
process_path("/path/to/file".into()); // Explicit
|
|
20
|
-
|
|
21
|
-
set_name(String::from("Alice"));
|
|
22
|
-
set_name("Alice".to_string()); // Verbose
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Good
|
|
26
|
-
|
|
27
|
-
```rust
|
|
28
|
-
// Accept anything that converts to the target type
|
|
29
|
-
fn process_path(path: impl Into<PathBuf>) {
|
|
30
|
-
let path = path.into(); // Convert once inside
|
|
31
|
-
// ...
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
fn set_name(name: impl Into<String>) {
|
|
35
|
-
let name = name.into();
|
|
36
|
-
// ...
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Callers are ergonomic
|
|
40
|
-
process_path("/path/to/file"); // &str converts automatically
|
|
41
|
-
process_path(PathBuf::from(".")); // PathBuf works too
|
|
42
|
-
|
|
43
|
-
set_name("Alice"); // &str
|
|
44
|
-
set_name(String::from("Alice")); // String
|
|
45
|
-
set_name(format!("User-{}", id)); // String from format!
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Implement From, Not Into
|
|
49
|
-
|
|
50
|
-
```rust
|
|
51
|
-
struct UserId(u64);
|
|
52
|
-
|
|
53
|
-
// ✅ Implement From
|
|
54
|
-
impl From<u64> for UserId {
|
|
55
|
-
fn from(id: u64) -> Self {
|
|
56
|
-
UserId(id)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Into is automatically provided by blanket impl
|
|
61
|
-
let id: UserId = 42u64.into(); // Works!
|
|
62
|
-
|
|
63
|
-
// ❌ Don't implement Into directly
|
|
64
|
-
impl Into<UserId> for u64 {
|
|
65
|
-
fn into(self) -> UserId {
|
|
66
|
-
UserId(self) // This works but is non-idiomatic
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Common Conversions
|
|
72
|
-
|
|
73
|
-
```rust
|
|
74
|
-
// String-like types
|
|
75
|
-
fn log_message(msg: impl Into<String>) { ... }
|
|
76
|
-
log_message("literal"); // &str
|
|
77
|
-
log_message(String::from("own")); // String
|
|
78
|
-
log_message(Cow::from("cow")); // Cow<str>
|
|
79
|
-
|
|
80
|
-
// Path-like types
|
|
81
|
-
fn read_file(path: impl AsRef<Path>) { ... } // AsRef for borrowed access
|
|
82
|
-
fn write_file(path: impl Into<PathBuf>) { ... } // Into when storing
|
|
83
|
-
|
|
84
|
-
// Duration
|
|
85
|
-
fn set_timeout(duration: impl Into<Duration>) { ... }
|
|
86
|
-
set_timeout(Duration::from_secs(5));
|
|
87
|
-
// Note: no blanket impl for integers, would need custom wrapper
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## AsRef vs Into
|
|
91
|
-
|
|
92
|
-
```rust
|
|
93
|
-
// AsRef<T>: borrow as &T, no conversion cost
|
|
94
|
-
fn count_bytes(data: impl AsRef<[u8]>) -> usize {
|
|
95
|
-
data.as_ref().len() // Just borrows, no allocation
|
|
96
|
-
}
|
|
97
|
-
count_bytes("hello"); // &str -> &[u8]
|
|
98
|
-
count_bytes(b"hello"); // &[u8] -> &[u8]
|
|
99
|
-
count_bytes(vec![1, 2, 3]); // &Vec<u8> -> &[u8]
|
|
100
|
-
|
|
101
|
-
// Into<T>: convert to owned T, may allocate
|
|
102
|
-
fn store_data(data: impl Into<Vec<u8>>) {
|
|
103
|
-
let owned: Vec<u8> = data.into(); // Takes ownership
|
|
104
|
-
// ...
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## When NOT to Use impl Into
|
|
109
|
-
|
|
110
|
-
```rust
|
|
111
|
-
// ❌ Trait objects need Sized
|
|
112
|
-
fn process(handler: impl Into<Box<dyn Handler>>) { }
|
|
113
|
-
// Better: just take Box<dyn Handler> directly
|
|
114
|
-
|
|
115
|
-
// ❌ Recursive types
|
|
116
|
-
struct Node {
|
|
117
|
-
children: Vec<impl Into<Node>>, // Error: impl Trait not allowed here
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// ❌ Performance-critical hot paths (minor overhead of trait dispatch)
|
|
121
|
-
fn hot_path(value: impl Into<u64>) {
|
|
122
|
-
// Consider taking u64 directly if called billions of times
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// ❌ When you need to name the type
|
|
126
|
-
fn returns_impl() -> impl Into<String> { } // Opaque, hard to use
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## Builder Pattern with Into
|
|
130
|
-
|
|
131
|
-
```rust
|
|
132
|
-
struct Config {
|
|
133
|
-
name: String,
|
|
134
|
-
path: PathBuf,
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
impl Config {
|
|
138
|
-
fn new(name: impl Into<String>) -> Self {
|
|
139
|
-
Config {
|
|
140
|
-
name: name.into(),
|
|
141
|
-
path: PathBuf::new(),
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
fn path(mut self, path: impl Into<PathBuf>) -> Self {
|
|
146
|
-
self.path = path.into();
|
|
147
|
-
self
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Clean builder calls
|
|
152
|
-
let config = Config::new("myapp")
|
|
153
|
-
.path("/etc/myapp");
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
## See Also
|
|
157
|
-
|
|
158
|
-
- [api-impl-asref](./api-impl-asref.md) - When to use AsRef instead
|
|
159
|
-
- [api-from-not-into](./api-from-not-into.md) - Why From is preferred
|
|
160
|
-
- [err-from-impl](./err-from-impl.md) - From for error conversion
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# api-must-use
|
|
2
|
-
|
|
3
|
-
> Mark types and functions with `#[must_use]` when ignoring results is likely a bug
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Some return values should never be ignored—`Result`, locks, RAII guards, computed values that have no side effects. Without `#[must_use]`, silently discarding these values can introduce subtle bugs that are hard to detect. The attribute generates compiler warnings when the value is unused.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Result ignored - error silently dropped
|
|
13
|
-
fn send_email(to: &str, body: &str) -> Result<(), EmailError> { ... }
|
|
14
|
-
|
|
15
|
-
send_email("user@example.com", "Hello!"); // No warning if Result ignored!
|
|
16
|
-
// Email may have failed, but we don't know
|
|
17
|
-
|
|
18
|
-
// Computed value ignored - likely a bug
|
|
19
|
-
fn compute_checksum(data: &[u8]) -> u32 { ... }
|
|
20
|
-
|
|
21
|
-
let data = vec![1, 2, 3, 4];
|
|
22
|
-
compute_checksum(&data); // Result discarded - pointless call
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Good
|
|
26
|
-
|
|
27
|
-
```rust
|
|
28
|
-
#[must_use = "this `Result` may be an `Err` that should be handled"]
|
|
29
|
-
fn send_email(to: &str, body: &str) -> Result<(), EmailError> { ... }
|
|
30
|
-
|
|
31
|
-
send_email("user@example.com", "Hello!");
|
|
32
|
-
// Warning: unused `Result` that must be used
|
|
33
|
-
|
|
34
|
-
// Mark pure functions
|
|
35
|
-
#[must_use = "this returns a new value and does not modify the input"]
|
|
36
|
-
fn compute_checksum(data: &[u8]) -> u32 { ... }
|
|
37
|
-
|
|
38
|
-
compute_checksum(&data);
|
|
39
|
-
// Warning: unused return value of `compute_checksum` that must be used
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Apply to Types
|
|
43
|
-
|
|
44
|
-
```rust
|
|
45
|
-
// Mark the type itself when it should always be used
|
|
46
|
-
#[must_use = "futures do nothing unless polled"]
|
|
47
|
-
struct MyFuture<T> { ... }
|
|
48
|
-
|
|
49
|
-
// Mark RAII guards
|
|
50
|
-
#[must_use = "if unused, the lock will be immediately released"]
|
|
51
|
-
struct MutexGuard<'a, T> { ... }
|
|
52
|
-
|
|
53
|
-
// Mark results/errors
|
|
54
|
-
#[must_use = "errors should be handled"]
|
|
55
|
-
enum AppError { ... }
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Standard Library Examples
|
|
59
|
-
|
|
60
|
-
```rust
|
|
61
|
-
// Result and Option are #[must_use]
|
|
62
|
-
let v: Vec<i32> = vec![1, 2, 3];
|
|
63
|
-
v.first(); // Warning: unused Option
|
|
64
|
-
|
|
65
|
-
// Iterator adapters are #[must_use]
|
|
66
|
-
v.iter().map(|x| x * 2); // Warning: iterators are lazy
|
|
67
|
-
|
|
68
|
-
// String methods that return new values
|
|
69
|
-
let s = "hello";
|
|
70
|
-
s.to_uppercase(); // Warning: unused String
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## When to Apply
|
|
74
|
-
|
|
75
|
-
```rust
|
|
76
|
-
// ✅ Pure functions (no side effects)
|
|
77
|
-
#[must_use]
|
|
78
|
-
fn add(a: i32, b: i32) -> i32 { a + b }
|
|
79
|
-
|
|
80
|
-
// ✅ Builder methods returning Self
|
|
81
|
-
#[must_use = "builder methods return a new builder"]
|
|
82
|
-
fn with_timeout(self, t: Duration) -> Self { ... }
|
|
83
|
-
|
|
84
|
-
// ✅ Fallible operations
|
|
85
|
-
#[must_use]
|
|
86
|
-
fn try_parse(s: &str) -> Result<Data, ParseError> { ... }
|
|
87
|
-
|
|
88
|
-
// ✅ Iterators and futures (lazy)
|
|
89
|
-
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
|
90
|
-
struct Map<I, F> { ... }
|
|
91
|
-
|
|
92
|
-
// ❌ Side-effecting functions where result is optional
|
|
93
|
-
fn log(msg: &str) -> Result<(), io::Error> { ... } // Might be ok to ignore
|
|
94
|
-
|
|
95
|
-
// ❌ Methods with useful side effects
|
|
96
|
-
fn vec.push(item); // Mutates vec, no return to use
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## Custom Messages
|
|
100
|
-
|
|
101
|
-
```rust
|
|
102
|
-
#[must_use = "creating a guard does nothing without assignment"]
|
|
103
|
-
struct ScopeGuard { ... }
|
|
104
|
-
|
|
105
|
-
#[must_use = "this returns the old value"]
|
|
106
|
-
fn replace(&mut self, new: T) -> T { ... }
|
|
107
|
-
|
|
108
|
-
#[must_use = "use `.await` to execute the future"]
|
|
109
|
-
async fn fetch() -> Data { ... }
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## Clippy Lints
|
|
113
|
-
|
|
114
|
-
```toml
|
|
115
|
-
[lints.clippy]
|
|
116
|
-
must_use_candidate = "warn" # Suggests where to add #[must_use]
|
|
117
|
-
unused_must_use = "deny" # Built-in, treat warnings as errors
|
|
118
|
-
double_must_use = "warn" # Redundant #[must_use]
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## See Also
|
|
122
|
-
|
|
123
|
-
- [api-builder-must-use](./api-builder-must-use.md) - Builder pattern must_use
|
|
124
|
-
- [err-result-over-panic](./err-result-over-panic.md) - Result types require handling
|
|
125
|
-
- [lint-deny-correctness](./lint-deny-correctness.md) - Enabling useful lints
|