agy-superpowers 5.1.4 → 5.1.6
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/package.json +1 -1
- package/template/agent/rules/debug-confirmation-policy.md +34 -0
- package/template/agent/rules/language-matching.md +32 -0
- package/template/agent/skills/rust-developer/SKILL.md +281 -0
- package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +231 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +124 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +131 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +132 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +95 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +141 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +125 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +127 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +120 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +131 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +156 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +122 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +167 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +134 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +143 -0
- package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +121 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +143 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +187 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +165 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +177 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +163 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +146 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +142 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +160 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +125 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +162 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +177 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +184 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +168 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +182 -0
- package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +199 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +175 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +185 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +203 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +171 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +158 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +195 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +171 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +156 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +191 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +198 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +154 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +167 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +169 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +172 -0
- package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +189 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +113 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +147 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +122 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +161 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +149 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +138 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +169 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +116 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +128 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +136 -0
- package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +131 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +179 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +144 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +152 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +145 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +133 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +152 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +124 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +115 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +151 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +130 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +155 -0
- package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +171 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +138 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +107 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +154 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +118 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +157 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +133 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +131 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +136 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +135 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +122 -0
- package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +172 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +168 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +142 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +168 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +147 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +158 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +139 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +147 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +149 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +174 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +159 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +138 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +142 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +156 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +172 -0
- package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +164 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +99 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +104 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +94 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +78 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +76 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +123 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +127 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +129 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +131 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +142 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +86 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +154 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +118 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +92 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +65 -0
- package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +101 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +161 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +187 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +142 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +152 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +141 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +181 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +160 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +171 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +130 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +167 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +144 -0
- package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +154 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +141 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +95 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +135 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +124 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +135 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +134 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +134 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +105 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +65 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +97 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +122 -0
- package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +119 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +153 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +136 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +133 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +120 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +137 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +134 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +150 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +123 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +113 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +175 -0
- package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +149 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +142 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +133 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +148 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +130 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +120 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +155 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +139 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +135 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +162 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +186 -0
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +162 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +160 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +151 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +171 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +142 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +168 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +151 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +144 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +189 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +226 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +161 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +130 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +154 -0
- package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +127 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +154 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +142 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +146 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +160 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +159 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +144 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +137 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +188 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +143 -0
- package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +131 -0
- package/template/agent/skills/systematic-debugging/SKILL.md +17 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# lint-unsafe-doc
|
|
2
|
+
|
|
3
|
+
> Require documentation for unsafe blocks
|
|
4
|
+
|
|
5
|
+
## Why It Matters
|
|
6
|
+
|
|
7
|
+
The `undocumented_unsafe_blocks` lint ensures every unsafe block has a `// SAFETY:` comment explaining why the operation is sound. Unsafe code is the source of most memory safety bugs—documenting invariants catches mistakes and helps reviewers.
|
|
8
|
+
|
|
9
|
+
## Configuration
|
|
10
|
+
|
|
11
|
+
```rust
|
|
12
|
+
#![warn(clippy::undocumented_unsafe_blocks)]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or in `Cargo.toml`:
|
|
16
|
+
|
|
17
|
+
```toml
|
|
18
|
+
[lints.clippy]
|
|
19
|
+
undocumented_unsafe_blocks = "warn"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
For strict enforcement:
|
|
23
|
+
|
|
24
|
+
```toml
|
|
25
|
+
[lints.clippy]
|
|
26
|
+
undocumented_unsafe_blocks = "deny"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Bad
|
|
30
|
+
|
|
31
|
+
```rust
|
|
32
|
+
pub fn read_data(ptr: *const u8, len: usize) -> &[u8] {
|
|
33
|
+
unsafe {
|
|
34
|
+
std::slice::from_raw_parts(ptr, len) // WARN: undocumented
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
impl Buffer {
|
|
39
|
+
pub fn get_unchecked(&self, index: usize) -> &u8 {
|
|
40
|
+
unsafe { self.data.get_unchecked(index) } // WARN
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Good
|
|
46
|
+
|
|
47
|
+
```rust
|
|
48
|
+
pub fn read_data(ptr: *const u8, len: usize) -> &[u8] {
|
|
49
|
+
// SAFETY: Caller guarantees:
|
|
50
|
+
// - ptr is valid for reads of len bytes
|
|
51
|
+
// - ptr is properly aligned for u8
|
|
52
|
+
// - the memory is initialized
|
|
53
|
+
// - no mutable references exist to this memory
|
|
54
|
+
unsafe {
|
|
55
|
+
std::slice::from_raw_parts(ptr, len)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
impl Buffer {
|
|
60
|
+
pub fn get_unchecked(&self, index: usize) -> &u8 {
|
|
61
|
+
debug_assert!(index < self.len(), "index out of bounds");
|
|
62
|
+
// SAFETY: We verified index < len in debug builds.
|
|
63
|
+
// Callers must ensure index is within bounds.
|
|
64
|
+
unsafe { self.data.get_unchecked(index) }
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## SAFETY Comment Format
|
|
70
|
+
|
|
71
|
+
```rust
|
|
72
|
+
// SAFETY: <explanation of why this is sound>
|
|
73
|
+
unsafe {
|
|
74
|
+
// ...
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The comment should explain:
|
|
79
|
+
1. **What invariants are upheld** - preconditions that make this safe
|
|
80
|
+
2. **Why the invariants hold** - how you know they're satisfied
|
|
81
|
+
3. **What could go wrong** - if invariants are violated
|
|
82
|
+
|
|
83
|
+
## Examples by Category
|
|
84
|
+
|
|
85
|
+
### Pointer Operations
|
|
86
|
+
|
|
87
|
+
```rust
|
|
88
|
+
// SAFETY: ptr was obtained from Box::into_raw, so it's valid
|
|
89
|
+
// and properly aligned. We're taking back ownership.
|
|
90
|
+
let boxed = unsafe { Box::from_raw(ptr) };
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Unchecked Operations
|
|
94
|
+
|
|
95
|
+
```rust
|
|
96
|
+
// SAFETY: We just checked that i < self.len() above.
|
|
97
|
+
// The bounds check cannot be elided by the optimizer
|
|
98
|
+
// because len() is not inlined.
|
|
99
|
+
unsafe { self.data.get_unchecked(i) }
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### FFI Calls
|
|
103
|
+
|
|
104
|
+
```rust
|
|
105
|
+
// SAFETY: libc::getenv is safe to call with a null-terminated
|
|
106
|
+
// string. We ensure null termination with CString::new.
|
|
107
|
+
// The returned pointer is valid for the lifetime of the environment.
|
|
108
|
+
let value = unsafe { libc::getenv(key.as_ptr()) };
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Trait Implementations
|
|
112
|
+
|
|
113
|
+
```rust
|
|
114
|
+
// SAFETY: MyType contains no pointers or interior mutability,
|
|
115
|
+
// and all bit patterns are valid MyType values.
|
|
116
|
+
unsafe impl Send for MyType {}
|
|
117
|
+
unsafe impl Sync for MyType {}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Related Lints
|
|
121
|
+
|
|
122
|
+
```toml
|
|
123
|
+
[lints.clippy]
|
|
124
|
+
undocumented_unsafe_blocks = "warn"
|
|
125
|
+
# Also consider:
|
|
126
|
+
multiple_unsafe_ops_per_block = "warn" # One operation per block
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## See Also
|
|
130
|
+
|
|
131
|
+
- [doc-safety-section](./doc-safety-section.md) - `# Safety` in docs
|
|
132
|
+
- [lint-deny-correctness](./lint-deny-correctness.md) - Correctness lints
|
|
133
|
+
- [type-repr-transparent](./type-repr-transparent.md) - FFI safety
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# lint-warn-complexity
|
|
2
|
+
|
|
3
|
+
> Enable clippy::complexity for simpler code
|
|
4
|
+
|
|
5
|
+
## Why It Matters
|
|
6
|
+
|
|
7
|
+
The `clippy::complexity` lint group identifies unnecessarily complex code that can be simplified. Complex code is harder to read, maintain, and often hides bugs. Clippy suggests cleaner alternatives.
|
|
8
|
+
|
|
9
|
+
## Configuration
|
|
10
|
+
|
|
11
|
+
```rust
|
|
12
|
+
// In lib.rs or main.rs
|
|
13
|
+
#![warn(clippy::complexity)]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or in `Cargo.toml`:
|
|
17
|
+
|
|
18
|
+
```toml
|
|
19
|
+
[lints.clippy]
|
|
20
|
+
complexity = "warn"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## What It Catches
|
|
24
|
+
|
|
25
|
+
### Unnecessary Complexity
|
|
26
|
+
|
|
27
|
+
```rust
|
|
28
|
+
// WARN: Overly complex boolean expression
|
|
29
|
+
if !(x == 0) { } // Use: if x != 0 { }
|
|
30
|
+
|
|
31
|
+
// WARN: Manual implementation of Option::map
|
|
32
|
+
match option {
|
|
33
|
+
Some(x) => Some(x + 1),
|
|
34
|
+
None => None,
|
|
35
|
+
} // Use: option.map(|x| x + 1)
|
|
36
|
+
|
|
37
|
+
// WARN: Unnecessary filter before count
|
|
38
|
+
iter.filter(|x| predicate(x)).count() // Could simplify if only counting
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Redundant Operations
|
|
42
|
+
|
|
43
|
+
```rust
|
|
44
|
+
// WARN: Redundant allocation
|
|
45
|
+
let s = format!("literal"); // Use: "literal".to_string() or just "literal"
|
|
46
|
+
|
|
47
|
+
// WARN: Unnecessarily complicated match
|
|
48
|
+
match result {
|
|
49
|
+
Ok(ok) => Ok(ok),
|
|
50
|
+
Err(err) => Err(err),
|
|
51
|
+
} // Just use: result
|
|
52
|
+
|
|
53
|
+
// WARN: Box::new in return position
|
|
54
|
+
fn make_error() -> Box<dyn Error> {
|
|
55
|
+
Box::new(MyError) // Could use: MyError.into()
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Overly Verbose Code
|
|
60
|
+
|
|
61
|
+
```rust
|
|
62
|
+
// WARN: bind_instead_of_map
|
|
63
|
+
option.and_then(|x| Some(x + 1)) // Use: option.map(|x| x + 1)
|
|
64
|
+
|
|
65
|
+
// WARN: clone_on_copy
|
|
66
|
+
let y = x.clone(); // Where x is Copy type, just use: let y = x;
|
|
67
|
+
|
|
68
|
+
// WARN: useless_let_if_seq
|
|
69
|
+
let result;
|
|
70
|
+
if condition {
|
|
71
|
+
result = 1;
|
|
72
|
+
} else {
|
|
73
|
+
result = 2;
|
|
74
|
+
}
|
|
75
|
+
// Use: let result = if condition { 1 } else { 2 };
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Notable Lints in This Group
|
|
79
|
+
|
|
80
|
+
| Lint | Simplification |
|
|
81
|
+
|------|---------------|
|
|
82
|
+
| `bind_instead_of_map` | Use `map` instead of `and_then(Some(...))` |
|
|
83
|
+
| `bool_comparison` | `if x == true` → `if x` |
|
|
84
|
+
| `clone_on_copy` | Remove `.clone()` for Copy types |
|
|
85
|
+
| `filter_next` | Use `.find()` instead |
|
|
86
|
+
| `option_map_unit_fn` | Use `if let` instead |
|
|
87
|
+
| `search_is_some` | Use `.any()` or `.contains()` |
|
|
88
|
+
| `unnecessary_cast` | Remove redundant casts |
|
|
89
|
+
| `useless_conversion` | Remove `.into()` when types match |
|
|
90
|
+
|
|
91
|
+
## Examples
|
|
92
|
+
|
|
93
|
+
```rust
|
|
94
|
+
// Before (complexity warnings)
|
|
95
|
+
fn find_positive(nums: &[i32]) -> Option<i32> {
|
|
96
|
+
let filtered: Vec<_> = nums.iter()
|
|
97
|
+
.cloned()
|
|
98
|
+
.filter(|x| *x > 0)
|
|
99
|
+
.collect();
|
|
100
|
+
if filtered.len() == 0 {
|
|
101
|
+
None
|
|
102
|
+
} else {
|
|
103
|
+
Some(filtered[0])
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// After (simplified)
|
|
108
|
+
fn find_positive(nums: &[i32]) -> Option<i32> {
|
|
109
|
+
nums.iter()
|
|
110
|
+
.copied()
|
|
111
|
+
.find(|&x| x > 0)
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Cognitive Load
|
|
116
|
+
|
|
117
|
+
Complex code isn't just longer—it's harder to understand:
|
|
118
|
+
|
|
119
|
+
```rust
|
|
120
|
+
// High cognitive load
|
|
121
|
+
let value = if x.is_some() { x.unwrap() } else { y.unwrap_or(z) };
|
|
122
|
+
|
|
123
|
+
// Lower cognitive load
|
|
124
|
+
let value = x.unwrap_or_else(|| y.unwrap_or(z));
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## See Also
|
|
128
|
+
|
|
129
|
+
- [lint-warn-style](./lint-warn-style.md) - Style warnings
|
|
130
|
+
- [lint-warn-perf](./lint-warn-perf.md) - Performance warnings
|
|
131
|
+
- [lint-pedantic-selective](./lint-pedantic-selective.md) - Pedantic lints
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# lint-warn-perf
|
|
2
|
+
|
|
3
|
+
> Enable clippy::perf for performance improvements
|
|
4
|
+
|
|
5
|
+
## Why It Matters
|
|
6
|
+
|
|
7
|
+
The `clippy::perf` lint group catches performance anti-patterns—inefficient allocations, unnecessary copies, suboptimal API usage. While not all performance issues are critical, avoiding obvious inefficiencies is good practice.
|
|
8
|
+
|
|
9
|
+
## Configuration
|
|
10
|
+
|
|
11
|
+
```rust
|
|
12
|
+
// In lib.rs or main.rs
|
|
13
|
+
#![warn(clippy::perf)]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or in `Cargo.toml`:
|
|
17
|
+
|
|
18
|
+
```toml
|
|
19
|
+
[lints.clippy]
|
|
20
|
+
perf = "warn"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## What It Catches
|
|
24
|
+
|
|
25
|
+
### Unnecessary Allocations
|
|
26
|
+
|
|
27
|
+
```rust
|
|
28
|
+
// WARN: Unnecessary to_string before into
|
|
29
|
+
fn take_string(s: impl Into<String>) { }
|
|
30
|
+
take_string("hello".to_string()); // Just use: "hello"
|
|
31
|
+
|
|
32
|
+
// WARN: Box::new in return with deref coercion
|
|
33
|
+
fn make_trait() -> Box<dyn Trait> {
|
|
34
|
+
Box::new(concrete) // Could use Into
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// WARN: Unnecessary vec! for iteration
|
|
38
|
+
for x in vec![1, 2, 3] { } // Use array: [1, 2, 3]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Inefficient Operations
|
|
42
|
+
|
|
43
|
+
```rust
|
|
44
|
+
// WARN: Single-character string patterns
|
|
45
|
+
s.starts_with("x") // Use char: 'x'
|
|
46
|
+
s.contains("a") // Use char: 'a'
|
|
47
|
+
|
|
48
|
+
// WARN: iter().nth(0) instead of first()
|
|
49
|
+
iter.nth(0) // Use: iter.first() or iter.next()
|
|
50
|
+
|
|
51
|
+
// WARN: Manual saturating arithmetic
|
|
52
|
+
if x > i32::MAX - y { i32::MAX } else { x + y }
|
|
53
|
+
// Use: x.saturating_add(y)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Collection Inefficiencies
|
|
57
|
+
|
|
58
|
+
```rust
|
|
59
|
+
// WARN: extend with a single element
|
|
60
|
+
vec.extend(std::iter::once(item)); // Use: vec.push(item)
|
|
61
|
+
|
|
62
|
+
// WARN: Inefficient to_vec
|
|
63
|
+
slice.iter().cloned().collect::<Vec<_>>() // Use: slice.to_vec()
|
|
64
|
+
|
|
65
|
+
// WARN: Manual string concatenation
|
|
66
|
+
let s = format!("{}{}", a, b); // When both are &str, use: a.to_owned() + b
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Notable Lints in This Group
|
|
70
|
+
|
|
71
|
+
| Lint | Improvement |
|
|
72
|
+
|------|-------------|
|
|
73
|
+
| `box_collection` | Use `Vec<T>` not `Box<Vec<T>>` |
|
|
74
|
+
| `iter_nth` | Use `.get(n)` or `.next()` |
|
|
75
|
+
| `large_enum_variant` | Box large variants |
|
|
76
|
+
| `manual_memcpy` | Use slice copy methods |
|
|
77
|
+
| `redundant_allocation` | Remove double boxing |
|
|
78
|
+
| `single_char_pattern` | Use `char` not `&str` |
|
|
79
|
+
| `slow_vector_initialization` | Use `vec![0; n]` |
|
|
80
|
+
| `unnecessary_to_owned` | Remove redundant `.to_owned()` |
|
|
81
|
+
|
|
82
|
+
## Examples
|
|
83
|
+
|
|
84
|
+
```rust
|
|
85
|
+
// Before (perf warnings)
|
|
86
|
+
fn process(input: &str) -> String {
|
|
87
|
+
let parts: Vec<_> = input.split(",").collect();
|
|
88
|
+
let mut result = String::new();
|
|
89
|
+
for part in parts.iter() {
|
|
90
|
+
if part.starts_with(" ") {
|
|
91
|
+
result = result + &part.trim().to_string();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
result
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// After (optimized)
|
|
98
|
+
fn process(input: &str) -> String {
|
|
99
|
+
input.split(',')
|
|
100
|
+
.filter(|part| part.starts_with(' '))
|
|
101
|
+
.map(str::trim)
|
|
102
|
+
.collect()
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Allocation Patterns
|
|
107
|
+
|
|
108
|
+
```rust
|
|
109
|
+
// Unnecessary allocation
|
|
110
|
+
let vec: Vec<i32> = vec![]; // Creates capacity
|
|
111
|
+
let vec: Vec<i32> = Vec::new(); // No allocation
|
|
112
|
+
|
|
113
|
+
// Pre-allocation
|
|
114
|
+
let mut vec = Vec::with_capacity(100); // One allocation
|
|
115
|
+
for i in 0..100 {
|
|
116
|
+
vec.push(i); // No reallocation
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## String Patterns
|
|
121
|
+
|
|
122
|
+
```rust
|
|
123
|
+
// Slow: str pattern
|
|
124
|
+
s.contains("x");
|
|
125
|
+
s.find("y");
|
|
126
|
+
|
|
127
|
+
// Fast: char pattern
|
|
128
|
+
s.contains('x');
|
|
129
|
+
s.find('y');
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## See Also
|
|
133
|
+
|
|
134
|
+
- [lint-warn-complexity](./lint-warn-complexity.md) - Complexity warnings
|
|
135
|
+
- [mem-with-capacity](./mem-with-capacity.md) - Pre-allocation
|
|
136
|
+
- [perf-profile-first](./perf-profile-first.md) - Profile before optimizing
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# lint-warn-style
|
|
2
|
+
|
|
3
|
+
> Enable clippy::style for idiomatic code
|
|
4
|
+
|
|
5
|
+
## Why It Matters
|
|
6
|
+
|
|
7
|
+
The `clippy::style` lint group enforces idiomatic Rust patterns. While not bugs, style violations make code harder to read and maintain. Consistent style helps teams work together and makes code easier to review.
|
|
8
|
+
|
|
9
|
+
## Configuration
|
|
10
|
+
|
|
11
|
+
```rust
|
|
12
|
+
// In lib.rs or main.rs
|
|
13
|
+
#![warn(clippy::style)]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or in `Cargo.toml`:
|
|
17
|
+
|
|
18
|
+
```toml
|
|
19
|
+
[lints.clippy]
|
|
20
|
+
style = "warn"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## What It Catches
|
|
24
|
+
|
|
25
|
+
### Redundant Code
|
|
26
|
+
|
|
27
|
+
```rust
|
|
28
|
+
// WARN: Redundant clone on Copy type
|
|
29
|
+
let x = 5;
|
|
30
|
+
let y = x.clone(); // Just use: let y = x;
|
|
31
|
+
|
|
32
|
+
// WARN: Redundant closure
|
|
33
|
+
iter.map(|x| foo(x)) // Just use: iter.map(foo)
|
|
34
|
+
|
|
35
|
+
// WARN: Redundant pattern matching
|
|
36
|
+
match result {
|
|
37
|
+
Ok(x) => Ok(x),
|
|
38
|
+
Err(e) => Err(e),
|
|
39
|
+
} // Just return result
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Non-Idiomatic Patterns
|
|
43
|
+
|
|
44
|
+
```rust
|
|
45
|
+
// WARN: Should use if let
|
|
46
|
+
match option {
|
|
47
|
+
Some(x) => do_something(x),
|
|
48
|
+
None => {},
|
|
49
|
+
}
|
|
50
|
+
// Better: if let Some(x) = option { do_something(x) }
|
|
51
|
+
|
|
52
|
+
// WARN: Should use or_else
|
|
53
|
+
let value = if option.is_some() {
|
|
54
|
+
option.unwrap()
|
|
55
|
+
} else {
|
|
56
|
+
default()
|
|
57
|
+
};
|
|
58
|
+
// Better: option.unwrap_or_else(default)
|
|
59
|
+
|
|
60
|
+
// WARN: Collapsible if statements
|
|
61
|
+
if condition1 {
|
|
62
|
+
if condition2 {
|
|
63
|
+
do_something();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Better: if condition1 && condition2 { do_something() }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Naming Issues
|
|
70
|
+
|
|
71
|
+
```rust
|
|
72
|
+
// WARN: Function should not start with 'is_' returning non-bool
|
|
73
|
+
fn is_valid() -> i32 { 0 } // Misleading name
|
|
74
|
+
|
|
75
|
+
// WARN: Method should not be named 'new' without returning Self
|
|
76
|
+
impl Foo {
|
|
77
|
+
fn new() -> Bar { Bar } // Confusing
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Notable Lints in This Group
|
|
82
|
+
|
|
83
|
+
| Lint | Better Pattern |
|
|
84
|
+
|------|---------------|
|
|
85
|
+
| `len_zero` | Use `is_empty()` instead of `len() == 0` |
|
|
86
|
+
| `redundant_field_names` | Use shorthand `{ x }` not `{ x: x }` |
|
|
87
|
+
| `unused_unit` | Remove `-> ()` and trailing `()` |
|
|
88
|
+
| `collapsible_if` | Combine nested ifs with `&&` |
|
|
89
|
+
| `single_match` | Use `if let` instead |
|
|
90
|
+
| `match_like_matches_macro` | Use `matches!()` macro |
|
|
91
|
+
| `needless_return` | Remove explicit `return` at end |
|
|
92
|
+
| `question_mark` | Use `?` instead of `match` |
|
|
93
|
+
|
|
94
|
+
## Examples
|
|
95
|
+
|
|
96
|
+
```rust
|
|
97
|
+
// Before (style warnings)
|
|
98
|
+
fn process(data: Vec<i32>) -> Option<i32> {
|
|
99
|
+
if data.len() == 0 {
|
|
100
|
+
return None;
|
|
101
|
+
}
|
|
102
|
+
let first = match data.first() {
|
|
103
|
+
Some(x) => x,
|
|
104
|
+
None => return None,
|
|
105
|
+
};
|
|
106
|
+
return Some(*first);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// After (idiomatic)
|
|
110
|
+
fn process(data: Vec<i32>) -> Option<i32> {
|
|
111
|
+
if data.is_empty() {
|
|
112
|
+
return None;
|
|
113
|
+
}
|
|
114
|
+
let first = data.first()?;
|
|
115
|
+
Some(*first)
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Selective Allowance
|
|
120
|
+
|
|
121
|
+
Some style lints may conflict with team preferences:
|
|
122
|
+
|
|
123
|
+
```rust
|
|
124
|
+
// If your team prefers explicit returns
|
|
125
|
+
#[allow(clippy::needless_return)]
|
|
126
|
+
fn explicit_return() -> i32 {
|
|
127
|
+
return 42;
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## See Also
|
|
132
|
+
|
|
133
|
+
- [lint-warn-suspicious](./lint-warn-suspicious.md) - Suspicious patterns
|
|
134
|
+
- [lint-warn-complexity](./lint-warn-complexity.md) - Complexity warnings
|
|
135
|
+
- [lint-rustfmt-check](./lint-rustfmt-check.md) - Formatting checks
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# lint-warn-suspicious
|
|
2
|
+
|
|
3
|
+
> Enable clippy::suspicious for likely bugs
|
|
4
|
+
|
|
5
|
+
## Why It Matters
|
|
6
|
+
|
|
7
|
+
The `clippy::suspicious` lint group catches code patterns that are syntactically valid but almost always wrong. These are potential bugs that deserve investigation. Enabling this group as a warning helps catch mistakes early.
|
|
8
|
+
|
|
9
|
+
## Configuration
|
|
10
|
+
|
|
11
|
+
```rust
|
|
12
|
+
// In lib.rs or main.rs
|
|
13
|
+
#![warn(clippy::suspicious)]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or in `Cargo.toml`:
|
|
17
|
+
|
|
18
|
+
```toml
|
|
19
|
+
[lints.clippy]
|
|
20
|
+
suspicious = "warn"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or in `clippy.toml`:
|
|
24
|
+
|
|
25
|
+
```toml
|
|
26
|
+
warn = ["clippy::suspicious"]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## What It Catches
|
|
30
|
+
|
|
31
|
+
### Suspicious Arithmetic
|
|
32
|
+
|
|
33
|
+
```rust
|
|
34
|
+
// WARN: Suspicious use of + in a << expression
|
|
35
|
+
let bits = 1 << 4 + 1; // Probably meant (1 << 4) + 1 or 1 << (4 + 1)
|
|
36
|
+
|
|
37
|
+
// WARN: Suspicious use of | in a + expression
|
|
38
|
+
let value = x | 1 + y; // Probably meant (x | 1) + y or x | (1 + y)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Suspicious Comparisons
|
|
42
|
+
|
|
43
|
+
```rust
|
|
44
|
+
// WARN: Almost swapped operands in a comparison
|
|
45
|
+
if 5 < x && x < 3 { } // Impossible condition
|
|
46
|
+
|
|
47
|
+
// WARN: Suspicious assignment in a condition
|
|
48
|
+
if (x = 5) { } // Probably meant x == 5
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Suspicious Method Calls
|
|
52
|
+
|
|
53
|
+
```rust
|
|
54
|
+
// WARN: Suspicious map usage
|
|
55
|
+
let _: Vec<_> = vec.iter().map(|x| {
|
|
56
|
+
println!("{}", x); // Side effect in map
|
|
57
|
+
x
|
|
58
|
+
}).collect(); // Use for_each instead
|
|
59
|
+
|
|
60
|
+
// WARN: Suspicious string formatting
|
|
61
|
+
let s = format!("{}", format!("{}", x)); // Redundant nested format
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Suspicious Casts
|
|
65
|
+
|
|
66
|
+
```rust
|
|
67
|
+
// WARN: Suspicious use of not on a bool
|
|
68
|
+
let inverted = !x as i32; // Did you mean (!x) as i32 or !(x as i32)?
|
|
69
|
+
|
|
70
|
+
// WARN: Cast of float to int may lose precision
|
|
71
|
+
let n = 3.14_f64 as i32; // May want .round() first
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Notable Lints in This Group
|
|
75
|
+
|
|
76
|
+
| Lint | Description |
|
|
77
|
+
|------|-------------|
|
|
78
|
+
| `suspicious_arithmetic_impl` | Unusual operator in arithmetic trait |
|
|
79
|
+
| `suspicious_assignment_formatting` | Looks like typo in assignment |
|
|
80
|
+
| `suspicious_else_formatting` | Else on wrong line |
|
|
81
|
+
| `suspicious_map` | Map with side effects |
|
|
82
|
+
| `suspicious_op_assign_impl` | Unusual op-assign implementation |
|
|
83
|
+
| `suspicious_splitn` | splitn that can't produce n parts |
|
|
84
|
+
| `suspicious_unary_op_formatting` | Confusing unary operator spacing |
|
|
85
|
+
|
|
86
|
+
## Example Catches
|
|
87
|
+
|
|
88
|
+
```rust
|
|
89
|
+
// Caught: Suspicious double negation
|
|
90
|
+
let value = --x; // In Rust, this is -(-x), not pre-decrement
|
|
91
|
+
|
|
92
|
+
// Caught: Suspicious modulo
|
|
93
|
+
let remainder = x % 1; // Always 0 for integers
|
|
94
|
+
|
|
95
|
+
// Caught: Suspicious else formatting
|
|
96
|
+
if condition {
|
|
97
|
+
do_something();
|
|
98
|
+
}
|
|
99
|
+
else { // Weird formatting, might be a mistake
|
|
100
|
+
do_other();
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## When to Allow
|
|
105
|
+
|
|
106
|
+
Rarely. If you need to suppress, document why:
|
|
107
|
+
|
|
108
|
+
```rust
|
|
109
|
+
#[allow(clippy::suspicious_arithmetic_impl)]
|
|
110
|
+
impl Mul for Matrix {
|
|
111
|
+
// Custom matrix multiplication using + for reduction step
|
|
112
|
+
fn mul(self, rhs: Self) -> Self::Output {
|
|
113
|
+
// ...
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## See Also
|
|
119
|
+
|
|
120
|
+
- [lint-deny-correctness](./lint-deny-correctness.md) - Deny definite bugs
|
|
121
|
+
- [lint-warn-style](./lint-warn-style.md) - Style warnings
|
|
122
|
+
- [lint-warn-complexity](./lint-warn-complexity.md) - Complexity warnings
|