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.
Files changed (185) hide show
  1. package/package.json +1 -1
  2. package/template/agent/rules/debug-confirmation-policy.md +34 -0
  3. package/template/agent/rules/language-matching.md +32 -0
  4. package/template/agent/skills/rust-developer/SKILL.md +281 -0
  5. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +231 -0
  6. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +124 -0
  7. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +131 -0
  8. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +132 -0
  9. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +95 -0
  10. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +141 -0
  11. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +125 -0
  12. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +127 -0
  13. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +120 -0
  14. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +131 -0
  15. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +156 -0
  16. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +122 -0
  17. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +167 -0
  18. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +134 -0
  19. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +143 -0
  20. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +121 -0
  21. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +143 -0
  22. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +187 -0
  23. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +165 -0
  24. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +177 -0
  25. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +163 -0
  26. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +146 -0
  27. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +142 -0
  28. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +160 -0
  29. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +125 -0
  30. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +162 -0
  31. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +177 -0
  32. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +184 -0
  33. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +168 -0
  34. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +182 -0
  35. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +199 -0
  36. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +175 -0
  37. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +185 -0
  38. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +203 -0
  39. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +171 -0
  40. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +158 -0
  41. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +195 -0
  42. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +171 -0
  43. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +156 -0
  44. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +191 -0
  45. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +198 -0
  46. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +154 -0
  47. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +167 -0
  48. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +169 -0
  49. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +172 -0
  50. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +189 -0
  51. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +113 -0
  52. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +147 -0
  53. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +122 -0
  54. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +161 -0
  55. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +149 -0
  56. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +138 -0
  57. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +169 -0
  58. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +116 -0
  59. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +128 -0
  60. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +136 -0
  61. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +131 -0
  62. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +179 -0
  63. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +144 -0
  64. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +152 -0
  65. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +145 -0
  66. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +133 -0
  67. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +152 -0
  68. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +124 -0
  69. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +115 -0
  70. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +151 -0
  71. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +130 -0
  72. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +155 -0
  73. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +171 -0
  74. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +138 -0
  75. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +107 -0
  76. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +154 -0
  77. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +118 -0
  78. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +157 -0
  79. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +133 -0
  80. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +131 -0
  81. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +136 -0
  82. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +135 -0
  83. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +122 -0
  84. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +172 -0
  85. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +168 -0
  86. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +142 -0
  87. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +168 -0
  88. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +147 -0
  89. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +158 -0
  90. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +139 -0
  91. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +147 -0
  92. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +149 -0
  93. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +174 -0
  94. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +159 -0
  95. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +138 -0
  96. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +142 -0
  97. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +156 -0
  98. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +172 -0
  99. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +164 -0
  100. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +99 -0
  101. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +104 -0
  102. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +94 -0
  103. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +78 -0
  104. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +76 -0
  105. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +123 -0
  106. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +127 -0
  107. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +129 -0
  108. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +131 -0
  109. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +142 -0
  110. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +86 -0
  111. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +154 -0
  112. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +118 -0
  113. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +92 -0
  114. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +65 -0
  115. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +101 -0
  116. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +161 -0
  117. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +187 -0
  118. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +142 -0
  119. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +152 -0
  120. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +141 -0
  121. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +181 -0
  122. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +160 -0
  123. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +171 -0
  124. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +130 -0
  125. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +167 -0
  126. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +144 -0
  127. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +154 -0
  128. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +141 -0
  129. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +95 -0
  130. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +135 -0
  131. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +124 -0
  132. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +135 -0
  133. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +134 -0
  134. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +134 -0
  135. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +105 -0
  136. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +65 -0
  137. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +97 -0
  138. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +122 -0
  139. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +119 -0
  140. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +153 -0
  141. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +136 -0
  142. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +133 -0
  143. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +120 -0
  144. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +137 -0
  145. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +134 -0
  146. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +150 -0
  147. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +123 -0
  148. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +113 -0
  149. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +175 -0
  150. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +149 -0
  151. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +142 -0
  152. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +133 -0
  153. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +148 -0
  154. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +130 -0
  155. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +120 -0
  156. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +155 -0
  157. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +139 -0
  158. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +135 -0
  159. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +162 -0
  160. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +186 -0
  161. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +162 -0
  162. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +160 -0
  163. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +151 -0
  164. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +171 -0
  165. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +142 -0
  166. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +168 -0
  167. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +151 -0
  168. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +144 -0
  169. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +189 -0
  170. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +226 -0
  171. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +161 -0
  172. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +130 -0
  173. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +154 -0
  174. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +127 -0
  175. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +154 -0
  176. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +142 -0
  177. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +146 -0
  178. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +160 -0
  179. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +159 -0
  180. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +144 -0
  181. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +137 -0
  182. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +188 -0
  183. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +143 -0
  184. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +131 -0
  185. package/template/agent/skills/systematic-debugging/SKILL.md +17 -0
@@ -0,0 +1,181 @@
1
+ # opt-inline-never-cold
2
+
3
+ > Use `#[inline(never)]` and `#[cold]` for error paths and rarely-executed code
4
+
5
+ ## Why It Matters
6
+
7
+ Inlining error handling code into hot paths wastes instruction cache space and can prevent other optimizations. `#[inline(never)]` keeps cold code out of the hot path. `#[cold]` tells the compiler this branch is unlikely, enabling better branch prediction hints and code layout.
8
+
9
+ ## Bad
10
+
11
+ ```rust
12
+ fn process_data(data: &[u8]) -> Result<Output, Error> {
13
+ if data.is_empty() {
14
+ // Error path inlined into hot function
15
+ return Err(Error::Empty {
16
+ context: format!("Expected data, got empty slice"),
17
+ suggestions: vec!["Check input", "Validate before calling"],
18
+ });
19
+ }
20
+
21
+ // Hot path - now polluted with error construction code
22
+ do_processing(data)
23
+ }
24
+ ```
25
+
26
+ ## Good
27
+
28
+ ```rust
29
+ fn process_data(data: &[u8]) -> Result<Output, Error> {
30
+ if data.is_empty() {
31
+ return Err(empty_data_error()); // Cold path stays small
32
+ }
33
+
34
+ do_processing(data)
35
+ }
36
+
37
+ #[cold]
38
+ #[inline(never)]
39
+ fn empty_data_error() -> Error {
40
+ Error::Empty {
41
+ context: format!("Expected data, got empty slice"),
42
+ suggestions: vec!["Check input", "Validate before calling"],
43
+ }
44
+ }
45
+ ```
46
+
47
+ ## #[cold] for Unlikely Branches
48
+
49
+ ```rust
50
+ fn parse_value(input: &str) -> Result<i32, ParseError> {
51
+ match input.parse() {
52
+ Ok(n) => Ok(n),
53
+ Err(e) => cold_parse_error(input, e),
54
+ }
55
+ }
56
+
57
+ #[cold]
58
+ fn cold_parse_error(input: &str, e: std::num::ParseIntError) -> Result<i32, ParseError> {
59
+ Err(ParseError {
60
+ input: input.to_string(),
61
+ source: e,
62
+ })
63
+ }
64
+ ```
65
+
66
+ ## Panic Paths
67
+
68
+ ```rust
69
+ fn get_index(&self, idx: usize) -> &T {
70
+ if idx >= self.len {
71
+ cold_out_of_bounds(idx, self.len);
72
+ }
73
+ unsafe { self.ptr.add(idx).as_ref().unwrap() }
74
+ }
75
+
76
+ #[cold]
77
+ #[inline(never)]
78
+ fn cold_out_of_bounds(idx: usize, len: usize) -> ! {
79
+ panic!("index {} out of bounds for length {}", idx, len);
80
+ }
81
+ ```
82
+
83
+ ## Error Construction Functions
84
+
85
+ ```rust
86
+ // Keep error construction out of hot path
87
+ impl MyError {
88
+ #[cold]
89
+ pub fn io_error(source: std::io::Error, path: &Path) -> Self {
90
+ MyError::Io {
91
+ source,
92
+ path: path.to_path_buf(),
93
+ context: get_context(),
94
+ }
95
+ }
96
+
97
+ #[cold]
98
+ pub fn validation_error(msg: &str, field: &str) -> Self {
99
+ MyError::Validation {
100
+ message: msg.to_string(),
101
+ field: field.to_string(),
102
+ }
103
+ }
104
+ }
105
+
106
+ fn read_config(path: &Path) -> Result<Config, MyError> {
107
+ std::fs::read_to_string(path)
108
+ .map_err(|e| MyError::io_error(e, path))?
109
+ .parse()
110
+ .map_err(|e| MyError::parse_error(e))
111
+ }
112
+ ```
113
+
114
+ ## likely/unlikely Hints
115
+
116
+ ```rust
117
+ // Nightly: intrinsics for branch hints
118
+ #![feature(core_intrinsics)]
119
+ use std::intrinsics::{likely, unlikely};
120
+
121
+ fn process(data: Option<&Data>) -> Result<Output, Error> {
122
+ if unlikely(data.is_none()) {
123
+ return cold_none_error();
124
+ }
125
+
126
+ let data = data.unwrap();
127
+
128
+ if likely(data.is_valid()) {
129
+ fast_process(data)
130
+ } else {
131
+ slow_validate_and_process(data)
132
+ }
133
+ }
134
+
135
+ // Stable alternative: structure code so hot path is "fall through"
136
+ fn process(data: Option<&Data>) -> Result<Output, Error> {
137
+ let data = match data {
138
+ Some(d) => d,
139
+ None => return cold_none_error(), // Early return = unlikely hint
140
+ };
141
+
142
+ // Compiler assumes code after early returns is "hot"
143
+ fast_process(data)
144
+ }
145
+ ```
146
+
147
+ ## Pattern: Extract Cold Code
148
+
149
+ ```rust
150
+ // Before: cold code inline
151
+ fn hot_function(x: i32) -> i32 {
152
+ if x < 0 {
153
+ log::error!("Negative value: {}", x);
154
+ eprintln!("Debug info: {:?}", std::backtrace::Backtrace::capture());
155
+ return 0;
156
+ }
157
+ x * 2
158
+ }
159
+
160
+ // After: cold code extracted
161
+ fn hot_function(x: i32) -> i32 {
162
+ if x < 0 {
163
+ return handle_negative(x);
164
+ }
165
+ x * 2
166
+ }
167
+
168
+ #[cold]
169
+ #[inline(never)]
170
+ fn handle_negative(x: i32) -> i32 {
171
+ log::error!("Negative value: {}", x);
172
+ eprintln!("Debug info: {:?}", std::backtrace::Backtrace::capture());
173
+ 0
174
+ }
175
+ ```
176
+
177
+ ## See Also
178
+
179
+ - [opt-inline-small](./opt-inline-small.md) - Inlining for hot code
180
+ - [opt-inline-always-rare](./opt-inline-always-rare.md) - Forced inlining
181
+ - [err-result-over-panic](./err-result-over-panic.md) - Error handling patterns
@@ -0,0 +1,160 @@
1
+ # opt-inline-small
2
+
3
+ > Use `#[inline]` for small hot functions
4
+
5
+ ## Why It Matters
6
+
7
+ Function call overhead (stack frame setup, register saves, jumps) can dominate small functions. Inlining eliminates this overhead and enables further optimizations by the compiler. The compiler often inlines automatically, but hints help for cross-crate calls.
8
+
9
+ ## Bad
10
+
11
+ ```rust
12
+ // Small hot function without inline hint
13
+ // May not be inlined across crate boundaries
14
+ fn is_ascii_digit(b: u8) -> bool {
15
+ b >= b'0' && b <= b'9'
16
+ }
17
+
18
+ // Called millions of times
19
+ for byte in data {
20
+ if is_ascii_digit(*byte) { // Function call overhead
21
+ count += 1;
22
+ }
23
+ }
24
+ ```
25
+
26
+ ## Good
27
+
28
+ ```rust
29
+ #[inline]
30
+ fn is_ascii_digit(b: u8) -> bool {
31
+ b >= b'0' && b <= b'9'
32
+ }
33
+
34
+ // Now the compiler will inline this
35
+ for byte in data {
36
+ if is_ascii_digit(*byte) { // Inlined, no call overhead
37
+ count += 1;
38
+ }
39
+ }
40
+ ```
41
+
42
+ ## Inline Attributes
43
+
44
+ ```rust
45
+ // No attribute - compiler decides (usually good for same-crate)
46
+ fn auto_decide() { }
47
+
48
+ // Suggest inlining - helps cross-crate
49
+ #[inline]
50
+ fn suggest_inline() { }
51
+
52
+ // Strongly suggest inlining - almost always inlined
53
+ #[inline(always)]
54
+ fn force_inline() { }
55
+
56
+ // Strongly suggest NOT inlining - for large/cold code
57
+ #[inline(never)]
58
+ fn prevent_inline() { }
59
+ ```
60
+
61
+ ## When to Use Each
62
+
63
+ ```rust
64
+ // #[inline] - Small functions, especially in libraries
65
+ #[inline]
66
+ pub fn len(&self) -> usize {
67
+ self.inner.len()
68
+ }
69
+
70
+ // #[inline(always)] - Critical hot path, verified by profiling
71
+ #[inline(always)]
72
+ fn hot_inner_loop_helper(x: u32) -> u32 {
73
+ x.wrapping_mul(0x9E3779B9)
74
+ }
75
+
76
+ // #[inline(never)] - Error handlers, cold paths
77
+ #[inline(never)]
78
+ fn handle_error(err: Error) -> ! {
79
+ eprintln!("Fatal: {}", err);
80
+ std::process::exit(1);
81
+ }
82
+
83
+ // No attribute - large functions, infrequent calls
84
+ fn complex_processing(data: &mut Data) {
85
+ // Many lines of code...
86
+ }
87
+ ```
88
+
89
+ ## Evidence from ripgrep
90
+
91
+ ```rust
92
+ // https://github.com/BurntSushi/ripgrep/blob/master/crates/printer/src/standard.rs
93
+
94
+ #[inline(always)]
95
+ fn write_prelude(
96
+ &self,
97
+ absolute_byte_offset: u64,
98
+ line_number: Option<u64>,
99
+ column: Option<u64>,
100
+ ) -> io::Result<()> {
101
+ // Hot path in printing matches
102
+ }
103
+
104
+ #[inline(always)]
105
+ fn write_line(&self, line: &[u8]) -> io::Result<()> {
106
+ // Called for every line
107
+ }
108
+ ```
109
+
110
+ ## Generic Functions
111
+
112
+ ```rust
113
+ // Generic functions are already candidates for per-monomorphization inlining
114
+ // But #[inline] helps ensure it across crates
115
+
116
+ #[inline]
117
+ pub fn min<T: Ord>(a: T, b: T) -> T {
118
+ if a < b { a } else { b }
119
+ }
120
+ ```
121
+
122
+ ## Cautions
123
+
124
+ ```rust
125
+ // DON'T inline large functions - hurts instruction cache
126
+ #[inline(always)] // BAD for large function
127
+ fn large_complex_function(data: &mut [u8]) {
128
+ // 100+ lines of code
129
+ // Inlining bloats every call site
130
+ }
131
+
132
+ // DON'T assume inlining always helps - measure!
133
+ // Sometimes the compiler makes better decisions
134
+
135
+ // Inlining is non-transitive
136
+ #[inline]
137
+ fn outer() {
138
+ inner(); // inner() also needs #[inline] to be inlined together
139
+ }
140
+
141
+ fn inner() { } // Won't be inlined at outer's call sites
142
+ ```
143
+
144
+ ## Verifying Inlining
145
+
146
+ ```bash
147
+ # Check if function was inlined using Cachegrind
148
+ # Non-inlined functions show entry/exit counts
149
+
150
+ # Or examine assembly
151
+ cargo rustc --release -- --emit=asm
152
+ # Look for call instructions vs inlined code
153
+ ```
154
+
155
+ ## See Also
156
+
157
+ - [opt-inline-always-rare](opt-inline-always-rare.md) - Use #[inline(always)] sparingly
158
+ - [opt-inline-never-cold](opt-inline-never-cold.md) - Use #[inline(never)] for cold paths
159
+ - [opt-cold-unlikely](opt-cold-unlikely.md) - Use #[cold] for unlikely paths
160
+ - [opt-lto-release](opt-lto-release.md) - LTO enables cross-crate inlining
@@ -0,0 +1,171 @@
1
+ # opt-likely-hint
2
+
3
+ > Use code structure to hint at likely branches; use intrinsics on nightly
4
+
5
+ ## Why It Matters
6
+
7
+ Modern CPUs predict branches to speculatively execute code. Mispredictions cause pipeline stalls (10-20 cycles). Helping the compiler understand which branches are likely allows it to generate optimal code layout and branch hints, improving performance in hot paths.
8
+
9
+ ## Stable Rust: Code Structure Hints
10
+
11
+ ```rust
12
+ // Pattern 1: Early returns for unlikely cases
13
+ fn process(data: Option<&Data>) -> i32 {
14
+ // Compiler assumes early return is "unlikely"
15
+ let data = match data {
16
+ None => return 0, // Unlikely
17
+ Some(d) => d,
18
+ };
19
+
20
+ // Hot path continues here
21
+ complex_processing(data)
22
+ }
23
+
24
+ // Pattern 2: if-else ordering
25
+ fn calculate(x: i32) -> i32 {
26
+ if x >= 0 {
27
+ // Put likely case in "if" branch
28
+ x * 2
29
+ } else {
30
+ // Unlikely case in "else"
31
+ handle_negative(x)
32
+ }
33
+ }
34
+
35
+ // Pattern 3: Cold function extraction
36
+ fn hot_path(data: &[u8]) -> Result<(), Error> {
37
+ if data.is_empty() {
38
+ return cold_empty_error(); // Extracted = unlikely
39
+ }
40
+
41
+ process_fast(data)
42
+ }
43
+
44
+ #[cold]
45
+ fn cold_empty_error() -> Result<(), Error> {
46
+ Err(Error::EmptyInput)
47
+ }
48
+ ```
49
+
50
+ ## Nightly: Intrinsics
51
+
52
+ ```rust
53
+ #![feature(core_intrinsics)]
54
+ use std::intrinsics::{likely, unlikely};
55
+
56
+ fn process(data: &Data) -> i32 {
57
+ if unlikely(data.is_corrupted()) {
58
+ return handle_corruption(data);
59
+ }
60
+
61
+ if likely(data.is_cached()) {
62
+ return fast_cached_path(data);
63
+ }
64
+
65
+ slow_uncached_path(data)
66
+ }
67
+ ```
68
+
69
+ ## Boolean Likely Wrapper (Nightly)
70
+
71
+ ```rust
72
+ #![feature(core_intrinsics)]
73
+
74
+ #[inline(always)]
75
+ fn likely(b: bool) -> bool {
76
+ std::intrinsics::likely(b)
77
+ }
78
+
79
+ #[inline(always)]
80
+ fn unlikely(b: bool) -> bool {
81
+ std::intrinsics::unlikely(b)
82
+ }
83
+
84
+ // Usage
85
+ if likely(x > 0) {
86
+ hot_path(x)
87
+ } else {
88
+ cold_path(x)
89
+ }
90
+ ```
91
+
92
+ ## Stable: likely-stable Crate
93
+
94
+ ```rust
95
+ use likely_stable::{likely, unlikely};
96
+
97
+ fn check(value: i32) -> bool {
98
+ if unlikely(value < 0) {
99
+ handle_negative()
100
+ } else if likely(value < 1000) {
101
+ handle_common()
102
+ } else {
103
+ handle_large()
104
+ }
105
+ }
106
+ ```
107
+
108
+ ## Loop Optimization
109
+
110
+ ```rust
111
+ fn search(data: &[i32], target: i32) -> Option<usize> {
112
+ for (i, &item) in data.iter().enumerate() {
113
+ // Assume most iterations DON'T find the target
114
+ if unlikely(item == target) {
115
+ return Some(i);
116
+ }
117
+ }
118
+ None
119
+ }
120
+
121
+ // Alternative: structure for likely case
122
+ fn search_common(data: &[i32], target: i32) -> Option<usize> {
123
+ // If target is usually found
124
+ for (i, &item) in data.iter().enumerate() {
125
+ if likely(item == target) {
126
+ return Some(i);
127
+ }
128
+ }
129
+ None
130
+ }
131
+ ```
132
+
133
+ ## Match Arm Ordering
134
+
135
+ ```rust
136
+ // Put most common variants first
137
+ fn process_message(msg: Message) {
138
+ match msg {
139
+ // Most common - listed first
140
+ Message::Data(d) => handle_data(d),
141
+ Message::Heartbeat => (), // Second most common
142
+
143
+ // Rare cases last
144
+ Message::Error(e) => handle_error(e),
145
+ Message::Shutdown => shutdown(),
146
+ }
147
+ }
148
+ ```
149
+
150
+ ## Benchmark-Driven Hints
151
+
152
+ ```rust
153
+ // Profile first to know which branches are actually likely!
154
+ fn speculative(x: i32) -> i32 {
155
+ // DON'T GUESS - measure with profiling
156
+ // perf record / perf report
157
+ // cargo flamegraph
158
+
159
+ if x > threshold { // Is this actually common?
160
+ path_a(x)
161
+ } else {
162
+ path_b(x)
163
+ }
164
+ }
165
+ ```
166
+
167
+ ## See Also
168
+
169
+ - [opt-cold-unlikely](./opt-cold-unlikely.md) - #[cold] for unlikely functions
170
+ - [opt-inline-never-cold](./opt-inline-never-cold.md) - Keeping cold code separate
171
+ - [perf-profile-first](./perf-profile-first.md) - Profile to know what's likely
@@ -0,0 +1,130 @@
1
+ # opt-lto-release
2
+
3
+ > Enable LTO in release builds
4
+
5
+ ## Why It Matters
6
+
7
+ Link-Time Optimization (LTO) enables optimizations across crate boundaries that aren't possible during normal compilation. This includes cross-crate inlining, dead code elimination, and devirtualization. Typically provides 5-20% performance improvement.
8
+
9
+ ## Bad
10
+
11
+ ```toml
12
+ # Cargo.toml - default release profile
13
+ [profile.release]
14
+ opt-level = 3
15
+ # No LTO = missed optimization opportunities
16
+ ```
17
+
18
+ ## Good
19
+
20
+ ```toml
21
+ # Cargo.toml - optimized release profile
22
+ [profile.release]
23
+ opt-level = 3
24
+ lto = "fat" # Maximum optimization
25
+ codegen-units = 1 # Better optimization (single codegen unit)
26
+ panic = "abort" # Smaller binary, no unwind tables
27
+ strip = true # Remove symbols for smaller binary
28
+ ```
29
+
30
+ ## LTO Options Explained
31
+
32
+ ```toml
33
+ # No LTO (default)
34
+ lto = false
35
+
36
+ # Thin LTO - fast compilation, most benefits
37
+ lto = "thin"
38
+
39
+ # Fat LTO - slowest compilation, maximum optimization
40
+ lto = "fat"
41
+ # Equivalent to:
42
+ lto = true
43
+
44
+ # Thin-local - LTO within each crate only
45
+ lto = "off"
46
+ ```
47
+
48
+ ## Trade-offs
49
+
50
+ | Setting | Compile Time | Binary Size | Performance |
51
+ |---------|--------------|-------------|-------------|
52
+ | `lto = false` | Fast | Larger | Baseline |
53
+ | `lto = "thin"` | Medium | Smaller | +5-15% |
54
+ | `lto = "fat"` | Slow | Smallest | +10-20% |
55
+
56
+ ## Evidence from Production
57
+
58
+ ```toml
59
+ # From Anchor (Solana framework)
60
+ # https://github.com/solana-foundation/anchor/blob/master/cli/src/rust_template.rs
61
+ [profile.release]
62
+ overflow-checks = true
63
+ lto = "fat"
64
+ codegen-units = 1
65
+
66
+ # From sol-trade-sdk
67
+ # https://github.com/0xfnzero/sol-trade-sdk
68
+ [profile.release]
69
+ opt-level = 3
70
+ lto = "fat"
71
+ codegen-units = 1
72
+ panic = "abort"
73
+ ```
74
+
75
+ ## Complete Optimized Profile
76
+
77
+ ```toml
78
+ [profile.release]
79
+ opt-level = 3 # Maximum optimization
80
+ lto = "fat" # Link-time optimization
81
+ codegen-units = 1 # Single codegen unit for better optimization
82
+ panic = "abort" # Remove panic unwinding code
83
+ strip = true # Strip symbols
84
+ debug = false # No debug info
85
+
86
+ # For benchmarking (need some debug info for profiling)
87
+ [profile.bench]
88
+ inherits = "release"
89
+ debug = true
90
+ strip = false
91
+
92
+ # Fast dev builds with optimized dependencies
93
+ [profile.dev]
94
+ opt-level = 0
95
+ debug = true
96
+
97
+ [profile.dev.package."*"]
98
+ opt-level = 3 # Optimize dependencies even in dev
99
+ ```
100
+
101
+ ## When to Use Each
102
+
103
+ | Situation | LTO Setting |
104
+ |-----------|-------------|
105
+ | Development | `false` (fast compiles) |
106
+ | CI builds | `"thin"` (balance) |
107
+ | Release binaries | `"fat"` (max perf) |
108
+ | Libraries (crates.io) | `false` (users choose) |
109
+
110
+ ## Measuring Impact
111
+
112
+ ```bash
113
+ # Build without LTO
114
+ cargo build --release
115
+ hyperfine ./target/release/myapp
116
+
117
+ # Build with LTO
118
+ # (after adding lto = "fat" to Cargo.toml)
119
+ cargo build --release
120
+ hyperfine ./target/release/myapp
121
+
122
+ # Compare binary sizes
123
+ ls -la target/release/myapp
124
+ ```
125
+
126
+ ## See Also
127
+
128
+ - [opt-codegen-units](opt-codegen-units.md) - Use codegen-units = 1
129
+ - [opt-pgo-profile](opt-pgo-profile.md) - Profile-guided optimization
130
+ - [perf-release-profile](perf-release-profile.md) - Full release profile settings