html-to-markdown 2.23.4 → 2.24.1

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 (585) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +7 -7
  3. data/README.md +9 -7
  4. data/ext/html-to-markdown-rb/native/Cargo.lock +21 -21
  5. data/ext/html-to-markdown-rb/native/Cargo.toml +1 -3
  6. data/lib/html_to_markdown/cli_proxy.rb +5 -2
  7. data/lib/html_to_markdown/version.rb +1 -1
  8. data/rust-vendor/cc/.cargo-checksum.json +1 -1
  9. data/rust-vendor/cc/.cargo_vcs_info.json +1 -1
  10. data/rust-vendor/cc/CHANGELOG.md +7 -0
  11. data/rust-vendor/cc/Cargo.lock +1 -1
  12. data/rust-vendor/cc/Cargo.toml +1 -1
  13. data/rust-vendor/cc/Cargo.toml.orig +1 -1
  14. data/rust-vendor/cc/src/target/generated.rs +1 -0
  15. data/rust-vendor/cc/src/target/parser.rs +4 -0
  16. data/rust-vendor/html-to-markdown-rs/README.md +1 -1
  17. data/rust-vendor/html-to-markdown-rs/src/convert_api.rs +90 -15
  18. data/rust-vendor/html-to-markdown-rs/src/converter/block/preformatted.rs +15 -4
  19. data/rust-vendor/html-to-markdown-rs/src/converter/handlers/graphic.rs +5 -3
  20. data/rust-vendor/html-to-markdown-rs/src/converter/media/svg.rs +5 -1
  21. data/rust-vendor/html-to-markdown-rs/src/converter/text/processing.rs +15 -8
  22. data/rust-vendor/html-to-markdown-rs/src/converter/utility/preprocessing.rs +43 -18
  23. data/rust-vendor/html-to-markdown-rs/src/lib.rs +6 -6
  24. data/rust-vendor/html-to-markdown-rs/src/validation.rs +68 -29
  25. data/rust-vendor/html-to-markdown-rs/tests/issue_190_regressions.rs +121 -0
  26. data/rust-vendor/html-to-markdown-rs/tests/skip_images_test.rs +21 -0
  27. data/rust-vendor/proc-macro2/.cargo-checksum.json +1 -1
  28. data/rust-vendor/proc-macro2/.cargo_vcs_info.json +1 -1
  29. data/rust-vendor/proc-macro2/Cargo.lock +14 -89
  30. data/rust-vendor/proc-macro2/Cargo.toml +1 -1
  31. data/rust-vendor/proc-macro2/Cargo.toml.orig +1 -1
  32. data/rust-vendor/proc-macro2/src/fallback.rs +37 -23
  33. data/rust-vendor/proc-macro2/src/lib.rs +1 -1
  34. data/rust-vendor/quote/.cargo-checksum.json +1 -1
  35. data/rust-vendor/quote/.cargo_vcs_info.json +1 -1
  36. data/rust-vendor/quote/.github/workflows/ci.yml +1 -1
  37. data/rust-vendor/quote/Cargo.lock +17 -17
  38. data/rust-vendor/quote/Cargo.toml +1 -1
  39. data/rust-vendor/quote/Cargo.toml.orig +1 -1
  40. data/rust-vendor/quote/src/format.rs +2 -2
  41. data/rust-vendor/quote/src/lib.rs +1 -1
  42. data/rust-vendor/quote/src/runtime.rs +2 -2
  43. data/rust-vendor/quote/tests/test.rs +6 -0
  44. data/rust-vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr +2 -2
  45. data/rust-vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr +2 -2
  46. data/rust-vendor/quote/tests/ui/does-not-have-iter-separated.stderr +2 -2
  47. data/rust-vendor/quote/tests/ui/does-not-have-iter.stderr +2 -2
  48. data/rust-vendor/quote/tests/ui/not-repeatable.stderr +8 -8
  49. data/rust-vendor/siphasher/.cargo-checksum.json +1 -1
  50. data/rust-vendor/siphasher/.cargo_vcs_info.json +1 -1
  51. data/rust-vendor/siphasher/.github/workflows/issues.yml +17 -0
  52. data/rust-vendor/siphasher/COPYING +1 -1
  53. data/rust-vendor/siphasher/Cargo.lock +89 -0
  54. data/rust-vendor/siphasher/Cargo.toml +23 -13
  55. data/rust-vendor/siphasher/Cargo.toml.orig +1 -1
  56. data/rust-vendor/siphasher/src/common.rs +65 -0
  57. data/rust-vendor/siphasher/src/lib.rs +1 -1
  58. data/rust-vendor/siphasher/src/sip.rs +2 -68
  59. data/rust-vendor/siphasher/src/sip128.rs +15 -74
  60. data/rust-vendor/siphasher/src/tests.rs +1 -1
  61. data/rust-vendor/siphasher/src/tests128.rs +1 -1
  62. data/rust-vendor/uuid/.cargo-checksum.json +1 -1
  63. data/rust-vendor/uuid/.cargo_vcs_info.json +1 -1
  64. data/rust-vendor/uuid/Cargo.lock +125 -96
  65. data/rust-vendor/uuid/Cargo.toml +4 -11
  66. data/rust-vendor/uuid/Cargo.toml.orig +5 -14
  67. data/rust-vendor/uuid/README.md +3 -3
  68. data/rust-vendor/uuid/src/builder.rs +2 -1
  69. data/rust-vendor/uuid/src/external/serde_support.rs +209 -142
  70. data/rust-vendor/uuid/src/lib.rs +9 -11
  71. data/rust-vendor/uuid/src/macros.rs +9 -54
  72. data/rust-vendor/uuid/src/non_nil.rs +49 -2
  73. data/rust-vendor/web_atoms/.cargo-checksum.json +1 -1
  74. data/rust-vendor/web_atoms/.cargo_vcs_info.json +1 -1
  75. data/rust-vendor/web_atoms/Cargo.lock +1 -1
  76. data/rust-vendor/web_atoms/Cargo.toml +1 -1
  77. data/rust-vendor/web_atoms/Cargo.toml.orig +1 -1
  78. data/rust-vendor/web_atoms/local_names.txt +3 -0
  79. data/rust-vendor/zerocopy/.cargo-checksum.json +1 -1
  80. data/rust-vendor/zerocopy/.cargo_vcs_info.json +1 -1
  81. data/rust-vendor/zerocopy/Cargo.lock +5 -9
  82. data/rust-vendor/zerocopy/Cargo.toml +10 -18
  83. data/rust-vendor/zerocopy/Cargo.toml.orig +6 -14
  84. data/rust-vendor/zerocopy/Cargo.toml.std +58 -0
  85. data/rust-vendor/zerocopy/agent_docs/ui_tests.md +5 -5
  86. data/rust-vendor/zerocopy/cargo.sh +1 -1
  87. data/rust-vendor/zerocopy/ci/check_fmt.sh +1 -1
  88. data/rust-vendor/zerocopy/ci/check_readme.sh +1 -1
  89. data/rust-vendor/zerocopy/ci/check_stale_stderr.sh +44 -0
  90. data/rust-vendor/zerocopy/githooks/pre-push +2 -0
  91. data/rust-vendor/zerocopy/src/byte_slice.rs +1 -1
  92. data/rust-vendor/zerocopy/src/byteorder.rs +0 -1
  93. data/rust-vendor/zerocopy/src/impls.rs +334 -118
  94. data/rust-vendor/zerocopy/src/layout.rs +9 -0
  95. data/rust-vendor/zerocopy/src/lib.rs +163 -74
  96. data/rust-vendor/zerocopy/src/macros.rs +4 -8
  97. data/rust-vendor/zerocopy/src/pointer/inner.rs +4 -4
  98. data/rust-vendor/zerocopy/src/pointer/invariant.rs +22 -5
  99. data/rust-vendor/zerocopy/src/pointer/mod.rs +155 -18
  100. data/rust-vendor/zerocopy/src/pointer/ptr.rs +133 -182
  101. data/rust-vendor/zerocopy/src/pointer/transmute.rs +99 -106
  102. data/rust-vendor/zerocopy/src/ref.rs +4 -4
  103. data/rust-vendor/zerocopy/src/util/macro_util.rs +73 -127
  104. data/rust-vendor/zerocopy/src/util/macros.rs +61 -150
  105. data/rust-vendor/zerocopy/src/wrappers.rs +249 -3
  106. data/rust-vendor/zerocopy/tests/include.rs +67 -0
  107. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-from-bytes.rs +1 -3
  108. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-from-bytes.stderr +6 -6
  109. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-from-zeros.rs +1 -3
  110. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-from-zeros.stderr +4 -4
  111. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-immutable.rs +1 -3
  112. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-immutable.stderr +6 -6
  113. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-into-bytes.rs +1 -3
  114. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-into-bytes.stderr +6 -6
  115. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-issue-1296.rs +1 -3
  116. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-issue-1296.stderr +8 -8
  117. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-known-layout.rs +1 -3
  118. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-known-layout.stderr +6 -6
  119. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-try-from-bytes.rs +1 -3
  120. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-try-from-bytes.stderr +6 -6
  121. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-unaligned.rs +1 -3
  122. data/rust-vendor/zerocopy/tests/ui-msrv/diagnostic-not-implemented-unaligned.stderr +4 -4
  123. data/rust-vendor/zerocopy/tests/ui-msrv/include_value_not_from_bytes.rs +3 -5
  124. data/rust-vendor/zerocopy/tests/ui-msrv/include_value_not_from_bytes.stderr +10 -10
  125. data/rust-vendor/zerocopy/tests/ui-msrv/include_value_wrong_size.rs +1 -4
  126. data/rust-vendor/zerocopy/tests/ui-msrv/include_value_wrong_size.stderr +3 -3
  127. data/rust-vendor/zerocopy/tests/ui-msrv/invalid-impls/invalid-impls.rs +0 -1
  128. data/rust-vendor/zerocopy/tests/ui-msrv/invalid-impls/invalid-impls.stderr +35 -35
  129. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-dst-not-frombytes.rs +1 -3
  130. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-dst-not-frombytes.stderr +6 -6
  131. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-const.rs +1 -3
  132. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-const.stderr +10 -10
  133. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-not-a-reference.rs +0 -2
  134. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-not-a-reference.stderr +2 -2
  135. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-not-frombytes.rs +0 -2
  136. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-not-frombytes.stderr +2 -2
  137. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-not-intobytes.rs +0 -2
  138. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-not-intobytes.stderr +2 -2
  139. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-unsized.rs +0 -2
  140. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-unsized.stderr +2 -2
  141. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-dst-not-references.rs +0 -2
  142. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-dst-not-references.stderr +2 -2
  143. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-immutable.rs +0 -2
  144. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-immutable.stderr +2 -2
  145. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-not-a-reference.rs +0 -2
  146. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-not-a-reference.stderr +2 -2
  147. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-not-frombytes.rs +0 -2
  148. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-not-frombytes.stderr +2 -2
  149. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-not-intobytes.rs +0 -2
  150. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-not-intobytes.stderr +2 -2
  151. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-unsized.rs +0 -2
  152. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-unsized.stderr +2 -2
  153. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ptr-to-usize.rs +0 -2
  154. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ptr-to-usize.stderr +4 -4
  155. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-mutable.rs +0 -2
  156. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-mutable.stderr +6 -6
  157. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-not-a-reference.rs +0 -2
  158. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-not-a-reference.stderr +6 -6
  159. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-not-frombytes.rs +1 -3
  160. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-not-frombytes.stderr +6 -6
  161. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-not-nocell.rs +1 -3
  162. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-not-nocell.stderr +6 -6
  163. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-unsized.rs +0 -2
  164. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-unsized.stderr +2 -2
  165. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-dst-not-references.rs +0 -2
  166. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-dst-not-references.stderr +8 -8
  167. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-not-a-reference.rs +0 -2
  168. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-not-a-reference.stderr +2 -2
  169. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-not-intobytes.rs +1 -3
  170. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-not-intobytes.stderr +12 -12
  171. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-not-nocell.rs +1 -3
  172. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-not-nocell.stderr +12 -12
  173. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-unsized.rs +0 -2
  174. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-unsized.stderr +2 -2
  175. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-size-decrease.rs +1 -3
  176. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-size-decrease.stderr +2 -2
  177. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-size-increase-allow-shrink.rs +1 -3
  178. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-size-increase-allow-shrink.stderr +2 -2
  179. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-size-increase.rs +1 -3
  180. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-size-increase.stderr +2 -2
  181. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-src-not-intobytes.rs +1 -3
  182. data/rust-vendor/zerocopy/tests/ui-msrv/transmute-src-not-intobytes.stderr +6 -6
  183. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute-dst-not-tryfrombytes.rs +1 -3
  184. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute-dst-not-tryfrombytes.stderr +12 -12
  185. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute-size-decrease.rs +1 -3
  186. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute-size-decrease.stderr +2 -2
  187. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute-size-increase.rs +1 -3
  188. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute-size-increase.stderr +2 -2
  189. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute-src-not-intobytes.rs +1 -3
  190. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute-src-not-intobytes.stderr +4 -4
  191. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-alignment-increase.rs +1 -3
  192. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-alignment-increase.stderr +2 -2
  193. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-dst-not-tryfrombytes.rs +1 -3
  194. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-dst-not-tryfrombytes.stderr +16 -16
  195. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-size-decrease.rs +1 -3
  196. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-size-decrease.stderr +2 -2
  197. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-size-increase.rs +1 -3
  198. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-size-increase.stderr +4 -4
  199. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-src-not-frombytes.rs +0 -2
  200. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-src-not-frombytes.stderr +6 -6
  201. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-src-not-intobytes.rs +0 -2
  202. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-src-not-intobytes.stderr +6 -6
  203. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-alignment-increase.rs +1 -3
  204. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-alignment-increase.stderr +2 -2
  205. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-dst-mutable.rs +0 -2
  206. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-dst-mutable.stderr +4 -4
  207. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-dst-not-immutable-tryfrombytes.rs +1 -3
  208. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-dst-not-immutable-tryfrombytes.stderr +16 -16
  209. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-size-decrease.rs +1 -3
  210. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-size-decrease.stderr +2 -2
  211. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-size-increase.rs +1 -3
  212. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-size-increase.stderr +2 -2
  213. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-src-not-immutable-intobytes.rs +1 -3
  214. data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-src-not-immutable-intobytes.stderr +8 -8
  215. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-from-bytes.rs +1 -3
  216. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-from-bytes.stderr +15 -15
  217. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-from-zeros.rs +1 -3
  218. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-from-zeros.stderr +12 -12
  219. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-immutable.rs +1 -3
  220. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-immutable.stderr +13 -13
  221. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-into-bytes.rs +1 -3
  222. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-into-bytes.stderr +8 -8
  223. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-issue-1296.rs +1 -3
  224. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-issue-1296.stderr +16 -16
  225. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-known-layout.rs +1 -3
  226. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-known-layout.stderr +8 -8
  227. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-try-from-bytes.rs +1 -3
  228. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-try-from-bytes.stderr +15 -15
  229. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-unaligned.rs +1 -3
  230. data/rust-vendor/zerocopy/tests/ui-nightly/diagnostic-not-implemented-unaligned.stderr +5 -5
  231. data/rust-vendor/zerocopy/tests/ui-nightly/include_value_not_from_bytes.rs +3 -5
  232. data/rust-vendor/zerocopy/tests/ui-nightly/include_value_not_from_bytes.stderr +21 -21
  233. data/rust-vendor/zerocopy/tests/ui-nightly/include_value_wrong_size.rs +1 -4
  234. data/rust-vendor/zerocopy/tests/ui-nightly/include_value_wrong_size.stderr +8 -8
  235. data/rust-vendor/zerocopy/tests/ui-nightly/invalid-impls/invalid-impls.rs +0 -1
  236. data/rust-vendor/zerocopy/tests/ui-nightly/invalid-impls/invalid-impls.stderr +35 -51
  237. data/rust-vendor/zerocopy/tests/ui-nightly/ptr-is-invariant-over-v.stderr +2 -2
  238. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-dst-not-frombytes.rs +1 -3
  239. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-dst-not-frombytes.stderr +15 -15
  240. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-const.rs +1 -3
  241. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-const.stderr +7 -7
  242. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-not-a-reference.rs +0 -2
  243. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-not-a-reference.stderr +2 -2
  244. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-not-frombytes.rs +0 -2
  245. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-not-frombytes.stderr +12 -12
  246. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-not-intobytes.rs +0 -2
  247. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-not-intobytes.stderr +5 -5
  248. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-unsized.rs +0 -2
  249. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-unsized.stderr +3 -3
  250. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-dst-not-references.rs +0 -2
  251. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-dst-not-references.stderr +3 -3
  252. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-immutable.rs +0 -2
  253. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-immutable.stderr +2 -2
  254. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-not-a-reference.rs +0 -2
  255. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-not-a-reference.stderr +3 -3
  256. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-not-frombytes.rs +0 -2
  257. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-not-frombytes.stderr +12 -12
  258. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-not-intobytes.rs +0 -2
  259. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-not-intobytes.stderr +5 -5
  260. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-unsized.rs +0 -2
  261. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-unsized.stderr +3 -3
  262. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ptr-to-usize.rs +0 -2
  263. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ptr-to-usize.stderr +4 -4
  264. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-mutable.rs +0 -2
  265. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-mutable.stderr +6 -6
  266. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-not-a-reference.rs +0 -2
  267. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-not-a-reference.stderr +6 -6
  268. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-not-frombytes.rs +1 -3
  269. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-not-frombytes.stderr +16 -16
  270. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-not-nocell.rs +1 -3
  271. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-not-nocell.stderr +14 -14
  272. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-unsized.rs +0 -2
  273. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-unsized.stderr +3 -3
  274. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-dst-not-references.rs +0 -2
  275. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-dst-not-references.stderr +9 -9
  276. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-not-a-reference.rs +0 -2
  277. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-not-a-reference.stderr +3 -3
  278. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-not-intobytes.rs +1 -3
  279. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-not-intobytes.stderr +18 -18
  280. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-not-nocell.rs +1 -3
  281. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-not-nocell.stderr +28 -28
  282. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-unsized.rs +0 -2
  283. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-unsized.stderr +3 -3
  284. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-size-decrease.rs +1 -3
  285. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-size-decrease.stderr +4 -4
  286. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-size-increase-allow-shrink.rs +1 -3
  287. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-size-increase-allow-shrink.stderr +4 -4
  288. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-size-increase.rs +1 -3
  289. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-size-increase.stderr +4 -4
  290. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-src-not-intobytes.rs +1 -3
  291. data/rust-vendor/zerocopy/tests/ui-nightly/transmute-src-not-intobytes.stderr +8 -8
  292. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute-dst-not-tryfrombytes.rs +1 -3
  293. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute-dst-not-tryfrombytes.stderr +43 -43
  294. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute-size-decrease.rs +1 -3
  295. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute-size-decrease.stderr +2 -2
  296. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute-size-increase.rs +1 -3
  297. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute-size-increase.stderr +2 -2
  298. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute-src-not-intobytes.rs +1 -3
  299. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute-src-not-intobytes.stderr +8 -8
  300. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-alignment-increase.rs +1 -3
  301. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-alignment-increase.stderr +4 -4
  302. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-dst-not-tryfrombytes.rs +1 -3
  303. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-dst-not-tryfrombytes.stderr +51 -51
  304. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-size-decrease.rs +1 -3
  305. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-size-decrease.stderr +2 -2
  306. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-size-increase.rs +1 -3
  307. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-size-increase.stderr +4 -4
  308. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-src-not-frombytes.rs +0 -2
  309. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-src-not-frombytes.stderr +29 -29
  310. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-src-not-intobytes.rs +0 -2
  311. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-src-not-intobytes.stderr +22 -22
  312. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-alignment-increase.rs +1 -3
  313. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-alignment-increase.stderr +4 -4
  314. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-dst-mutable.rs +0 -2
  315. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-dst-mutable.stderr +6 -6
  316. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-dst-not-immutable-tryfrombytes.rs +1 -3
  317. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-dst-not-immutable-tryfrombytes.stderr +56 -56
  318. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-size-decrease.rs +1 -3
  319. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-size-decrease.stderr +2 -2
  320. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-size-increase.rs +1 -3
  321. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-size-increase.stderr +4 -4
  322. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-src-not-immutable-intobytes.rs +1 -3
  323. data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-src-not-immutable-intobytes.stderr +21 -21
  324. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-from-bytes.rs +1 -3
  325. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-from-bytes.stderr +15 -15
  326. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-from-zeros.rs +1 -3
  327. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-from-zeros.stderr +12 -12
  328. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-immutable.rs +1 -3
  329. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-immutable.stderr +13 -13
  330. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-into-bytes.rs +1 -3
  331. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-into-bytes.stderr +8 -8
  332. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-issue-1296.rs +1 -3
  333. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-issue-1296.stderr +16 -16
  334. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-known-layout.rs +1 -3
  335. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-known-layout.stderr +8 -8
  336. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-try-from-bytes.rs +1 -3
  337. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-try-from-bytes.stderr +15 -15
  338. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-unaligned.rs +1 -3
  339. data/rust-vendor/zerocopy/tests/ui-stable/diagnostic-not-implemented-unaligned.stderr +5 -5
  340. data/rust-vendor/zerocopy/tests/ui-stable/include_value_not_from_bytes.rs +3 -5
  341. data/rust-vendor/zerocopy/tests/ui-stable/include_value_not_from_bytes.stderr +21 -21
  342. data/rust-vendor/zerocopy/tests/ui-stable/include_value_wrong_size.rs +1 -4
  343. data/rust-vendor/zerocopy/tests/ui-stable/include_value_wrong_size.stderr +8 -8
  344. data/rust-vendor/zerocopy/tests/ui-stable/invalid-impls/invalid-impls.rs +0 -1
  345. data/rust-vendor/zerocopy/tests/ui-stable/invalid-impls/invalid-impls.stderr +37 -37
  346. data/rust-vendor/zerocopy/tests/ui-stable/ptr-is-invariant-over-v.stderr +2 -2
  347. data/rust-vendor/zerocopy/tests/ui-stable/transmute-dst-not-frombytes.rs +1 -3
  348. data/rust-vendor/zerocopy/tests/ui-stable/transmute-dst-not-frombytes.stderr +15 -15
  349. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-const.rs +1 -3
  350. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-const.stderr +6 -6
  351. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-not-a-reference.rs +0 -2
  352. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-not-a-reference.stderr +2 -2
  353. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-not-frombytes.rs +0 -2
  354. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-not-frombytes.stderr +11 -11
  355. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-not-intobytes.rs +0 -2
  356. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-not-intobytes.stderr +4 -4
  357. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-unsized.rs +0 -2
  358. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-unsized.stderr +2 -2
  359. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-dst-not-references.rs +0 -2
  360. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-dst-not-references.stderr +3 -3
  361. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-immutable.rs +0 -2
  362. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-immutable.stderr +2 -2
  363. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-not-a-reference.rs +0 -2
  364. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-not-a-reference.stderr +3 -3
  365. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-not-frombytes.rs +0 -2
  366. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-not-frombytes.stderr +11 -11
  367. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-not-intobytes.rs +0 -2
  368. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-not-intobytes.stderr +4 -4
  369. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-unsized.rs +0 -2
  370. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-unsized.stderr +2 -2
  371. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ptr-to-usize.rs +0 -2
  372. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ptr-to-usize.stderr +9 -5
  373. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-mutable.rs +0 -2
  374. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-mutable.stderr +6 -6
  375. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-not-a-reference.rs +0 -2
  376. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-not-a-reference.stderr +6 -6
  377. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-not-frombytes.rs +1 -3
  378. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-not-frombytes.stderr +16 -16
  379. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-not-nocell.rs +1 -3
  380. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-not-nocell.stderr +14 -14
  381. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-unsized.rs +0 -2
  382. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-unsized.stderr +2 -2
  383. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-dst-not-references.rs +0 -2
  384. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-dst-not-references.stderr +9 -9
  385. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-not-a-reference.rs +0 -2
  386. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-not-a-reference.stderr +3 -3
  387. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-not-intobytes.rs +1 -3
  388. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-not-intobytes.stderr +18 -18
  389. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-not-nocell.rs +1 -3
  390. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-not-nocell.stderr +28 -28
  391. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-unsized.rs +0 -2
  392. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-unsized.stderr +2 -2
  393. data/rust-vendor/zerocopy/tests/ui-stable/transmute-size-decrease.rs +1 -3
  394. data/rust-vendor/zerocopy/tests/ui-stable/transmute-size-decrease.stderr +4 -4
  395. data/rust-vendor/zerocopy/tests/ui-stable/transmute-size-increase-allow-shrink.rs +1 -3
  396. data/rust-vendor/zerocopy/tests/ui-stable/transmute-size-increase-allow-shrink.stderr +4 -4
  397. data/rust-vendor/zerocopy/tests/ui-stable/transmute-size-increase.rs +1 -3
  398. data/rust-vendor/zerocopy/tests/ui-stable/transmute-size-increase.stderr +4 -4
  399. data/rust-vendor/zerocopy/tests/ui-stable/transmute-src-not-intobytes.rs +1 -3
  400. data/rust-vendor/zerocopy/tests/ui-stable/transmute-src-not-intobytes.stderr +8 -8
  401. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute-dst-not-tryfrombytes.rs +1 -3
  402. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute-dst-not-tryfrombytes.stderr +42 -42
  403. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute-size-decrease.rs +1 -3
  404. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute-size-decrease.stderr +2 -2
  405. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute-size-increase.rs +1 -3
  406. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute-size-increase.stderr +2 -2
  407. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute-src-not-intobytes.rs +1 -3
  408. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute-src-not-intobytes.stderr +7 -7
  409. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-alignment-increase.rs +1 -3
  410. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-alignment-increase.stderr +2 -2
  411. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-dst-not-tryfrombytes.rs +1 -3
  412. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-dst-not-tryfrombytes.stderr +49 -49
  413. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-size-decrease.rs +1 -3
  414. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-size-decrease.stderr +2 -2
  415. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-size-increase.rs +1 -3
  416. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-size-increase.stderr +4 -4
  417. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-src-not-frombytes.rs +0 -2
  418. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-src-not-frombytes.stderr +26 -26
  419. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-src-not-intobytes.rs +0 -2
  420. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-src-not-intobytes.stderr +19 -19
  421. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-alignment-increase.rs +1 -3
  422. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-alignment-increase.stderr +2 -2
  423. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-dst-mutable.rs +0 -2
  424. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-dst-mutable.stderr +6 -6
  425. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-dst-not-immutable-tryfrombytes.rs +1 -3
  426. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-dst-not-immutable-tryfrombytes.stderr +54 -54
  427. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-size-decrease.rs +1 -3
  428. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-size-decrease.stderr +2 -2
  429. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-size-increase.rs +1 -3
  430. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-size-increase.stderr +2 -2
  431. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-src-not-immutable-intobytes.rs +1 -3
  432. data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-src-not-immutable-intobytes.stderr +19 -19
  433. data/rust-vendor/zerocopy-derive/.cargo-checksum.json +1 -1
  434. data/rust-vendor/zerocopy-derive/.cargo_vcs_info.json +1 -1
  435. data/rust-vendor/zerocopy-derive/Cargo.lock +3 -11
  436. data/rust-vendor/zerocopy-derive/Cargo.toml +13 -11
  437. data/rust-vendor/zerocopy-derive/Cargo.toml.orig +7 -10
  438. data/rust-vendor/zerocopy-derive/src/derive/from_bytes.rs +188 -0
  439. data/rust-vendor/zerocopy-derive/src/derive/into_bytes.rs +158 -0
  440. data/rust-vendor/zerocopy-derive/src/derive/known_layout.rs +348 -0
  441. data/rust-vendor/zerocopy-derive/src/derive/mod.rs +130 -0
  442. data/rust-vendor/zerocopy-derive/src/derive/try_from_bytes.rs +729 -0
  443. data/rust-vendor/zerocopy-derive/src/derive/unaligned.rs +78 -0
  444. data/rust-vendor/zerocopy-derive/src/lib.rs +31 -1893
  445. data/rust-vendor/zerocopy-derive/src/output_tests/expected/eq.expected.rs +17 -0
  446. data/rust-vendor/zerocopy-derive/src/output_tests/expected/from_bytes_enum.expected.rs +64 -0
  447. data/rust-vendor/zerocopy-derive/src/output_tests/expected/from_bytes_struct.expected.rs +64 -0
  448. data/rust-vendor/zerocopy-derive/src/output_tests/expected/from_bytes_union.expected.rs +144 -0
  449. data/rust-vendor/zerocopy-derive/src/output_tests/expected/from_zeros.expected.rs +39 -0
  450. data/rust-vendor/zerocopy-derive/src/output_tests/expected/hash.expected.rs +24 -0
  451. data/rust-vendor/zerocopy-derive/src/output_tests/expected/immutable.expected.rs +17 -0
  452. data/rust-vendor/zerocopy-derive/src/output_tests/expected/into_bytes_enum.expected.rs +17 -0
  453. data/rust-vendor/zerocopy-derive/src/output_tests/expected/into_bytes_struct_basic.expected.rs +25 -0
  454. data/rust-vendor/zerocopy-derive/src/output_tests/expected/into_bytes_struct_empty.expected.rs +17 -0
  455. data/rust-vendor/zerocopy-derive/src/output_tests/expected/into_bytes_struct_trailing.expected.rs +25 -0
  456. data/rust-vendor/zerocopy-derive/src/output_tests/expected/into_bytes_struct_trailing_generic.expected.rs +21 -0
  457. data/rust-vendor/zerocopy-derive/src/output_tests/expected/known_layout_repr_c_struct.expected.rs +135 -0
  458. data/rust-vendor/zerocopy-derive/src/output_tests/expected/known_layout_struct.expected.rs +34 -0
  459. data/rust-vendor/zerocopy-derive/src/output_tests/expected/split_at_repr_c.expected.rs +22 -0
  460. data/rust-vendor/zerocopy-derive/src/output_tests/expected/split_at_repr_transparent.expected.rs +22 -0
  461. data/rust-vendor/zerocopy-derive/src/output_tests/expected/try_from_bytes.expected.rs +22 -0
  462. data/rust-vendor/zerocopy-derive/src/output_tests/expected/try_from_bytes_enum_1.expected.rs +2802 -0
  463. data/rust-vendor/zerocopy-derive/src/output_tests/expected/try_from_bytes_enum_2.expected.rs +2802 -0
  464. data/rust-vendor/zerocopy-derive/src/output_tests/expected/try_from_bytes_enum_3.expected.rs +2802 -0
  465. data/rust-vendor/zerocopy-derive/src/output_tests/expected/try_from_bytes_trivial_is_bit_valid_enum.expected.rs +22 -0
  466. data/rust-vendor/zerocopy-derive/src/output_tests/expected/unaligned.expected.rs +17 -0
  467. data/rust-vendor/zerocopy-derive/src/output_tests/mod.rs +960 -0
  468. data/rust-vendor/zerocopy-derive/src/util.rs +757 -0
  469. data/rust-vendor/zerocopy-derive/tests/deprecated.rs +6 -0
  470. data/rust-vendor/zerocopy-derive/tests/enum_from_zeros.rs +9 -0
  471. data/rust-vendor/zerocopy-derive/tests/enum_known_layout.rs +4 -0
  472. data/rust-vendor/zerocopy-derive/tests/enum_no_cell.rs +4 -0
  473. data/rust-vendor/zerocopy-derive/tests/enum_to_bytes.rs +14 -0
  474. data/rust-vendor/zerocopy-derive/tests/enum_try_from_bytes.rs +37 -15
  475. data/rust-vendor/zerocopy-derive/tests/enum_unaligned.rs +4 -0
  476. data/rust-vendor/zerocopy-derive/tests/eq.rs +1 -0
  477. data/rust-vendor/zerocopy-derive/tests/hash.rs +1 -0
  478. data/rust-vendor/zerocopy-derive/tests/hygiene.rs +3 -1
  479. data/rust-vendor/zerocopy-derive/tests/include.rs +26 -4
  480. data/rust-vendor/zerocopy-derive/tests/issue_2117.rs +1 -0
  481. data/rust-vendor/zerocopy-derive/tests/issue_2835.rs +2 -1
  482. data/rust-vendor/zerocopy-derive/tests/issue_2880.rs +292 -0
  483. data/rust-vendor/zerocopy-derive/tests/issue_2915.rs +78 -0
  484. data/rust-vendor/zerocopy-derive/tests/paths_and_modules.rs +3 -0
  485. data/rust-vendor/zerocopy-derive/tests/priv_in_pub.rs +2 -0
  486. data/rust-vendor/zerocopy-derive/tests/struct_from_bytes.rs +6 -0
  487. data/rust-vendor/zerocopy-derive/tests/struct_from_zeros.rs +6 -0
  488. data/rust-vendor/zerocopy-derive/tests/struct_known_layout.rs +9 -0
  489. data/rust-vendor/zerocopy-derive/tests/struct_no_cell.rs +8 -0
  490. data/rust-vendor/zerocopy-derive/tests/struct_to_bytes.rs +17 -0
  491. data/rust-vendor/zerocopy-derive/tests/struct_try_from_bytes.rs +29 -65
  492. data/rust-vendor/zerocopy-derive/tests/struct_unaligned.rs +7 -0
  493. data/rust-vendor/zerocopy-derive/tests/ui-msrv/derive_transparent.rs +3 -2
  494. data/rust-vendor/zerocopy-derive/tests/ui-msrv/derive_transparent.stderr +32 -32
  495. data/rust-vendor/zerocopy-derive/tests/ui-msrv/enum.rs +48 -1
  496. data/rust-vendor/zerocopy-derive/tests/ui-msrv/enum.stderr +129 -126
  497. data/rust-vendor/zerocopy-derive/tests/ui-msrv/enum_from_bytes_u8_too_few.rs +2 -1
  498. data/rust-vendor/zerocopy-derive/tests/ui-msrv/enum_from_bytes_u8_too_few.stderr +6 -6
  499. data/rust-vendor/zerocopy-derive/tests/ui-msrv/late_compile_pass.rs +9 -2
  500. data/rust-vendor/zerocopy-derive/tests/ui-msrv/late_compile_pass.stderr +37 -37
  501. data/rust-vendor/zerocopy-derive/tests/ui-msrv/mid_compile_pass.rs +6 -2
  502. data/rust-vendor/zerocopy-derive/tests/ui-msrv/mid_compile_pass.stderr +26 -26
  503. data/rust-vendor/zerocopy-derive/tests/ui-msrv/msrv_specific.rs +3 -2
  504. data/rust-vendor/zerocopy-derive/tests/ui-msrv/msrv_specific.stderr +7 -7
  505. data/rust-vendor/zerocopy-derive/tests/ui-msrv/privacy.rs +66 -29
  506. data/rust-vendor/zerocopy-derive/tests/ui-msrv/privacy.stderr +78 -78
  507. data/rust-vendor/zerocopy-derive/tests/ui-msrv/struct.rs +34 -2
  508. data/rust-vendor/zerocopy-derive/tests/ui-msrv/struct.stderr +79 -79
  509. data/rust-vendor/zerocopy-derive/tests/ui-msrv/union.rs +12 -1
  510. data/rust-vendor/zerocopy-derive/tests/ui-msrv/union.stderr +29 -29
  511. data/rust-vendor/zerocopy-derive/tests/ui-msrv/union_into_bytes_cfg/union_into_bytes_cfg.rs +3 -2
  512. data/rust-vendor/zerocopy-derive/tests/ui-nightly/absence_of_deprecated_warning.rs +3 -2
  513. data/rust-vendor/zerocopy-derive/tests/ui-nightly/absence_of_deprecated_warning.stderr +2 -2
  514. data/rust-vendor/zerocopy-derive/tests/ui-nightly/derive_transparent.rs +3 -2
  515. data/rust-vendor/zerocopy-derive/tests/ui-nightly/derive_transparent.stderr +57 -57
  516. data/rust-vendor/zerocopy-derive/tests/ui-nightly/enum.rs +48 -1
  517. data/rust-vendor/zerocopy-derive/tests/ui-nightly/enum.stderr +200 -192
  518. data/rust-vendor/zerocopy-derive/tests/ui-nightly/enum_from_bytes_u8_too_few.rs +2 -1
  519. data/rust-vendor/zerocopy-derive/tests/ui-nightly/enum_from_bytes_u8_too_few.stderr +6 -6
  520. data/rust-vendor/zerocopy-derive/tests/ui-nightly/late_compile_pass.rs +9 -2
  521. data/rust-vendor/zerocopy-derive/tests/ui-nightly/late_compile_pass.stderr +105 -105
  522. data/rust-vendor/zerocopy-derive/tests/ui-nightly/mid_compile_pass.rs +6 -2
  523. data/rust-vendor/zerocopy-derive/tests/ui-nightly/mid_compile_pass.stderr +29 -29
  524. data/rust-vendor/zerocopy-derive/tests/ui-nightly/privacy.rs +66 -29
  525. data/rust-vendor/zerocopy-derive/tests/ui-nightly/privacy.stderr +15 -15
  526. data/rust-vendor/zerocopy-derive/tests/ui-nightly/struct.rs +34 -2
  527. data/rust-vendor/zerocopy-derive/tests/ui-nightly/struct.stderr +130 -129
  528. data/rust-vendor/zerocopy-derive/tests/ui-nightly/union.rs +12 -1
  529. data/rust-vendor/zerocopy-derive/tests/ui-nightly/union.stderr +42 -42
  530. data/rust-vendor/zerocopy-derive/tests/ui-nightly/union_into_bytes_cfg/union_into_bytes_cfg.rs +3 -2
  531. data/rust-vendor/zerocopy-derive/tests/ui-stable/derive_transparent.rs +3 -2
  532. data/rust-vendor/zerocopy-derive/tests/ui-stable/derive_transparent.stderr +57 -57
  533. data/rust-vendor/zerocopy-derive/tests/ui-stable/enum.rs +48 -1
  534. data/rust-vendor/zerocopy-derive/tests/ui-stable/enum.stderr +201 -186
  535. data/rust-vendor/zerocopy-derive/tests/ui-stable/enum_from_bytes_u8_too_few.rs +2 -1
  536. data/rust-vendor/zerocopy-derive/tests/ui-stable/enum_from_bytes_u8_too_few.stderr +6 -6
  537. data/rust-vendor/zerocopy-derive/tests/ui-stable/late_compile_pass.rs +9 -2
  538. data/rust-vendor/zerocopy-derive/tests/ui-stable/late_compile_pass.stderr +105 -105
  539. data/rust-vendor/zerocopy-derive/tests/ui-stable/mid_compile_pass.rs +6 -2
  540. data/rust-vendor/zerocopy-derive/tests/ui-stable/mid_compile_pass.stderr +29 -29
  541. data/rust-vendor/zerocopy-derive/tests/ui-stable/privacy.rs +66 -29
  542. data/rust-vendor/zerocopy-derive/tests/ui-stable/privacy.stderr +15 -15
  543. data/rust-vendor/zerocopy-derive/tests/ui-stable/struct.rs +34 -2
  544. data/rust-vendor/zerocopy-derive/tests/ui-stable/struct.stderr +158 -129
  545. data/rust-vendor/zerocopy-derive/tests/ui-stable/union.rs +12 -1
  546. data/rust-vendor/zerocopy-derive/tests/ui-stable/union.stderr +48 -44
  547. data/rust-vendor/zerocopy-derive/tests/ui-stable/union_into_bytes_cfg/union_into_bytes_cfg.rs +3 -2
  548. data/rust-vendor/zerocopy-derive/tests/union_from_bytes.rs +15 -0
  549. data/rust-vendor/zerocopy-derive/tests/union_from_zeros.rs +14 -0
  550. data/rust-vendor/zerocopy-derive/tests/union_known_layout.rs +5 -0
  551. data/rust-vendor/zerocopy-derive/tests/union_no_cell.rs +5 -0
  552. data/rust-vendor/zerocopy-derive/tests/union_to_bytes.rs +5 -0
  553. data/rust-vendor/zerocopy-derive/tests/union_try_from_bytes.rs +34 -74
  554. data/rust-vendor/zerocopy-derive/tests/union_unaligned.rs +4 -1
  555. data/rust-vendor/zerocopy-derive/tests/unsafe_cell.rs +3 -0
  556. data/rust-vendor/zmij/.cargo-checksum.json +1 -1
  557. data/rust-vendor/zmij/.cargo_vcs_info.json +1 -1
  558. data/rust-vendor/zmij/Cargo.lock +10 -10
  559. data/rust-vendor/zmij/Cargo.toml +1 -1
  560. data/rust-vendor/zmij/Cargo.toml.orig +1 -1
  561. data/rust-vendor/zmij/README.md +1 -1
  562. data/rust-vendor/zmij/src/lib.rs +132 -158
  563. data/rust-vendor/zune-jpeg/.cargo-checksum.json +1 -1
  564. data/rust-vendor/zune-jpeg/.cargo_vcs_info.json +1 -1
  565. data/rust-vendor/zune-jpeg/Cargo.lock +1 -1
  566. data/rust-vendor/zune-jpeg/Cargo.toml +1 -1
  567. data/rust-vendor/zune-jpeg/Cargo.toml.orig +1 -1
  568. data/rust-vendor/zune-jpeg/src/bitstream.rs +1 -1
  569. data/rust-vendor/zune-jpeg/src/components.rs +2 -1
  570. data/rust-vendor/zune-jpeg/src/decoder.rs +3 -23
  571. data/rust-vendor/zune-jpeg/src/headers.rs +19 -1
  572. data/rust-vendor/zune-jpeg/src/lib.rs +1 -0
  573. data/rust-vendor/zune-jpeg/src/mcu.rs +6 -6
  574. data/rust-vendor/zune-jpeg/src/mcu_prog.rs +22 -34
  575. data/rust-vendor/zune-jpeg/src/upsampler/avx2.rs +3 -1
  576. data/rust-vendor/zune-jpeg/src/upsampler/neon.rs +13 -23
  577. data/rust-vendor/zune-jpeg/src/upsampler/portable_simd.rs +4 -1
  578. data/rust-vendor/zune-jpeg/src/upsampler/scalar.rs +4 -1
  579. metadata +41 -8
  580. data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-dst-unsized.stderr +0 -183
  581. data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-dst-unsized.stderr +0 -183
  582. data/rust-vendor/zerocopy-derive/src/enum.rs +0 -456
  583. data/rust-vendor/zerocopy-derive/src/ext.rs +0 -123
  584. data/rust-vendor/zerocopy-derive/src/output_tests.rs +0 -5608
  585. data/rust-vendor/zerocopy-derive/tests/crate_path.rs +0 -189
@@ -39,25 +39,19 @@
39
39
 
40
40
  macro_rules! ident {
41
41
  (($fmt:literal $(, $arg:expr)*), $span:expr) => {
42
- syn::Ident::new(&format!($fmt $(, crate::ext::to_ident_str($arg))*), $span)
42
+ syn::Ident::new(&format!($fmt $(, crate::util::to_ident_str($arg))*), $span)
43
43
  };
44
44
  }
45
45
 
46
- mod r#enum;
47
- mod ext;
46
+ mod derive;
48
47
  #[cfg(test)]
49
48
  mod output_tests;
50
49
  mod repr;
50
+ mod util;
51
51
 
52
- use proc_macro2::{Span, TokenStream};
53
- use quote::{quote, ToTokens};
54
- use syn::{
55
- parse_quote, spanned::Spanned as _, Attribute, Data, DataEnum, DataStruct, DataUnion,
56
- DeriveInput, Error, Expr, ExprLit, ExprUnary, GenericParam, Ident, Lit, Meta, Path, Type, UnOp,
57
- WherePredicate,
58
- };
52
+ use syn::{DeriveInput, Error};
59
53
 
60
- use crate::{ext::*, repr::*};
54
+ use crate::util::*;
61
55
 
62
56
  // FIXME(https://github.com/rust-lang/rust/issues/54140): Some errors could be
63
57
  // made better if we could add multiple lines of error output like this:
@@ -83,31 +77,38 @@ use crate::{ext::*, repr::*};
83
77
  /// are currently required to live at the crate root, and so the caller must
84
78
  /// specify the name in order to avoid name collisions.
85
79
  macro_rules! derive {
86
- ($trait:ident => $outer:ident => $inner:ident) => {
80
+ ($trait:ident => $outer:ident => $inner:path) => {
87
81
  #[proc_macro_derive($trait, attributes(zerocopy))]
88
82
  pub fn $outer(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
89
83
  let ast = syn::parse_macro_input!(ts as DeriveInput);
90
- let zerocopy_crate = match extract_zerocopy_crate(&ast.attrs) {
91
- Ok(zerocopy_crate) => zerocopy_crate,
84
+ let ctx = match Ctx::try_from_derive_input(ast) {
85
+ Ok(ctx) => ctx,
92
86
  Err(e) => return e.into_compile_error().into(),
93
87
  };
94
- $inner(&ast, Trait::$trait, &zerocopy_crate).into_ts().into()
88
+ let ts = $inner(&ctx, Trait::$trait).into_ts();
89
+ // We wrap in `const_block` as a backstop in case any derive fails
90
+ // to wrap its output in `const_block` (and thus fails to annotate)
91
+ // with the full set of `#[allow(...)]` attributes).
92
+ let ts = const_block([Some(ts)]);
93
+ #[cfg(test)]
94
+ crate::util::testutil::check_hygiene(ts.clone());
95
+ ts.into()
95
96
  }
96
97
  };
97
98
  }
98
99
 
99
100
  trait IntoTokenStream {
100
- fn into_ts(self) -> TokenStream;
101
+ fn into_ts(self) -> proc_macro2::TokenStream;
101
102
  }
102
103
 
103
- impl IntoTokenStream for TokenStream {
104
- fn into_ts(self) -> TokenStream {
104
+ impl IntoTokenStream for proc_macro2::TokenStream {
105
+ fn into_ts(self) -> proc_macro2::TokenStream {
105
106
  self
106
107
  }
107
108
  }
108
109
 
109
- impl IntoTokenStream for Result<TokenStream, Error> {
110
- fn into_ts(self) -> TokenStream {
110
+ impl IntoTokenStream for Result<proc_macro2::TokenStream, Error> {
111
+ fn into_ts(self) -> proc_macro2::TokenStream {
111
112
  match self {
112
113
  Ok(ts) => ts,
113
114
  Err(err) => err.to_compile_error(),
@@ -115,52 +116,16 @@ impl IntoTokenStream for Result<TokenStream, Error> {
115
116
  }
116
117
  }
117
118
 
118
- /// Attempt to extract a crate path from the provided attributes. Defaults to
119
- /// `::zerocopy` if not found.
120
- fn extract_zerocopy_crate(attrs: &[Attribute]) -> Result<Path, Error> {
121
- let mut path = parse_quote!(::zerocopy);
122
-
123
- for attr in attrs {
124
- if let Meta::List(ref meta_list) = attr.meta {
125
- if meta_list.path.is_ident("zerocopy") {
126
- attr.parse_nested_meta(|meta| {
127
- if meta.path.is_ident("crate") {
128
- let expr = meta.value().and_then(|value| value.parse());
129
- if let Ok(Expr::Lit(ExprLit { lit: Lit::Str(lit), .. })) = expr {
130
- if let Ok(path_lit) = lit.parse() {
131
- path = path_lit;
132
- return Ok(());
133
- }
134
- }
135
-
136
- return Err(Error::new(
137
- Span::call_site(),
138
- "`crate` attribute requires a path as the value",
139
- ));
140
- }
141
-
142
- Err(Error::new(
143
- Span::call_site(),
144
- format!("unknown attribute encountered: {}", meta.path.into_token_stream()),
145
- ))
146
- })?;
147
- }
148
- }
149
- }
150
-
151
- Ok(path)
152
- }
153
-
154
- derive!(KnownLayout => derive_known_layout => derive_known_layout_inner);
155
- derive!(Immutable => derive_no_cell => derive_no_cell_inner);
156
- derive!(TryFromBytes => derive_try_from_bytes => derive_try_from_bytes_inner);
157
- derive!(FromZeros => derive_from_zeros => derive_from_zeros_inner);
158
- derive!(FromBytes => derive_from_bytes => derive_from_bytes_inner);
159
- derive!(IntoBytes => derive_into_bytes => derive_into_bytes_inner);
160
- derive!(Unaligned => derive_unaligned => derive_unaligned_inner);
161
- derive!(ByteHash => derive_hash => derive_hash_inner);
162
- derive!(ByteEq => derive_eq => derive_eq_inner);
163
- derive!(SplitAt => derive_split_at => derive_split_at_inner);
119
+ derive!(KnownLayout => derive_known_layout => crate::derive::known_layout::derive);
120
+ derive!(Immutable => derive_immutable => crate::derive::derive_immutable);
121
+ derive!(TryFromBytes => derive_try_from_bytes => crate::derive::try_from_bytes::derive_try_from_bytes);
122
+ derive!(FromZeros => derive_from_zeros => crate::derive::from_bytes::derive_from_zeros);
123
+ derive!(FromBytes => derive_from_bytes => crate::derive::from_bytes::derive_from_bytes);
124
+ derive!(IntoBytes => derive_into_bytes => crate::derive::into_bytes::derive_into_bytes);
125
+ derive!(Unaligned => derive_unaligned => crate::derive::unaligned::derive_unaligned);
126
+ derive!(ByteHash => derive_hash => crate::derive::derive_hash);
127
+ derive!(ByteEq => derive_eq => crate::derive::derive_eq);
128
+ derive!(SplitAt => derive_split_at => crate::derive::derive_split_at);
164
129
 
165
130
  /// Deprecated: prefer [`FromZeros`] instead.
166
131
  #[deprecated(since = "0.8.0", note = "`FromZeroes` was renamed to `FromZeros`")]
@@ -177,1830 +142,3 @@ pub fn derive_from_zeroes(ts: proc_macro::TokenStream) -> proc_macro::TokenStrea
177
142
  pub fn derive_as_bytes(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
178
143
  derive_into_bytes(ts)
179
144
  }
180
-
181
- fn derive_known_layout_inner(
182
- ast: &DeriveInput,
183
- _top_level: Trait,
184
- zerocopy_crate: &Path,
185
- ) -> Result<TokenStream, Error> {
186
- let is_repr_c_struct = match &ast.data {
187
- Data::Struct(..) => {
188
- let repr = StructUnionRepr::from_attrs(&ast.attrs)?;
189
- if repr.is_c() {
190
- Some(repr)
191
- } else {
192
- None
193
- }
194
- }
195
- Data::Enum(..) | Data::Union(..) => None,
196
- };
197
-
198
- let fields = ast.data.fields();
199
-
200
- let (self_bounds, inner_extras, outer_extras) = if let (
201
- Some(repr),
202
- Some((trailing_field, leading_fields)),
203
- ) = (is_repr_c_struct, fields.split_last())
204
- {
205
- let (_vis, trailing_field_name, trailing_field_ty) = trailing_field;
206
- let leading_fields_tys = leading_fields.iter().map(|(_vis, _name, ty)| ty);
207
-
208
- let core_path = quote!(#zerocopy_crate::util::macro_util::core_reexport);
209
- let repr_align = repr
210
- .get_align()
211
- .map(|align| {
212
- let align = align.t.get();
213
- quote!(#core_path::num::NonZeroUsize::new(#align as usize))
214
- })
215
- .unwrap_or_else(|| quote!(#core_path::option::Option::None));
216
- let repr_packed = repr
217
- .get_packed()
218
- .map(|packed| {
219
- let packed = packed.get();
220
- quote!(#core_path::num::NonZeroUsize::new(#packed as usize))
221
- })
222
- .unwrap_or_else(|| quote!(#core_path::option::Option::None));
223
-
224
- let make_methods = |trailing_field_ty| {
225
- quote! {
226
- // SAFETY:
227
- // - The returned pointer has the same address and provenance as
228
- // `bytes`:
229
- // - The recursive call to `raw_from_ptr_len` preserves both
230
- // address and provenance.
231
- // - The `as` cast preserves both address and provenance.
232
- // - `NonNull::new_unchecked` preserves both address and
233
- // provenance.
234
- // - If `Self` is a slice DST, the returned pointer encodes
235
- // `elems` elements in the trailing slice:
236
- // - This is true of the recursive call to `raw_from_ptr_len`.
237
- // - `trailing.as_ptr() as *mut Self` preserves trailing slice
238
- // element count [1].
239
- // - `NonNull::new_unchecked` preserves trailing slice element
240
- // count.
241
- //
242
- // [1] Per https://doc.rust-lang.org/reference/expressions/operator-expr.html#pointer-to-pointer-cast:
243
- //
244
- // `*const T`` / `*mut T` can be cast to `*const U` / `*mut U`
245
- // with the following behavior:
246
- // ...
247
- // - If `T` and `U` are both unsized, the pointer is also
248
- // returned unchanged. In particular, the metadata is
249
- // preserved exactly.
250
- //
251
- // For instance, a cast from `*const [T]` to `*const [U]`
252
- // preserves the number of elements. ... The same holds
253
- // for str and any compound type whose unsized tail is a
254
- // slice type, such as struct `Foo(i32, [u8])` or
255
- // `(u64, Foo)`.
256
- #[inline(always)]
257
- fn raw_from_ptr_len(
258
- bytes: #zerocopy_crate::util::macro_util::core_reexport::ptr::NonNull<u8>,
259
- meta: Self::PointerMetadata,
260
- ) -> #zerocopy_crate::util::macro_util::core_reexport::ptr::NonNull<Self> {
261
- use #zerocopy_crate::KnownLayout;
262
- let trailing = <#trailing_field_ty as KnownLayout>::raw_from_ptr_len(bytes, meta);
263
- let slf = trailing.as_ptr() as *mut Self;
264
- // SAFETY: Constructed from `trailing`, which is non-null.
265
- unsafe { #zerocopy_crate::util::macro_util::core_reexport::ptr::NonNull::new_unchecked(slf) }
266
- }
267
-
268
- #[inline(always)]
269
- fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata {
270
- <#trailing_field_ty>::pointer_to_metadata(ptr as *mut _)
271
- }
272
- }
273
- };
274
-
275
- let inner_extras = {
276
- let leading_fields_tys = leading_fields_tys.clone();
277
- let methods = make_methods(*trailing_field_ty);
278
- let (_, ty_generics, _) = ast.generics.split_for_impl();
279
-
280
- quote!(
281
- type PointerMetadata = <#trailing_field_ty as #zerocopy_crate::KnownLayout>::PointerMetadata;
282
-
283
- type MaybeUninit = __ZerocopyKnownLayoutMaybeUninit #ty_generics;
284
-
285
- // SAFETY: `LAYOUT` accurately describes the layout of `Self`.
286
- // The documentation of `DstLayout::for_repr_c_struct` vows that
287
- // invocations in this manner will accurately describe a type,
288
- // so long as:
289
- //
290
- // - that type is `repr(C)`,
291
- // - its fields are enumerated in the order they appear,
292
- // - the presence of `repr_align` and `repr_packed` are
293
- // correctly accounted for.
294
- //
295
- // We respect all three of these preconditions here. This
296
- // expansion is only used if `is_repr_c_struct`, we enumerate
297
- // the fields in order, and we extract the values of `align(N)`
298
- // and `packed(N)`.
299
- const LAYOUT: #zerocopy_crate::DstLayout = {
300
- use #zerocopy_crate::util::macro_util::core_reexport::num::NonZeroUsize;
301
- use #zerocopy_crate::{DstLayout, KnownLayout};
302
-
303
- DstLayout::for_repr_c_struct(
304
- #repr_align,
305
- #repr_packed,
306
- &[
307
- #(DstLayout::for_type::<#leading_fields_tys>(),)*
308
- <#trailing_field_ty as KnownLayout>::LAYOUT
309
- ],
310
- )
311
- };
312
-
313
- #methods
314
- )
315
- };
316
-
317
- let outer_extras = {
318
- let ident = &ast.ident;
319
- let vis = &ast.vis;
320
- let params = &ast.generics.params;
321
- let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
322
-
323
- let predicates = if let Some(where_clause) = where_clause {
324
- where_clause.predicates.clone()
325
- } else {
326
- Default::default()
327
- };
328
-
329
- // Generate a valid ident for a type-level handle to a field of a
330
- // given `name`.
331
- let field_index =
332
- |name: &TokenStream| ident!(("__Zerocopy_Field_{}", name), ident.span());
333
-
334
- let field_indices: Vec<_> =
335
- fields.iter().map(|(_vis, name, _ty)| field_index(name)).collect();
336
-
337
- // Define the collection of type-level field handles.
338
- let field_defs = field_indices.iter().zip(&fields).map(|(idx, (vis, _, _))| {
339
- quote! {
340
- #[allow(non_camel_case_types)]
341
- #vis struct #idx;
342
- }
343
- });
344
-
345
- let field_impls = field_indices.iter().zip(&fields).map(|(idx, (_, _, ty))| quote! {
346
- // SAFETY: `#ty` is the type of `#ident`'s field at `#idx`.
347
- //
348
- // We implement `Field` for each field of the struct to create a
349
- // projection from the field index to its type. This allows us
350
- // to refer to the field's type in a way that respects `Self`
351
- // hygiene. If we just copy-pasted the tokens of `#ty`, we
352
- // would not respect `Self` hygiene, as `Self` would refer to
353
- // the helper struct we are generating, not the derive target
354
- // type.
355
- #[allow(deprecated)]
356
- unsafe impl #impl_generics #zerocopy_crate::util::macro_util::Field<#idx> for #ident #ty_generics
357
- where
358
- #predicates
359
- {
360
- type Type = #ty;
361
- }
362
- });
363
-
364
- let trailing_field_index = field_index(trailing_field_name);
365
- let leading_field_indices =
366
- leading_fields.iter().map(|(_vis, name, _ty)| field_index(name));
367
-
368
- // We use `Field` to project the type of the trailing field. This is
369
- // required to ensure that if the field type uses `Self`, it
370
- // resolves to the derive target type, not the helper struct we are
371
- // generating.
372
- let trailing_field_ty = quote! {
373
- <#ident #ty_generics as
374
- #zerocopy_crate::util::macro_util::Field<#trailing_field_index>
375
- >::Type
376
- };
377
-
378
- let methods = make_methods(&parse_quote! {
379
- <#trailing_field_ty as #zerocopy_crate::KnownLayout>::MaybeUninit
380
- });
381
-
382
- quote! {
383
- #(#field_defs)*
384
-
385
- #(#field_impls)*
386
-
387
- // SAFETY: This has the same layout as the derive target type,
388
- // except that it admits uninit bytes. This is ensured by using
389
- // the same repr as the target type, and by using field types
390
- // which have the same layout as the target type's fields,
391
- // except that they admit uninit bytes. We indirect through
392
- // `Field` to ensure that occurrences of `Self` resolve to
393
- // `#ty`, not `__ZerocopyKnownLayoutMaybeUninit` (see #2116).
394
- #repr
395
- #[doc(hidden)]
396
- // Required on some rustc versions due to a lint that is only
397
- // triggered when `derive(KnownLayout)` is applied to `repr(C)`
398
- // structs that are generated by macros. See #2177 for details.
399
- #[allow(private_bounds)]
400
- #[allow(deprecated)]
401
- #vis struct __ZerocopyKnownLayoutMaybeUninit<#params> (
402
- #(#zerocopy_crate::util::macro_util::core_reexport::mem::MaybeUninit<
403
- <#ident #ty_generics as
404
- #zerocopy_crate::util::macro_util::Field<#leading_field_indices>
405
- >::Type
406
- >,)*
407
- // NOTE(#2302): We wrap in `ManuallyDrop` here in case the
408
- // type we're operating on is both generic and
409
- // `repr(packed)`. In that case, Rust needs to know that the
410
- // type is *either* `Sized` or has a trivial `Drop`.
411
- // `ManuallyDrop` has a trivial `Drop`, and so satisfies
412
- // this requirement.
413
- #zerocopy_crate::util::macro_util::core_reexport::mem::ManuallyDrop<
414
- <#trailing_field_ty as #zerocopy_crate::KnownLayout>::MaybeUninit
415
- >
416
- )
417
- where
418
- #trailing_field_ty: #zerocopy_crate::KnownLayout,
419
- #predicates;
420
-
421
- // SAFETY: We largely defer to the `KnownLayout` implementation
422
- // on the derive target type (both by using the same tokens, and
423
- // by deferring to impl via type-level indirection). This is
424
- // sound, since `__ZerocopyKnownLayoutMaybeUninit` is guaranteed
425
- // to have the same layout as the derive target type, except
426
- // that `__ZerocopyKnownLayoutMaybeUninit` admits uninit bytes.
427
- #[allow(deprecated)]
428
- unsafe impl #impl_generics #zerocopy_crate::KnownLayout for __ZerocopyKnownLayoutMaybeUninit #ty_generics
429
- where
430
- #trailing_field_ty: #zerocopy_crate::KnownLayout,
431
- #predicates
432
- {
433
- #[allow(clippy::missing_inline_in_public_items)]
434
- fn only_derive_is_allowed_to_implement_this_trait() {}
435
-
436
- type PointerMetadata = <#ident #ty_generics as #zerocopy_crate::KnownLayout>::PointerMetadata;
437
-
438
- type MaybeUninit = Self;
439
-
440
- const LAYOUT: #zerocopy_crate::DstLayout = <#ident #ty_generics as #zerocopy_crate::KnownLayout>::LAYOUT;
441
-
442
- #methods
443
- }
444
- }
445
- };
446
-
447
- (SelfBounds::None, inner_extras, Some(outer_extras))
448
- } else {
449
- // For enums, unions, and non-`repr(C)` structs, we require that
450
- // `Self` is sized, and as a result don't need to reason about the
451
- // internals of the type.
452
- (
453
- SelfBounds::SIZED,
454
- quote!(
455
- type PointerMetadata = ();
456
- type MaybeUninit =
457
- #zerocopy_crate::util::macro_util::core_reexport::mem::MaybeUninit<Self>;
458
-
459
- // SAFETY: `LAYOUT` is guaranteed to accurately describe the
460
- // layout of `Self`, because that is the documented safety
461
- // contract of `DstLayout::for_type`.
462
- const LAYOUT: #zerocopy_crate::DstLayout = #zerocopy_crate::DstLayout::for_type::<Self>();
463
-
464
- // SAFETY: `.cast` preserves address and provenance.
465
- //
466
- // FIXME(#429): Add documentation to `.cast` that promises that
467
- // it preserves provenance.
468
- #[inline(always)]
469
- fn raw_from_ptr_len(
470
- bytes: #zerocopy_crate::util::macro_util::core_reexport::ptr::NonNull<u8>,
471
- _meta: (),
472
- ) -> #zerocopy_crate::util::macro_util::core_reexport::ptr::NonNull<Self>
473
- {
474
- bytes.cast::<Self>()
475
- }
476
-
477
- #[inline(always)]
478
- fn pointer_to_metadata(_ptr: *mut Self) -> () {}
479
- ),
480
- None,
481
- )
482
- };
483
-
484
- Ok(match &ast.data {
485
- Data::Struct(strct) => {
486
- let require_trait_bound_on_field_types =
487
- if matches!(self_bounds, SelfBounds::All(&[Trait::Sized])) {
488
- FieldBounds::None
489
- } else {
490
- FieldBounds::TRAILING_SELF
491
- };
492
-
493
- // A bound on the trailing field is required, since structs are
494
- // unsized if their trailing field is unsized. Reflecting the layout
495
- // of an usized trailing field requires that the field is
496
- // `KnownLayout`.
497
- ImplBlockBuilder::new(
498
- ast,
499
- strct,
500
- Trait::KnownLayout,
501
- require_trait_bound_on_field_types,
502
- zerocopy_crate,
503
- )
504
- .self_type_trait_bounds(self_bounds)
505
- .inner_extras(inner_extras)
506
- .outer_extras(outer_extras)
507
- .build()
508
- }
509
- Data::Enum(enm) => {
510
- // A bound on the trailing field is not required, since enums cannot
511
- // currently be unsized.
512
- ImplBlockBuilder::new(ast, enm, Trait::KnownLayout, FieldBounds::None, zerocopy_crate)
513
- .self_type_trait_bounds(SelfBounds::SIZED)
514
- .inner_extras(inner_extras)
515
- .outer_extras(outer_extras)
516
- .build()
517
- }
518
- Data::Union(unn) => {
519
- // A bound on the trailing field is not required, since unions
520
- // cannot currently be unsized.
521
- ImplBlockBuilder::new(ast, unn, Trait::KnownLayout, FieldBounds::None, zerocopy_crate)
522
- .self_type_trait_bounds(SelfBounds::SIZED)
523
- .inner_extras(inner_extras)
524
- .outer_extras(outer_extras)
525
- .build()
526
- }
527
- })
528
- }
529
-
530
- fn derive_no_cell_inner(
531
- ast: &DeriveInput,
532
- _top_level: Trait,
533
- zerocopy_crate: &Path,
534
- ) -> TokenStream {
535
- match &ast.data {
536
- Data::Struct(strct) => ImplBlockBuilder::new(
537
- ast,
538
- strct,
539
- Trait::Immutable,
540
- FieldBounds::ALL_SELF,
541
- zerocopy_crate,
542
- )
543
- .build(),
544
- Data::Enum(enm) => {
545
- ImplBlockBuilder::new(ast, enm, Trait::Immutable, FieldBounds::ALL_SELF, zerocopy_crate)
546
- .build()
547
- }
548
- Data::Union(unn) => {
549
- ImplBlockBuilder::new(ast, unn, Trait::Immutable, FieldBounds::ALL_SELF, zerocopy_crate)
550
- .build()
551
- }
552
- }
553
- }
554
-
555
- fn derive_try_from_bytes_inner(
556
- ast: &DeriveInput,
557
- top_level: Trait,
558
- zerocopy_crate: &Path,
559
- ) -> Result<TokenStream, Error> {
560
- match &ast.data {
561
- Data::Struct(strct) => derive_try_from_bytes_struct(ast, strct, top_level, zerocopy_crate),
562
- Data::Enum(enm) => derive_try_from_bytes_enum(ast, enm, top_level, zerocopy_crate),
563
- Data::Union(unn) => Ok(derive_try_from_bytes_union(ast, unn, top_level, zerocopy_crate)),
564
- }
565
- }
566
-
567
- fn derive_from_zeros_inner(
568
- ast: &DeriveInput,
569
- top_level: Trait,
570
- zerocopy_crate: &Path,
571
- ) -> Result<TokenStream, Error> {
572
- let try_from_bytes = derive_try_from_bytes_inner(ast, top_level, zerocopy_crate)?;
573
- let from_zeros = match &ast.data {
574
- Data::Struct(strct) => derive_from_zeros_struct(ast, strct, zerocopy_crate),
575
- Data::Enum(enm) => derive_from_zeros_enum(ast, enm, zerocopy_crate)?,
576
- Data::Union(unn) => derive_from_zeros_union(ast, unn, zerocopy_crate),
577
- };
578
- Ok(IntoIterator::into_iter([try_from_bytes, from_zeros]).collect())
579
- }
580
-
581
- fn derive_from_bytes_inner(
582
- ast: &DeriveInput,
583
- top_level: Trait,
584
- zerocopy_crate: &Path,
585
- ) -> Result<TokenStream, Error> {
586
- let from_zeros = derive_from_zeros_inner(ast, top_level, zerocopy_crate)?;
587
- let from_bytes = match &ast.data {
588
- Data::Struct(strct) => derive_from_bytes_struct(ast, strct, zerocopy_crate),
589
- Data::Enum(enm) => derive_from_bytes_enum(ast, enm, zerocopy_crate)?,
590
- Data::Union(unn) => derive_from_bytes_union(ast, unn, zerocopy_crate),
591
- };
592
-
593
- Ok(IntoIterator::into_iter([from_zeros, from_bytes]).collect())
594
- }
595
-
596
- fn derive_into_bytes_inner(
597
- ast: &DeriveInput,
598
- _top_level: Trait,
599
- zerocopy_crate: &Path,
600
- ) -> Result<TokenStream, Error> {
601
- match &ast.data {
602
- Data::Struct(strct) => derive_into_bytes_struct(ast, strct, zerocopy_crate),
603
- Data::Enum(enm) => derive_into_bytes_enum(ast, enm, zerocopy_crate),
604
- Data::Union(unn) => derive_into_bytes_union(ast, unn, zerocopy_crate),
605
- }
606
- }
607
-
608
- fn derive_unaligned_inner(
609
- ast: &DeriveInput,
610
- _top_level: Trait,
611
- zerocopy_crate: &Path,
612
- ) -> Result<TokenStream, Error> {
613
- match &ast.data {
614
- Data::Struct(strct) => derive_unaligned_struct(ast, strct, zerocopy_crate),
615
- Data::Enum(enm) => derive_unaligned_enum(ast, enm, zerocopy_crate),
616
- Data::Union(unn) => derive_unaligned_union(ast, unn, zerocopy_crate),
617
- }
618
- }
619
-
620
- fn derive_hash_inner(
621
- ast: &DeriveInput,
622
- _top_level: Trait,
623
- zerocopy_crate: &Path,
624
- ) -> Result<TokenStream, Error> {
625
- // This doesn't delegate to `impl_block` because `impl_block` assumes it is
626
- // deriving a `zerocopy`-defined trait, and these trait impls share a common
627
- // shape that `Hash` does not. In particular, `zerocopy` traits contain a
628
- // method that only `zerocopy_derive` macros are supposed to implement, and
629
- // `impl_block` generating this trait method is incompatible with `Hash`.
630
- let type_ident = &ast.ident;
631
- let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
632
- let where_predicates = where_clause.map(|clause| &clause.predicates);
633
- Ok(quote! {
634
- #[allow(deprecated)]
635
- // While there are not currently any warnings that this suppresses (that
636
- // we're aware of), it's good future-proofing hygiene.
637
- #[automatically_derived]
638
- impl #impl_generics #zerocopy_crate::util::macro_util::core_reexport::hash::Hash for #type_ident #ty_generics
639
- where
640
- Self: #zerocopy_crate::IntoBytes + #zerocopy_crate::Immutable,
641
- #where_predicates
642
- {
643
- fn hash<H>(&self, state: &mut H)
644
- where
645
- H: #zerocopy_crate::util::macro_util::core_reexport::hash::Hasher,
646
- {
647
- #zerocopy_crate::util::macro_util::core_reexport::hash::Hasher::write(
648
- state,
649
- #zerocopy_crate::IntoBytes::as_bytes(self)
650
- )
651
- }
652
-
653
- fn hash_slice<H>(data: &[Self], state: &mut H)
654
- where
655
- H: #zerocopy_crate::util::macro_util::core_reexport::hash::Hasher,
656
- {
657
- #zerocopy_crate::util::macro_util::core_reexport::hash::Hasher::write(
658
- state,
659
- #zerocopy_crate::IntoBytes::as_bytes(data)
660
- )
661
- }
662
- }
663
- })
664
- }
665
-
666
- fn derive_eq_inner(
667
- ast: &DeriveInput,
668
- _top_level: Trait,
669
- zerocopy_crate: &Path,
670
- ) -> Result<TokenStream, Error> {
671
- // This doesn't delegate to `impl_block` because `impl_block` assumes it is
672
- // deriving a `zerocopy`-defined trait, and these trait impls share a common
673
- // shape that `Eq` does not. In particular, `zerocopy` traits contain a
674
- // method that only `zerocopy_derive` macros are supposed to implement, and
675
- // `impl_block` generating this trait method is incompatible with `Eq`.
676
- let type_ident = &ast.ident;
677
- let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
678
- let where_predicates = where_clause.map(|clause| &clause.predicates);
679
- Ok(quote! {
680
- // FIXME(#553): Add a test that generates a warning when
681
- // `#[allow(deprecated)]` isn't present.
682
- #[allow(deprecated)]
683
- // While there are not currently any warnings that this suppresses (that
684
- // we're aware of), it's good future-proofing hygiene.
685
- #[automatically_derived]
686
- impl #impl_generics #zerocopy_crate::util::macro_util::core_reexport::cmp::PartialEq for #type_ident #ty_generics
687
- where
688
- Self: #zerocopy_crate::IntoBytes + #zerocopy_crate::Immutable,
689
- #where_predicates
690
- {
691
- fn eq(&self, other: &Self) -> bool {
692
- #zerocopy_crate::util::macro_util::core_reexport::cmp::PartialEq::eq(
693
- #zerocopy_crate::IntoBytes::as_bytes(self),
694
- #zerocopy_crate::IntoBytes::as_bytes(other),
695
- )
696
- }
697
- }
698
-
699
- // FIXME(#553): Add a test that generates a warning when
700
- // `#[allow(deprecated)]` isn't present.
701
- #[allow(deprecated)]
702
- // While there are not currently any warnings that this suppresses (that
703
- // we're aware of), it's good future-proofing hygiene.
704
- #[automatically_derived]
705
- impl #impl_generics #zerocopy_crate::util::macro_util::core_reexport::cmp::Eq for #type_ident #ty_generics
706
- where
707
- Self: #zerocopy_crate::IntoBytes + #zerocopy_crate::Immutable,
708
- #where_predicates
709
- {
710
- }
711
- })
712
- }
713
-
714
- fn derive_split_at_inner(
715
- ast: &DeriveInput,
716
- _top_level: Trait,
717
- zerocopy_crate: &Path,
718
- ) -> Result<TokenStream, Error> {
719
- let repr = StructUnionRepr::from_attrs(&ast.attrs)?;
720
-
721
- match &ast.data {
722
- Data::Struct(_) => {}
723
- Data::Enum(_) | Data::Union(_) => {
724
- return Err(Error::new(Span::call_site(), "can only be applied to structs"));
725
- }
726
- };
727
-
728
- if repr.get_packed().is_some() {
729
- return Err(Error::new(Span::call_site(), "must not have #[repr(packed)] attribute"));
730
- }
731
-
732
- if !(repr.is_c() || repr.is_transparent()) {
733
- return Err(Error::new(Span::call_site(), "must have #[repr(C)] or #[repr(transparent)] in order to guarantee this type's layout is splitable"));
734
- }
735
-
736
- let fields = ast.data.fields();
737
- let trailing_field = if let Some(((_, _, trailing_field), _)) = fields.split_last() {
738
- trailing_field
739
- } else {
740
- return Err(Error::new(Span::call_site(), "must at least one field"));
741
- };
742
-
743
- // SAFETY: `#ty`, per the above checks, is `repr(C)` or `repr(transparent)`
744
- // and is not packed; its trailing field is guaranteed to be well-aligned
745
- // for its type. By invariant on `FieldBounds::TRAILING_SELF`, the trailing
746
- // slice of the trailing field is also well-aligned for its type.
747
- Ok(ImplBlockBuilder::new(
748
- ast,
749
- &ast.data,
750
- Trait::SplitAt,
751
- FieldBounds::TRAILING_SELF,
752
- zerocopy_crate,
753
- )
754
- .inner_extras(quote! {
755
- type Elem = <#trailing_field as ::zerocopy::SplitAt>::Elem;
756
- })
757
- .build())
758
- }
759
-
760
- fn derive_has_field_struct_union(
761
- ast: &DeriveInput,
762
- data: &dyn DataExt,
763
- zerocopy_crate: &Path,
764
- ) -> TokenStream {
765
- let fields = ast.data.fields();
766
- if fields.is_empty() {
767
- return quote! {};
768
- }
769
-
770
- let field_tokens = fields.iter().map(|(vis, ident, _)| {
771
- let ident = ident!(("ẕ{}", ident), ident.span());
772
- quote!(
773
- #vis enum #ident {}
774
- )
775
- });
776
-
777
- let variant_id: Box<Expr> = match &ast.data {
778
- Data::Struct(_) => parse_quote!({ #zerocopy_crate::STRUCT_VARIANT_ID }),
779
- Data::Union(_) => parse_quote!({ #zerocopy_crate::UNION_VARIANT_ID }),
780
- _ => unreachable!(),
781
- };
782
-
783
- let is_repr_c_union = match &ast.data {
784
- Data::Union(..) => {
785
- StructUnionRepr::from_attrs(&ast.attrs).map(|repr| repr.is_c()).unwrap_or(false)
786
- }
787
- Data::Enum(..) | Data::Struct(..) => false,
788
- };
789
- let has_fields = fields.iter().map(move |(_, ident, ty)| {
790
- let field_token = ident!(("ẕ{}", ident), ident.span());
791
- let field: Box<Type> = parse_quote!(#field_token);
792
- let field_id: Box<Expr> = parse_quote!({ #zerocopy_crate::ident_id!(#ident) });
793
- ImplBlockBuilder::new(
794
- ast,
795
- data,
796
- Trait::HasField {
797
- variant_id: variant_id.clone(),
798
- field: field.clone(),
799
- field_id: field_id.clone(),
800
- },
801
- FieldBounds::None,
802
- zerocopy_crate,
803
- )
804
- .inner_extras(quote! {
805
- type Type = #ty;
806
-
807
- #[inline(always)]
808
- fn project(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut Self::Type {
809
- let slf = slf.as_ptr();
810
- // SAFETY: By invariant on `PtrInner`, `slf` is a non-null
811
- // pointer whose referent is zero-sized or lives in a valid
812
- // allocation. Since `#ident` is a struct or union field of
813
- // `Self`, this projection preserves or shrinks the referent
814
- // size, and so the resulting referent also fits in the same
815
- // allocation.
816
- unsafe { #zerocopy_crate::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).#ident) }
817
- }
818
- }).outer_extras(if is_repr_c_union {
819
- let ident = &ast.ident;
820
- let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
821
- quote! {
822
- // SAFETY: All `repr(C)` union fields exist at offset 0 within
823
- // the union [1], and so any union projection is actually a cast
824
- // (ie, preserves address).
825
- //
826
- // [1] Per
827
- // https://doc.rust-lang.org/1.92.0/reference/type-layout.html#reprc-unions,
828
- // it's not *technically* guaranteed that non-maximally-
829
- // sized fields are at offset 0, but it's clear that this is
830
- // the intention of `repr(C)` unions. It says:
831
- //
832
- // > A union declared with `#[repr(C)]` will have the same
833
- // > size and alignment as an equivalent C union declaration
834
- // > in the C language for the target platform.
835
- //
836
- // Note that this only mentions size and alignment, not layout.
837
- // However, C unions *do* guarantee that all fields start at
838
- // offset 0. [2]
839
- //
840
- // This is also reinforced by
841
- // https://doc.rust-lang.org/1.92.0/reference/items/unions.html#r-items.union.fields.offset:
842
- //
843
- // > Fields might have a non-zero offset (except when the C
844
- // > representation is used); in that case the bits starting
845
- // > at the offset of the fields are read
846
- //
847
- // [2] Per https://port70.net/~nsz/c/c11/n1570.html#6.7.2.1p16:
848
- //
849
- // > The size of a union is sufficient to contain the
850
- // > largest of its members. The value of at most one of the
851
- // > members can be stored in a union object at any time. A
852
- // > pointer to a union object, suitably converted, points
853
- // > to each of its members (or if a member is a bit- field,
854
- // > then to the unit in which it resides), and vice versa.
855
- //
856
- // FIXME(https://github.com/rust-lang/unsafe-code-guidelines/issues/595):
857
- // Cite the documentation once it's updated.
858
- unsafe impl #impl_generics #zerocopy_crate::pointer::cast::Cast<#ident #ty_generics, #ty>
859
- for #zerocopy_crate::pointer::cast::Projection<#field, { #zerocopy_crate::UNION_VARIANT_ID }, #field_id>
860
- #where_clause
861
- {
862
- }
863
- }
864
- } else {
865
- quote! {}
866
- })
867
- .build()
868
- });
869
-
870
- quote! {
871
- #[allow(non_camel_case_types)]
872
- const _: () = {
873
- #(#field_tokens)*
874
- #(#has_fields)*
875
- };
876
- }
877
- }
878
-
879
- /// A struct is `TryFromBytes` if:
880
- /// - all fields are `TryFromBytes`
881
- fn derive_try_from_bytes_struct(
882
- ast: &DeriveInput,
883
- strct: &DataStruct,
884
- top_level: Trait,
885
- zerocopy_crate: &Path,
886
- ) -> Result<TokenStream, Error> {
887
- let extras =
888
- try_gen_trivial_is_bit_valid(ast, top_level, zerocopy_crate).unwrap_or_else(|| {
889
- let fields = strct.fields();
890
- let field_names = fields.iter().map(|(_vis, name, _ty)| name);
891
- let field_tys = fields.iter().map(|(_vis, _name, ty)| ty);
892
- quote!(
893
- // SAFETY: We use `is_bit_valid` to validate that each field is
894
- // bit-valid, and only return `true` if all of them are. The bit
895
- // validity of a struct is just the composition of the bit
896
- // validities of its fields, so this is a sound implementation
897
- // of `is_bit_valid`.
898
- fn is_bit_valid<___ZerocopyAliasing>(
899
- mut candidate: #zerocopy_crate::Maybe<Self, ___ZerocopyAliasing>,
900
- ) -> #zerocopy_crate::util::macro_util::core_reexport::primitive::bool
901
- where
902
- ___ZerocopyAliasing: #zerocopy_crate::pointer::invariant::Reference,
903
- {
904
- use #zerocopy_crate::util::macro_util::core_reexport;
905
- use #zerocopy_crate::pointer::PtrInner;
906
-
907
- true #(&& {
908
- let field_candidate = candidate.reborrow().project::<
909
- _,
910
- { #zerocopy_crate::ident_id!(#field_names) }
911
- >();
912
-
913
- <#field_tys as #zerocopy_crate::TryFromBytes>::is_bit_valid(field_candidate)
914
- })*
915
- }
916
- )
917
- });
918
- Ok(ImplBlockBuilder::new(
919
- ast,
920
- strct,
921
- Trait::TryFromBytes,
922
- FieldBounds::ALL_SELF,
923
- zerocopy_crate,
924
- )
925
- .inner_extras(extras)
926
- .outer_extras(derive_has_field_struct_union(ast, strct, zerocopy_crate))
927
- .build())
928
- }
929
-
930
- /// A union is `TryFromBytes` if:
931
- /// - all of its fields are `TryFromBytes` and `Immutable`
932
- fn derive_try_from_bytes_union(
933
- ast: &DeriveInput,
934
- unn: &DataUnion,
935
- top_level: Trait,
936
- zerocopy_crate: &Path,
937
- ) -> TokenStream {
938
- // FIXME(#5): Remove the `Immutable` bound.
939
- let field_type_trait_bounds =
940
- FieldBounds::All(&[TraitBound::Slf, TraitBound::Other(Trait::Immutable)]);
941
- let extras =
942
- try_gen_trivial_is_bit_valid(ast, top_level, zerocopy_crate).unwrap_or_else(|| {
943
- let fields = unn.fields();
944
- let field_names = fields.iter().map(|(_vis, name, _ty)| name);
945
- let field_tys = fields.iter().map(|(_vis, _name, ty)| ty);
946
- quote!(
947
- // SAFETY: We use `is_bit_valid` to validate that any field is
948
- // bit-valid; we only return `true` if at least one of them is.
949
- // The bit validity of a union is not yet well defined in Rust,
950
- // but it is guaranteed to be no more strict than this
951
- // definition. See #696 for a more in-depth discussion.
952
- fn is_bit_valid<___ZerocopyAliasing>(
953
- mut candidate: #zerocopy_crate::Maybe<'_, Self,___ZerocopyAliasing>
954
- ) -> #zerocopy_crate::util::macro_util::core_reexport::primitive::bool
955
- where
956
- ___ZerocopyAliasing: #zerocopy_crate::pointer::invariant::Reference,
957
- {
958
- use #zerocopy_crate::util::macro_util::core_reexport;
959
- use #zerocopy_crate::pointer::PtrInner;
960
-
961
- false #(|| {
962
- // SAFETY:
963
- // - Since `Self: Immutable` is enforced by
964
- // `self_type_trait_bounds`, neither `*slf` nor the
965
- // returned pointer's referent contain any
966
- // `UnsafeCell`s
967
- // - Both source and destination validity are
968
- // `Initialized`, which is always a sound
969
- // transmutation.
970
- let field_candidate = unsafe {
971
- candidate.reborrow().project_transmute_unchecked::<
972
- _,
973
- _,
974
- #zerocopy_crate::pointer::cast::Projection<_, { #zerocopy_crate::UNION_VARIANT_ID }, { #zerocopy_crate::ident_id!(#field_names) }>
975
- >()
976
- };
977
-
978
- <#field_tys as #zerocopy_crate::TryFromBytes>::is_bit_valid(field_candidate)
979
- })*
980
- }
981
- )
982
- });
983
- ImplBlockBuilder::new(ast, unn, Trait::TryFromBytes, field_type_trait_bounds, zerocopy_crate)
984
- .inner_extras(extras)
985
- .outer_extras(derive_has_field_struct_union(ast, unn, zerocopy_crate))
986
- .build()
987
- }
988
-
989
- fn derive_try_from_bytes_enum(
990
- ast: &DeriveInput,
991
- enm: &DataEnum,
992
- top_level: Trait,
993
- zerocopy_crate: &Path,
994
- ) -> Result<TokenStream, Error> {
995
- let repr = EnumRepr::from_attrs(&ast.attrs)?;
996
-
997
- // If an enum has no fields, it has a well-defined integer representation,
998
- // and every possible bit pattern corresponds to a valid discriminant tag,
999
- // then it *could* be `FromBytes` (even if the user hasn't derived
1000
- // `FromBytes`). This holds if, for `repr(uN)` or `repr(iN)`, there are 2^N
1001
- // variants.
1002
- let could_be_from_bytes = enum_size_from_repr(&repr)
1003
- .map(|size| enm.fields().is_empty() && enm.variants.len() == 1usize << size)
1004
- .unwrap_or(false);
1005
-
1006
- let trivial_is_bit_valid = try_gen_trivial_is_bit_valid(ast, top_level, zerocopy_crate);
1007
- let extra = match (trivial_is_bit_valid, could_be_from_bytes) {
1008
- (Some(is_bit_valid), _) => is_bit_valid,
1009
- // SAFETY: It would be sound for the enum to implement `FromBytes`, as
1010
- // required by `gen_trivial_is_bit_valid_unchecked`.
1011
- (None, true) => unsafe { gen_trivial_is_bit_valid_unchecked(zerocopy_crate) },
1012
- (None, false) => {
1013
- r#enum::derive_is_bit_valid(ast, &ast.ident, &repr, &ast.generics, enm, zerocopy_crate)?
1014
- }
1015
- };
1016
-
1017
- Ok(ImplBlockBuilder::new(ast, enm, Trait::TryFromBytes, FieldBounds::ALL_SELF, zerocopy_crate)
1018
- .inner_extras(extra)
1019
- .build())
1020
- }
1021
-
1022
- /// Attempts to generate a `TryFromBytes::is_bit_valid` instance that
1023
- /// unconditionally returns true.
1024
- ///
1025
- /// This is possible when the `top_level` trait is `FromBytes` and there are no
1026
- /// generic type parameters. In this case, we know that compilation will succeed
1027
- /// only if the type is unconditionally `FromBytes`. Type parameters are not
1028
- /// supported because a type with type parameters could be `TryFromBytes` but
1029
- /// not `FromBytes` depending on its type parameters, and so deriving a trivial
1030
- /// `is_bit_valid` would be either unsound or, assuming we add a defensive
1031
- /// `Self: FromBytes` bound (as we currently do), overly restrictive. Consider,
1032
- /// for example, that `Foo<bool>` ought to be `TryFromBytes` but not `FromBytes`
1033
- /// in this example:
1034
- ///
1035
- /// ```rust,ignore
1036
- /// #[derive(FromBytes)]
1037
- /// #[repr(transparent)]
1038
- /// struct Foo<T>(T);
1039
- /// ```
1040
- ///
1041
- /// This should be used where possible. Using this impl is faster to codegen,
1042
- /// faster to compile, and is friendlier on the optimizer.
1043
- fn try_gen_trivial_is_bit_valid(
1044
- ast: &DeriveInput,
1045
- top_level: Trait,
1046
- zerocopy_crate: &Path,
1047
- ) -> Option<proc_macro2::TokenStream> {
1048
- // If the top-level trait is `FromBytes` and `Self` has no type parameters,
1049
- // then the `FromBytes` derive will fail compilation if `Self` is not
1050
- // actually soundly `FromBytes`, and so we can rely on that for our
1051
- // `is_bit_valid` impl. It's plausible that we could make changes - or Rust
1052
- // could make changes (such as the "trivial bounds" language feature) - that
1053
- // make this no longer true. To hedge against these, we include an explicit
1054
- // `Self: FromBytes` check in the generated `is_bit_valid`, which is
1055
- // bulletproof.
1056
- if matches!(top_level, Trait::FromBytes) && ast.generics.params.is_empty() {
1057
- Some(quote!(
1058
- // SAFETY: See inline.
1059
- fn is_bit_valid<___ZerocopyAliasing>(
1060
- _candidate: #zerocopy_crate::Maybe<Self, ___ZerocopyAliasing>,
1061
- ) -> #zerocopy_crate::util::macro_util::core_reexport::primitive::bool
1062
- where
1063
- ___ZerocopyAliasing: #zerocopy_crate::pointer::invariant::Reference,
1064
- {
1065
- if false {
1066
- fn assert_is_from_bytes<T>()
1067
- where
1068
- T: #zerocopy_crate::FromBytes,
1069
- T: ?#zerocopy_crate::util::macro_util::core_reexport::marker::Sized,
1070
- {
1071
- }
1072
-
1073
- assert_is_from_bytes::<Self>();
1074
- }
1075
-
1076
- // SAFETY: The preceding code only compiles if `Self:
1077
- // FromBytes`. Thus, this code only compiles if all initialized
1078
- // byte sequences represent valid instances of `Self`.
1079
- true
1080
- }
1081
- ))
1082
- } else {
1083
- None
1084
- }
1085
- }
1086
-
1087
- /// Generates a `TryFromBytes::is_bit_valid` instance that unconditionally
1088
- /// returns true.
1089
- ///
1090
- /// This should be used where possible, (although `try_gen_trivial_is_bit_valid`
1091
- /// should be preferred over this for safety reasons). Using this impl is faster
1092
- /// to codegen, faster to compile, and is friendlier on the optimizer.
1093
- ///
1094
- /// # Safety
1095
- ///
1096
- /// The caller must ensure that all initialized bit patterns are valid for
1097
- /// `Self`.
1098
- unsafe fn gen_trivial_is_bit_valid_unchecked(zerocopy_crate: &Path) -> proc_macro2::TokenStream {
1099
- quote!(
1100
- // SAFETY: The caller of `gen_trivial_is_bit_valid_unchecked` has
1101
- // promised that all initialized bit patterns are valid for `Self`.
1102
- fn is_bit_valid<___ZerocopyAliasing>(
1103
- _candidate: #zerocopy_crate::Maybe<Self, ___ZerocopyAliasing>,
1104
- ) -> #zerocopy_crate::util::macro_util::core_reexport::primitive::bool
1105
- where
1106
- ___ZerocopyAliasing: #zerocopy_crate::pointer::invariant::Reference,
1107
- {
1108
- true
1109
- }
1110
- )
1111
- }
1112
-
1113
- /// A struct is `FromZeros` if:
1114
- /// - all fields are `FromZeros`
1115
- fn derive_from_zeros_struct(
1116
- ast: &DeriveInput,
1117
- strct: &DataStruct,
1118
- zerocopy_crate: &Path,
1119
- ) -> TokenStream {
1120
- ImplBlockBuilder::new(ast, strct, Trait::FromZeros, FieldBounds::ALL_SELF, zerocopy_crate)
1121
- .build()
1122
- }
1123
-
1124
- /// Returns `Ok(index)` if variant `index` of the enum has a discriminant of
1125
- /// zero. If `Err(bool)` is returned, the boolean is true if the enum has
1126
- /// unknown discriminants (e.g. discriminants set to const expressions which we
1127
- /// can't evaluate in a proc macro). If the enum has unknown discriminants, then
1128
- /// it might have a zero variant that we just can't detect.
1129
- fn find_zero_variant(enm: &DataEnum) -> Result<usize, bool> {
1130
- // Discriminants can be anywhere in the range [i128::MIN, u128::MAX] because
1131
- // the discriminant type may be signed or unsigned. Since we only care about
1132
- // tracking the discriminant when it's less than or equal to zero, we can
1133
- // avoid u128 -> i128 conversions and bounds checking by making the "next
1134
- // discriminant" value implicitly negative.
1135
- // Technically 64 bits is enough, but 128 is better for future compatibility
1136
- // with https://github.com/rust-lang/rust/issues/56071
1137
- let mut next_negative_discriminant = Some(0);
1138
-
1139
- // Sometimes we encounter explicit discriminants that we can't know the
1140
- // value of (e.g. a constant expression that requires evaluation). These
1141
- // could evaluate to zero or a negative number, but we can't assume that
1142
- // they do (no false positives allowed!). So we treat them like strictly-
1143
- // positive values that can't result in any zero variants, and track whether
1144
- // we've encountered any unknown discriminants.
1145
- let mut has_unknown_discriminants = false;
1146
-
1147
- for (i, v) in enm.variants.iter().enumerate() {
1148
- match v.discriminant.as_ref() {
1149
- // Implicit discriminant
1150
- None => {
1151
- match next_negative_discriminant.as_mut() {
1152
- Some(0) => return Ok(i),
1153
- // n is nonzero so subtraction is always safe
1154
- Some(n) => *n -= 1,
1155
- None => (),
1156
- }
1157
- }
1158
- // Explicit positive discriminant
1159
- Some((_, Expr::Lit(ExprLit { lit: Lit::Int(int), .. }))) => {
1160
- match int.base10_parse::<u128>().ok() {
1161
- Some(0) => return Ok(i),
1162
- Some(_) => next_negative_discriminant = None,
1163
- None => {
1164
- // Numbers should never fail to parse, but just in case:
1165
- has_unknown_discriminants = true;
1166
- next_negative_discriminant = None;
1167
- }
1168
- }
1169
- }
1170
- // Explicit negative discriminant
1171
- Some((_, Expr::Unary(ExprUnary { op: UnOp::Neg(_), expr, .. }))) => match &**expr {
1172
- Expr::Lit(ExprLit { lit: Lit::Int(int), .. }) => {
1173
- match int.base10_parse::<u128>().ok() {
1174
- Some(0) => return Ok(i),
1175
- // x is nonzero so subtraction is always safe
1176
- Some(x) => next_negative_discriminant = Some(x - 1),
1177
- None => {
1178
- // Numbers should never fail to parse, but just in
1179
- // case:
1180
- has_unknown_discriminants = true;
1181
- next_negative_discriminant = None;
1182
- }
1183
- }
1184
- }
1185
- // Unknown negative discriminant (e.g. const repr)
1186
- _ => {
1187
- has_unknown_discriminants = true;
1188
- next_negative_discriminant = None;
1189
- }
1190
- },
1191
- // Unknown discriminant (e.g. const expr)
1192
- _ => {
1193
- has_unknown_discriminants = true;
1194
- next_negative_discriminant = None;
1195
- }
1196
- }
1197
- }
1198
-
1199
- Err(has_unknown_discriminants)
1200
- }
1201
-
1202
- /// An enum is `FromZeros` if:
1203
- /// - one of the variants has a discriminant of `0`
1204
- /// - that variant's fields are all `FromZeros`
1205
- fn derive_from_zeros_enum(
1206
- ast: &DeriveInput,
1207
- enm: &DataEnum,
1208
- zerocopy_crate: &Path,
1209
- ) -> Result<TokenStream, Error> {
1210
- let repr = EnumRepr::from_attrs(&ast.attrs)?;
1211
-
1212
- // We don't actually care what the repr is; we just care that it's one of
1213
- // the allowed ones.
1214
- match repr {
1215
- Repr::Compound(
1216
- Spanned { t: CompoundRepr::C | CompoundRepr::Primitive(_), span: _ },
1217
- _,
1218
- ) => {}
1219
- Repr::Transparent(_)
1220
- | Repr::Compound(Spanned { t: CompoundRepr::Rust, span: _ }, _) => return Err(Error::new(Span::call_site(), "must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout")),
1221
- }
1222
-
1223
- let zero_variant = match find_zero_variant(enm) {
1224
- Ok(index) => enm.variants.iter().nth(index).unwrap(),
1225
- // Has unknown variants
1226
- Err(true) => {
1227
- return Err(Error::new_spanned(
1228
- ast,
1229
- "FromZeros only supported on enums with a variant that has a discriminant of `0`\n\
1230
- help: This enum has discriminants which are not literal integers. One of those may \
1231
- define or imply which variant has a discriminant of zero. Use a literal integer to \
1232
- define or imply the variant with a discriminant of zero.",
1233
- ));
1234
- }
1235
- // Does not have unknown variants
1236
- Err(false) => {
1237
- return Err(Error::new_spanned(
1238
- ast,
1239
- "FromZeros only supported on enums with a variant that has a discriminant of `0`",
1240
- ));
1241
- }
1242
- };
1243
-
1244
- let explicit_bounds = zero_variant
1245
- .fields
1246
- .iter()
1247
- .map(|field| {
1248
- let ty = &field.ty;
1249
- parse_quote! { #ty: #zerocopy_crate::FromZeros }
1250
- })
1251
- .collect::<Vec<WherePredicate>>();
1252
-
1253
- Ok(ImplBlockBuilder::new(
1254
- ast,
1255
- enm,
1256
- Trait::FromZeros,
1257
- FieldBounds::Explicit(explicit_bounds),
1258
- zerocopy_crate,
1259
- )
1260
- .build())
1261
- }
1262
-
1263
- /// Unions are `FromZeros` if
1264
- /// - all fields are `FromZeros` and `Immutable`
1265
- fn derive_from_zeros_union(
1266
- ast: &DeriveInput,
1267
- unn: &DataUnion,
1268
- zerocopy_crate: &Path,
1269
- ) -> TokenStream {
1270
- // FIXME(#5): Remove the `Immutable` bound. It's only necessary for
1271
- // compatibility with `derive(TryFromBytes)` on unions; not for soundness.
1272
- let field_type_trait_bounds =
1273
- FieldBounds::All(&[TraitBound::Slf, TraitBound::Other(Trait::Immutable)]);
1274
- ImplBlockBuilder::new(ast, unn, Trait::FromZeros, field_type_trait_bounds, zerocopy_crate)
1275
- .build()
1276
- }
1277
-
1278
- /// A struct is `FromBytes` if:
1279
- /// - all fields are `FromBytes`
1280
- fn derive_from_bytes_struct(
1281
- ast: &DeriveInput,
1282
- strct: &DataStruct,
1283
- zerocopy_crate: &Path,
1284
- ) -> TokenStream {
1285
- ImplBlockBuilder::new(ast, strct, Trait::FromBytes, FieldBounds::ALL_SELF, zerocopy_crate)
1286
- .build()
1287
- }
1288
-
1289
- /// An enum is `FromBytes` if:
1290
- /// - Every possible bit pattern must be valid, which means that every bit
1291
- /// pattern must correspond to a different enum variant. Thus, for an enum
1292
- /// whose layout takes up N bytes, there must be 2^N variants.
1293
- /// - Since we must know N, only representations which guarantee the layout's
1294
- /// size are allowed. These are `repr(uN)` and `repr(iN)` (`repr(C)` implies
1295
- /// an implementation-defined size). `usize` and `isize` technically guarantee
1296
- /// the layout's size, but would require us to know how large those are on the
1297
- /// target platform. This isn't terribly difficult - we could emit a const
1298
- /// expression that could call `core::mem::size_of` in order to determine the
1299
- /// size and check against the number of enum variants, but a) this would be
1300
- /// platform-specific and, b) even on Rust's smallest bit width platform (32),
1301
- /// this would require ~4 billion enum variants, which obviously isn't a
1302
- /// thing.
1303
- /// - All fields of all variants are `FromBytes`.
1304
- fn derive_from_bytes_enum(
1305
- ast: &DeriveInput,
1306
- enm: &DataEnum,
1307
- zerocopy_crate: &Path,
1308
- ) -> Result<TokenStream, Error> {
1309
- let repr = EnumRepr::from_attrs(&ast.attrs)?;
1310
-
1311
- let variants_required = 1usize << enum_size_from_repr(&repr)?;
1312
- if enm.variants.len() != variants_required {
1313
- return Err(Error::new_spanned(
1314
- ast,
1315
- format!(
1316
- "FromBytes only supported on {} enum with {} variants",
1317
- repr.repr_type_name(),
1318
- variants_required
1319
- ),
1320
- ));
1321
- }
1322
-
1323
- Ok(ImplBlockBuilder::new(ast, enm, Trait::FromBytes, FieldBounds::ALL_SELF, zerocopy_crate)
1324
- .build())
1325
- }
1326
-
1327
- // Returns `None` if the enum's size is not guaranteed by the repr.
1328
- fn enum_size_from_repr(repr: &EnumRepr) -> Result<usize, Error> {
1329
- use CompoundRepr::*;
1330
- use PrimitiveRepr::*;
1331
- use Repr::*;
1332
- match repr {
1333
- Transparent(span)
1334
- | Compound(
1335
- Spanned { t: C | Rust | Primitive(U32 | I32 | U64 | I64 | U128 | I128 | Usize | Isize), span },
1336
- _,
1337
- ) => Err(Error::new(*span, "`FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`")),
1338
- Compound(Spanned { t: Primitive(U8 | I8), span: _ }, _align) => Ok(8),
1339
- Compound(Spanned { t: Primitive(U16 | I16), span: _ }, _align) => Ok(16),
1340
- }
1341
- }
1342
-
1343
- /// Unions are `FromBytes` if
1344
- /// - all fields are `FromBytes` and `Immutable`
1345
- fn derive_from_bytes_union(
1346
- ast: &DeriveInput,
1347
- unn: &DataUnion,
1348
- zerocopy_crate: &Path,
1349
- ) -> TokenStream {
1350
- // FIXME(#5): Remove the `Immutable` bound. It's only necessary for
1351
- // compatibility with `derive(TryFromBytes)` on unions; not for soundness.
1352
- let field_type_trait_bounds =
1353
- FieldBounds::All(&[TraitBound::Slf, TraitBound::Other(Trait::Immutable)]);
1354
- ImplBlockBuilder::new(ast, unn, Trait::FromBytes, field_type_trait_bounds, zerocopy_crate)
1355
- .build()
1356
- }
1357
-
1358
- fn derive_into_bytes_struct(
1359
- ast: &DeriveInput,
1360
- strct: &DataStruct,
1361
- zerocopy_crate: &Path,
1362
- ) -> Result<TokenStream, Error> {
1363
- let repr = StructUnionRepr::from_attrs(&ast.attrs)?;
1364
-
1365
- let is_transparent = repr.is_transparent();
1366
- let is_c = repr.is_c();
1367
- let is_packed_1 = repr.is_packed_1();
1368
- let num_fields = strct.fields().len();
1369
-
1370
- let (padding_check, require_unaligned_fields) = if is_transparent || is_packed_1 {
1371
- // No padding check needed.
1372
- // - repr(transparent): The layout and ABI of the whole struct is the
1373
- // same as its only non-ZST field (meaning there's no padding outside
1374
- // of that field) and we require that field to be `IntoBytes` (meaning
1375
- // there's no padding in that field).
1376
- // - repr(packed): Any inter-field padding bytes are removed, meaning
1377
- // that any padding bytes would need to come from the fields, all of
1378
- // which we require to be `IntoBytes` (meaning they don't have any
1379
- // padding). Note that this holds regardless of other `repr`
1380
- // attributes, including `repr(Rust)`. [1]
1381
- //
1382
- // [1] Per https://doc.rust-lang.org/1.81.0/reference/type-layout.html#the-alignment-modifiers:
1383
- //
1384
- // An important consequence of these rules is that a type with
1385
- // `#[repr(packed(1))]`` (or `#[repr(packed)]``) will have no
1386
- // inter-field padding.
1387
- (None, false)
1388
- } else if is_c && !repr.is_align_gt_1() && num_fields <= 1 {
1389
- // No padding check needed. A repr(C) struct with zero or one field has
1390
- // no padding unless #[repr(align)] explicitly adds padding, which we
1391
- // check for in this branch's condition.
1392
- (None, false)
1393
- } else if ast.generics.params.is_empty() {
1394
- // Is the last field a syntactic slice, i.e., `[SomeType]`.
1395
- let is_syntactic_dst =
1396
- strct.fields().last().map(|(_, _, ty)| matches!(ty, Type::Slice(_))).unwrap_or(false);
1397
- // Since there are no generics, we can emit a padding check. All reprs
1398
- // guarantee that fields won't overlap [1], so the padding check is
1399
- // sound. This is more permissive than the next case, which requires
1400
- // that all field types implement `Unaligned`.
1401
- //
1402
- // [1] Per https://doc.rust-lang.org/1.81.0/reference/type-layout.html#the-rust-representation:
1403
- //
1404
- // The only data layout guarantees made by [`repr(Rust)`] are those
1405
- // required for soundness. They are:
1406
- // ...
1407
- // 2. The fields do not overlap.
1408
- // ...
1409
- if is_c && is_syntactic_dst {
1410
- (Some(PaddingCheck::ReprCStruct), false)
1411
- } else {
1412
- (Some(PaddingCheck::Struct), false)
1413
- }
1414
- } else if is_c && !repr.is_align_gt_1() {
1415
- // We can't use a padding check since there are generic type arguments.
1416
- // Instead, we require all field types to implement `Unaligned`. This
1417
- // ensures that the `repr(C)` layout algorithm will not insert any
1418
- // padding unless #[repr(align)] explicitly adds padding, which we check
1419
- // for in this branch's condition.
1420
- //
1421
- // FIXME(#10): Support type parameters for non-transparent, non-packed
1422
- // structs without requiring `Unaligned`.
1423
- (None, true)
1424
- } else {
1425
- return Err(Error::new(Span::call_site(), "must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout"));
1426
- };
1427
-
1428
- let field_bounds = if require_unaligned_fields {
1429
- FieldBounds::All(&[TraitBound::Slf, TraitBound::Other(Trait::Unaligned)])
1430
- } else {
1431
- FieldBounds::ALL_SELF
1432
- };
1433
-
1434
- Ok(ImplBlockBuilder::new(ast, strct, Trait::IntoBytes, field_bounds, zerocopy_crate)
1435
- .padding_check(padding_check)
1436
- .build())
1437
- }
1438
-
1439
- /// If the type is an enum:
1440
- /// - It must have a defined representation (`repr`s `C`, `u8`, `u16`, `u32`,
1441
- /// `u64`, `usize`, `i8`, `i16`, `i32`, `i64`, or `isize`).
1442
- /// - It must have no padding bytes.
1443
- /// - Its fields must be `IntoBytes`.
1444
- fn derive_into_bytes_enum(
1445
- ast: &DeriveInput,
1446
- enm: &DataEnum,
1447
- zerocopy_crate: &Path,
1448
- ) -> Result<TokenStream, Error> {
1449
- let repr = EnumRepr::from_attrs(&ast.attrs)?;
1450
- if !repr.is_c() && !repr.is_primitive() {
1451
- return Err(Error::new(Span::call_site(), "must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout"));
1452
- }
1453
-
1454
- let tag_type_definition = r#enum::generate_tag_enum(&repr, enm);
1455
- Ok(ImplBlockBuilder::new(ast, enm, Trait::IntoBytes, FieldBounds::ALL_SELF, zerocopy_crate)
1456
- .padding_check(PaddingCheck::Enum { tag_type_definition })
1457
- .build())
1458
- }
1459
-
1460
- /// A union is `IntoBytes` if:
1461
- /// - all fields are `IntoBytes`
1462
- /// - `repr(C)`, `repr(transparent)`, or `repr(packed)`
1463
- /// - no padding (size of union equals size of each field type)
1464
- fn derive_into_bytes_union(
1465
- ast: &DeriveInput,
1466
- unn: &DataUnion,
1467
- zerocopy_crate: &Path,
1468
- ) -> Result<TokenStream, Error> {
1469
- // See #1792 for more context.
1470
- //
1471
- // By checking for `zerocopy_derive_union_into_bytes` both here and in the
1472
- // generated code, we ensure that `--cfg zerocopy_derive_union_into_bytes`
1473
- // need only be passed *either* when compiling this crate *or* when
1474
- // compiling the user's crate. The former is preferable, but in some
1475
- // situations (such as when cross-compiling using `cargo build --target`),
1476
- // it doesn't get propagated to this crate's build by default.
1477
- let cfg_compile_error = if cfg!(zerocopy_derive_union_into_bytes) {
1478
- quote!()
1479
- } else {
1480
- let error_message = "requires --cfg zerocopy_derive_union_into_bytes;
1481
- please let us know you use this feature: https://github.com/google/zerocopy/discussions/1802";
1482
- quote!(
1483
- const _: () = {
1484
- #[cfg(not(zerocopy_derive_union_into_bytes))]
1485
- #zerocopy_crate::util::macro_util::core_reexport::compile_error!(#error_message);
1486
- };
1487
- )
1488
- };
1489
-
1490
- // FIXME(#10): Support type parameters.
1491
- if !ast.generics.params.is_empty() {
1492
- return Err(Error::new(Span::call_site(), "unsupported on types with type parameters"));
1493
- }
1494
-
1495
- // Because we don't support generics, we don't need to worry about
1496
- // special-casing different reprs. So long as there is *some* repr which
1497
- // guarantees the layout, our `PaddingCheck::Union` guarantees that there is
1498
- // no padding.
1499
- let repr = StructUnionRepr::from_attrs(&ast.attrs)?;
1500
- if !repr.is_c() && !repr.is_transparent() && !repr.is_packed_1() {
1501
- return Err(Error::new(
1502
- Span::call_site(),
1503
- "must be #[repr(C)], #[repr(packed)], or #[repr(transparent)]",
1504
- ));
1505
- }
1506
-
1507
- let impl_block =
1508
- ImplBlockBuilder::new(ast, unn, Trait::IntoBytes, FieldBounds::ALL_SELF, zerocopy_crate)
1509
- .padding_check(PaddingCheck::Union)
1510
- .build();
1511
- Ok(quote!(#cfg_compile_error #impl_block))
1512
- }
1513
-
1514
- /// A struct is `Unaligned` if:
1515
- /// - `repr(align)` is no more than 1 and either
1516
- /// - `repr(C)` or `repr(transparent)` and
1517
- /// - all fields `Unaligned`
1518
- /// - `repr(packed)`
1519
- fn derive_unaligned_struct(
1520
- ast: &DeriveInput,
1521
- strct: &DataStruct,
1522
- zerocopy_crate: &Path,
1523
- ) -> Result<TokenStream, Error> {
1524
- let repr = StructUnionRepr::from_attrs(&ast.attrs)?;
1525
- repr.unaligned_validate_no_align_gt_1()?;
1526
-
1527
- let field_bounds = if repr.is_packed_1() {
1528
- FieldBounds::None
1529
- } else if repr.is_c() || repr.is_transparent() {
1530
- FieldBounds::ALL_SELF
1531
- } else {
1532
- return Err(Error::new(Span::call_site(), "must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment"));
1533
- };
1534
-
1535
- Ok(ImplBlockBuilder::new(ast, strct, Trait::Unaligned, field_bounds, zerocopy_crate).build())
1536
- }
1537
-
1538
- /// An enum is `Unaligned` if:
1539
- /// - No `repr(align(N > 1))`
1540
- /// - `repr(u8)` or `repr(i8)`
1541
- fn derive_unaligned_enum(
1542
- ast: &DeriveInput,
1543
- enm: &DataEnum,
1544
- zerocopy_crate: &Path,
1545
- ) -> Result<TokenStream, Error> {
1546
- let repr = EnumRepr::from_attrs(&ast.attrs)?;
1547
- repr.unaligned_validate_no_align_gt_1()?;
1548
-
1549
- if !repr.is_u8() && !repr.is_i8() {
1550
- return Err(Error::new(Span::call_site(), "must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment"));
1551
- }
1552
-
1553
- Ok(ImplBlockBuilder::new(ast, enm, Trait::Unaligned, FieldBounds::ALL_SELF, zerocopy_crate)
1554
- .build())
1555
- }
1556
-
1557
- /// Like structs, a union is `Unaligned` if:
1558
- /// - `repr(align)` is no more than 1 and either
1559
- /// - `repr(C)` or `repr(transparent)` and
1560
- /// - all fields `Unaligned`
1561
- /// - `repr(packed)`
1562
- fn derive_unaligned_union(
1563
- ast: &DeriveInput,
1564
- unn: &DataUnion,
1565
- zerocopy_crate: &Path,
1566
- ) -> Result<TokenStream, Error> {
1567
- let repr = StructUnionRepr::from_attrs(&ast.attrs)?;
1568
- repr.unaligned_validate_no_align_gt_1()?;
1569
-
1570
- let field_type_trait_bounds = if repr.is_packed_1() {
1571
- FieldBounds::None
1572
- } else if repr.is_c() || repr.is_transparent() {
1573
- FieldBounds::ALL_SELF
1574
- } else {
1575
- return Err(Error::new(Span::call_site(), "must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment"));
1576
- };
1577
-
1578
- Ok(ImplBlockBuilder::new(ast, unn, Trait::Unaligned, field_type_trait_bounds, zerocopy_crate)
1579
- .build())
1580
- }
1581
-
1582
- /// This enum describes what kind of padding check needs to be generated for the
1583
- /// associated impl.
1584
- enum PaddingCheck {
1585
- /// Check that the sum of the fields' sizes exactly equals the struct's
1586
- /// size.
1587
- Struct,
1588
- /// Check that a `repr(C)` struct has no padding.
1589
- ReprCStruct,
1590
- /// Check that the size of each field exactly equals the union's size.
1591
- Union,
1592
- /// Check that every variant of the enum contains no padding.
1593
- ///
1594
- /// Because doing so requires a tag enum, this padding check requires an
1595
- /// additional `TokenStream` which defines the tag enum as `___ZerocopyTag`.
1596
- Enum { tag_type_definition: TokenStream },
1597
- }
1598
-
1599
- impl PaddingCheck {
1600
- /// Returns the idents of the trait to use and the macro to call in order to
1601
- /// validate that a type passes the relevant padding check.
1602
- fn validator_trait_and_macro_idents(&self) -> (Ident, Ident) {
1603
- let (trt, mcro) = match self {
1604
- PaddingCheck::Struct => ("PaddingFree", "struct_padding"),
1605
- PaddingCheck::ReprCStruct => ("DynamicPaddingFree", "repr_c_struct_has_padding"),
1606
- PaddingCheck::Union => ("PaddingFree", "union_padding"),
1607
- PaddingCheck::Enum { .. } => ("PaddingFree", "enum_padding"),
1608
- };
1609
-
1610
- let trt = Ident::new(trt, Span::call_site());
1611
- let mcro = Ident::new(mcro, Span::call_site());
1612
- (trt, mcro)
1613
- }
1614
-
1615
- /// Sometimes performing the padding check requires some additional
1616
- /// "context" code. For enums, this is the definition of the tag enum.
1617
- fn validator_macro_context(&self) -> Option<&TokenStream> {
1618
- match self {
1619
- PaddingCheck::Struct | PaddingCheck::ReprCStruct | PaddingCheck::Union => None,
1620
- PaddingCheck::Enum { tag_type_definition } => Some(tag_type_definition),
1621
- }
1622
- }
1623
- }
1624
-
1625
- #[derive(Clone)]
1626
- enum Trait {
1627
- KnownLayout,
1628
- HasField { variant_id: Box<Expr>, field: Box<Type>, field_id: Box<Expr> },
1629
- Immutable,
1630
- TryFromBytes,
1631
- FromZeros,
1632
- FromBytes,
1633
- IntoBytes,
1634
- Unaligned,
1635
- Sized,
1636
- ByteHash,
1637
- ByteEq,
1638
- SplitAt,
1639
- }
1640
-
1641
- impl ToTokens for Trait {
1642
- fn to_tokens(&self, tokens: &mut TokenStream) {
1643
- // According to [1], the format of the derived `Debug`` output is not
1644
- // stable and therefore not guaranteed to represent the variant names.
1645
- // Indeed with the (unstable) `fmt-debug` compiler flag [2], it can
1646
- // return only a minimalized output or empty string. To make sure this
1647
- // code will work in the future and independent of the compiler flag, we
1648
- // translate the variants to their names manually here.
1649
- //
1650
- // [1] https://doc.rust-lang.org/1.81.0/std/fmt/trait.Debug.html#stability
1651
- // [2] https://doc.rust-lang.org/beta/unstable-book/compiler-flags/fmt-debug.html
1652
- let s = match self {
1653
- Trait::HasField { .. } => "HasField",
1654
- Trait::KnownLayout => "KnownLayout",
1655
- Trait::Immutable => "Immutable",
1656
- Trait::TryFromBytes => "TryFromBytes",
1657
- Trait::FromZeros => "FromZeros",
1658
- Trait::FromBytes => "FromBytes",
1659
- Trait::IntoBytes => "IntoBytes",
1660
- Trait::Unaligned => "Unaligned",
1661
- Trait::Sized => "Sized",
1662
- Trait::ByteHash => "ByteHash",
1663
- Trait::ByteEq => "ByteEq",
1664
- Trait::SplitAt => "SplitAt",
1665
- };
1666
- let ident = Ident::new(s, Span::call_site());
1667
- let arguments: Option<syn::AngleBracketedGenericArguments> = match self {
1668
- Trait::HasField { variant_id, field, field_id } => {
1669
- Some(parse_quote!(<#field, #variant_id, #field_id>))
1670
- }
1671
- Trait::KnownLayout
1672
- | Trait::Immutable
1673
- | Trait::TryFromBytes
1674
- | Trait::FromZeros
1675
- | Trait::FromBytes
1676
- | Trait::IntoBytes
1677
- | Trait::Unaligned
1678
- | Trait::Sized
1679
- | Trait::ByteHash
1680
- | Trait::ByteEq
1681
- | Trait::SplitAt => None,
1682
- };
1683
- tokens.extend(quote!(#ident #arguments));
1684
- }
1685
- }
1686
-
1687
- impl Trait {
1688
- fn crate_path(&self, zerocopy_crate: &Path) -> Path {
1689
- match self {
1690
- Self::Sized => {
1691
- parse_quote!(#zerocopy_crate::util::macro_util::core_reexport::marker::#self)
1692
- }
1693
- _ => parse_quote!(#zerocopy_crate::#self),
1694
- }
1695
- }
1696
- }
1697
-
1698
- enum TraitBound {
1699
- Slf,
1700
- Other(Trait),
1701
- }
1702
-
1703
- enum FieldBounds<'a> {
1704
- None,
1705
- All(&'a [TraitBound]),
1706
- Trailing(&'a [TraitBound]),
1707
- Explicit(Vec<WherePredicate>),
1708
- }
1709
-
1710
- impl<'a> FieldBounds<'a> {
1711
- const ALL_SELF: FieldBounds<'a> = FieldBounds::All(&[TraitBound::Slf]);
1712
- const TRAILING_SELF: FieldBounds<'a> = FieldBounds::Trailing(&[TraitBound::Slf]);
1713
- }
1714
-
1715
- enum SelfBounds<'a> {
1716
- None,
1717
- All(&'a [Trait]),
1718
- }
1719
-
1720
- // FIXME(https://github.com/rust-lang/rust-clippy/issues/12908): This is a false
1721
- // positive. Explicit lifetimes are actually necessary here.
1722
- #[allow(clippy::needless_lifetimes)]
1723
- impl<'a> SelfBounds<'a> {
1724
- const SIZED: Self = Self::All(&[Trait::Sized]);
1725
- }
1726
-
1727
- /// Normalizes a slice of bounds by replacing [`TraitBound::Slf`] with `slf`.
1728
- fn normalize_bounds<'a>(
1729
- slf: &'a Trait,
1730
- bounds: &'a [TraitBound],
1731
- ) -> impl 'a + Iterator<Item = Trait> {
1732
- bounds.iter().map(move |bound| match bound {
1733
- TraitBound::Slf => slf.clone(),
1734
- TraitBound::Other(trt) => trt.clone(),
1735
- })
1736
- }
1737
-
1738
- struct ImplBlockBuilder<'a> {
1739
- input: &'a DeriveInput,
1740
- data: &'a dyn DataExt,
1741
- trt: Trait,
1742
- field_type_trait_bounds: FieldBounds<'a>,
1743
- zerocopy_crate: &'a Path,
1744
- self_type_trait_bounds: SelfBounds<'a>,
1745
- padding_check: Option<PaddingCheck>,
1746
- inner_extras: Option<TokenStream>,
1747
- outer_extras: Option<TokenStream>,
1748
- }
1749
-
1750
- impl<'a> ImplBlockBuilder<'a> {
1751
- fn new(
1752
- input: &'a DeriveInput,
1753
- data: &'a dyn DataExt,
1754
- trt: Trait,
1755
- field_type_trait_bounds: FieldBounds<'a>,
1756
- zerocopy_crate: &'a Path,
1757
- ) -> Self {
1758
- Self {
1759
- input,
1760
- data,
1761
- trt,
1762
- field_type_trait_bounds,
1763
- zerocopy_crate,
1764
- self_type_trait_bounds: SelfBounds::None,
1765
- padding_check: None,
1766
- inner_extras: None,
1767
- outer_extras: None,
1768
- }
1769
- }
1770
-
1771
- fn self_type_trait_bounds(mut self, self_type_trait_bounds: SelfBounds<'a>) -> Self {
1772
- self.self_type_trait_bounds = self_type_trait_bounds;
1773
- self
1774
- }
1775
-
1776
- fn padding_check<P: Into<Option<PaddingCheck>>>(mut self, padding_check: P) -> Self {
1777
- self.padding_check = padding_check.into();
1778
- self
1779
- }
1780
-
1781
- fn inner_extras(mut self, inner_extras: TokenStream) -> Self {
1782
- self.inner_extras = Some(inner_extras);
1783
- self
1784
- }
1785
-
1786
- fn outer_extras<T: Into<Option<TokenStream>>>(mut self, outer_extras: T) -> Self {
1787
- self.outer_extras = outer_extras.into();
1788
- self
1789
- }
1790
-
1791
- fn build(self) -> TokenStream {
1792
- // In this documentation, we will refer to this hypothetical struct:
1793
- //
1794
- // #[derive(FromBytes)]
1795
- // struct Foo<T, I: Iterator>
1796
- // where
1797
- // T: Copy,
1798
- // I: Clone,
1799
- // I::Item: Clone,
1800
- // {
1801
- // a: u8,
1802
- // b: T,
1803
- // c: I::Item,
1804
- // }
1805
- //
1806
- // We extract the field types, which in this case are `u8`, `T`, and
1807
- // `I::Item`. We re-use the existing parameters and where clauses. If
1808
- // `require_trait_bound == true` (as it is for `FromBytes), we add where
1809
- // bounds for each field's type:
1810
- //
1811
- // impl<T, I: Iterator> FromBytes for Foo<T, I>
1812
- // where
1813
- // T: Copy,
1814
- // I: Clone,
1815
- // I::Item: Clone,
1816
- // T: FromBytes,
1817
- // I::Item: FromBytes,
1818
- // {
1819
- // }
1820
- //
1821
- // NOTE: It is standard practice to only emit bounds for the type
1822
- // parameters themselves, not for field types based on those parameters
1823
- // (e.g., `T` vs `T::Foo`). For a discussion of why this is standard
1824
- // practice, see https://github.com/rust-lang/rust/issues/26925.
1825
- //
1826
- // The reason we diverge from this standard is that doing it that way
1827
- // for us would be unsound. E.g., consider a type, `T` where `T:
1828
- // FromBytes` but `T::Foo: !FromBytes`. It would not be sound for us to
1829
- // accept a type with a `T::Foo` field as `FromBytes` simply because `T:
1830
- // FromBytes`.
1831
- //
1832
- // While there's no getting around this requirement for us, it does have
1833
- // the pretty serious downside that, when lifetimes are involved, the
1834
- // trait solver ties itself in knots:
1835
- //
1836
- // #[derive(Unaligned)]
1837
- // #[repr(C)]
1838
- // struct Dup<'a, 'b> {
1839
- // a: PhantomData<&'a u8>,
1840
- // b: PhantomData<&'b u8>,
1841
- // }
1842
- //
1843
- // error[E0283]: type annotations required: cannot resolve `core::marker::PhantomData<&'a u8>: zerocopy::Unaligned`
1844
- // --> src/main.rs:6:10
1845
- // |
1846
- // 6 | #[derive(Unaligned)]
1847
- // | ^^^^^^^^^
1848
- // |
1849
- // = note: required by `zerocopy::Unaligned`
1850
-
1851
- let type_ident = &self.input.ident;
1852
- let trait_path = self.trt.crate_path(self.zerocopy_crate);
1853
- let fields = self.data.fields();
1854
- let variants = self.data.variants();
1855
- let tag = self.data.tag();
1856
- let zerocopy_crate = self.zerocopy_crate;
1857
-
1858
- fn bound_tt(
1859
- ty: &Type,
1860
- traits: impl Iterator<Item = Trait>,
1861
- zerocopy_crate: &Path,
1862
- ) -> WherePredicate {
1863
- let traits = traits.map(|t| t.crate_path(zerocopy_crate));
1864
- parse_quote!(#ty: #(#traits)+*)
1865
- }
1866
- let field_type_bounds: Vec<_> = match (self.field_type_trait_bounds, &fields[..]) {
1867
- (FieldBounds::All(traits), _) => fields
1868
- .iter()
1869
- .map(|(_vis, _name, ty)| {
1870
- bound_tt(ty, normalize_bounds(&self.trt, traits), zerocopy_crate)
1871
- })
1872
- .collect(),
1873
- (FieldBounds::None, _) | (FieldBounds::Trailing(..), []) => vec![],
1874
- (FieldBounds::Trailing(traits), [.., last]) => {
1875
- vec![bound_tt(last.2, normalize_bounds(&self.trt, traits), zerocopy_crate)]
1876
- }
1877
- (FieldBounds::Explicit(bounds), _) => bounds,
1878
- };
1879
-
1880
- // Don't bother emitting a padding check if there are no fields.
1881
- #[allow(unstable_name_collisions)] // See `BoolExt` below
1882
- let padding_check_bound = self
1883
- .padding_check
1884
- .and_then(|check| (!fields.is_empty()).then_some(check))
1885
- .map(|check| {
1886
- let variant_types = variants.iter().map(|(_, fields)| {
1887
- let types = fields.iter().map(|(_vis, _name, ty)| ty);
1888
- quote!([#((#types)),*])
1889
- });
1890
- let validator_context = check.validator_macro_context();
1891
- let (trt, validator_macro) = check.validator_trait_and_macro_idents();
1892
- let t = tag.iter();
1893
- parse_quote! {
1894
- (): #zerocopy_crate::util::macro_util::#trt<
1895
- Self,
1896
- {
1897
- #validator_context
1898
- #zerocopy_crate::#validator_macro!(Self, #(#t,)* #(#variant_types),*)
1899
- }
1900
- >
1901
- }
1902
- });
1903
-
1904
- let self_bounds: Option<WherePredicate> = match self.self_type_trait_bounds {
1905
- SelfBounds::None => None,
1906
- SelfBounds::All(traits) => {
1907
- Some(bound_tt(&parse_quote!(Self), traits.iter().cloned(), zerocopy_crate))
1908
- }
1909
- };
1910
-
1911
- let bounds = self
1912
- .input
1913
- .generics
1914
- .where_clause
1915
- .as_ref()
1916
- .map(|where_clause| where_clause.predicates.iter())
1917
- .into_iter()
1918
- .flatten()
1919
- .chain(field_type_bounds.iter())
1920
- .chain(padding_check_bound.iter())
1921
- .chain(self_bounds.iter());
1922
-
1923
- // The parameters with trait bounds, but without type defaults.
1924
- let params = self.input.generics.params.clone().into_iter().map(|mut param| {
1925
- match &mut param {
1926
- GenericParam::Type(ty) => ty.default = None,
1927
- GenericParam::Const(cnst) => cnst.default = None,
1928
- GenericParam::Lifetime(_) => {}
1929
- }
1930
- quote!(#param)
1931
- });
1932
-
1933
- // The identifiers of the parameters without trait bounds or type
1934
- // defaults.
1935
- let param_idents = self.input.generics.params.iter().map(|param| match param {
1936
- GenericParam::Type(ty) => {
1937
- let ident = &ty.ident;
1938
- quote!(#ident)
1939
- }
1940
- GenericParam::Lifetime(l) => {
1941
- let ident = &l.lifetime;
1942
- quote!(#ident)
1943
- }
1944
- GenericParam::Const(cnst) => {
1945
- let ident = &cnst.ident;
1946
- quote!({#ident})
1947
- }
1948
- });
1949
-
1950
- let inner_extras = self.inner_extras;
1951
- let impl_tokens = quote! {
1952
- #[allow(deprecated, non_local_definitions)]
1953
- // While there are not currently any warnings that this suppresses
1954
- // (that we're aware of), it's good future-proofing hygiene.
1955
- #[automatically_derived]
1956
- unsafe impl < #(#params),* > #trait_path for #type_ident < #(#param_idents),* >
1957
- where
1958
- #(#bounds,)*
1959
- {
1960
- fn only_derive_is_allowed_to_implement_this_trait() {}
1961
-
1962
- #inner_extras
1963
- }
1964
- };
1965
-
1966
- if let Some(outer_extras) = self.outer_extras.filter(|e| !e.is_empty()) {
1967
- // So that any items defined in `#outer_extras` don't conflict with
1968
- // existing names defined in this scope.
1969
- quote! {
1970
- #[allow(deprecated, non_local_definitions)]
1971
- // While there are not currently any warnings that this suppresses
1972
- // (that we're aware of), it's good future-proofing hygiene.
1973
- #[automatically_derived]
1974
- const _: () = {
1975
- #impl_tokens
1976
-
1977
- #outer_extras
1978
- };
1979
- }
1980
- } else {
1981
- impl_tokens
1982
- }
1983
- }
1984
- }
1985
-
1986
- // A polyfill for `Option::then_some`, which was added after our MSRV.
1987
- //
1988
- // The `#[allow(unused)]` is necessary because, on sufficiently recent toolchain
1989
- // versions, `b.then_some(...)` resolves to the inherent method rather than to
1990
- // this trait, and so this trait is considered unused.
1991
- //
1992
- // FIXME(#67): Remove this once our MSRV is >= 1.62.
1993
- #[allow(unused)]
1994
- trait BoolExt {
1995
- fn then_some<T>(self, t: T) -> Option<T>;
1996
- }
1997
-
1998
- impl BoolExt for bool {
1999
- fn then_some<T>(self, t: T) -> Option<T> {
2000
- if self {
2001
- Some(t)
2002
- } else {
2003
- None
2004
- }
2005
- }
2006
- }