/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zerocopy-0.8.27/src/macros.rs
Line  | Count  | Source  | 
1  |  | // Copyright 2024 The Fuchsia Authors  | 
2  |  | //  | 
3  |  | // Licensed under the 2-Clause BSD License <LICENSE-BSD or  | 
4  |  | // https://opensource.org/license/bsd-2-clause>, Apache License, Version 2.0  | 
5  |  | // <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT  | 
6  |  | // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.  | 
7  |  | // This file may not be copied, modified, or distributed except according to  | 
8  |  | // those terms.  | 
9  |  |  | 
10  |  | /// Safely transmutes a value of one type to a value of another type of the same  | 
11  |  | /// size.  | 
12  |  | ///  | 
13  |  | /// This macro behaves like an invocation of this function:  | 
14  |  | ///  | 
15  |  | /// ```ignore  | 
16  |  | /// const fn transmute<Src, Dst>(src: Src) -> Dst  | 
17  |  | /// where  | 
18  |  | ///     Src: IntoBytes,  | 
19  |  | ///     Dst: FromBytes,  | 
20  |  | ///     size_of::<Src>() == size_of::<Dst>(),  | 
21  |  | /// { | 
22  |  | /// # /*  | 
23  |  | ///     ...  | 
24  |  | /// # */  | 
25  |  | /// }  | 
26  |  | /// ```  | 
27  |  | ///  | 
28  |  | /// However, unlike a function, this macro can only be invoked when the types of  | 
29  |  | /// `Src` and `Dst` are completely concrete. The types `Src` and `Dst` are  | 
30  |  | /// inferred from the calling context; they cannot be explicitly specified in  | 
31  |  | /// the macro invocation.  | 
32  |  | ///  | 
33  |  | /// Note that the `Src` produced by the expression `$e` will *not* be dropped.  | 
34  |  | /// Semantically, its bits will be copied into a new value of type `Dst`, the  | 
35  |  | /// original `Src` will be forgotten, and the value of type `Dst` will be  | 
36  |  | /// returned.  | 
37  |  | ///  | 
38  |  | /// # `#![allow(shrink)]`  | 
39  |  | ///  | 
40  |  | /// If `#![allow(shrink)]` is provided, `transmute!` additionally supports  | 
41  |  | /// transmutations that shrink the size of the value; e.g.:  | 
42  |  | ///  | 
43  |  | /// ```  | 
44  |  | /// # use zerocopy::transmute;  | 
45  |  | /// let u: u32 = transmute!(#![allow(shrink)] 0u64);  | 
46  |  | /// assert_eq!(u, 0u32);  | 
47  |  | /// ```  | 
48  |  | ///  | 
49  |  | /// # Examples  | 
50  |  | ///  | 
51  |  | /// ```  | 
52  |  | /// # use zerocopy::transmute;  | 
53  |  | /// let one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];  | 
54  |  | ///  | 
55  |  | /// let two_dimensional: [[u8; 4]; 2] = transmute!(one_dimensional);  | 
56  |  | ///  | 
57  |  | /// assert_eq!(two_dimensional, [[0, 1, 2, 3], [4, 5, 6, 7]]);  | 
58  |  | /// ```  | 
59  |  | ///  | 
60  |  | /// # Use in `const` contexts  | 
61  |  | ///  | 
62  |  | /// This macro can be invoked in `const` contexts.  | 
63  |  | #[macro_export]  | 
64  |  | macro_rules! transmute { | 
65  |  |     // NOTE: This must be a macro (rather than a function with trait bounds)  | 
66  |  |     // because there's no way, in a generic context, to enforce that two types  | 
67  |  |     // have the same size. `core::mem::transmute` uses compiler magic to enforce  | 
68  |  |     // this so long as the types are concrete.  | 
69  |  |     (#![allow(shrink)] $e:expr) => {{ | 
70  |  |         let mut e = $e;  | 
71  |  |         if false { | 
72  |  |             // This branch, though never taken, ensures that the type of `e` is  | 
73  |  |             // `IntoBytes` and that the type of the  outer macro invocation  | 
74  |  |             // expression is `FromBytes`.  | 
75  |  |  | 
76  |  |             fn transmute<Src, Dst>(src: Src) -> Dst  | 
77  |  |             where  | 
78  |  |                 Src: $crate::IntoBytes,  | 
79  |  |                 Dst: $crate::FromBytes,  | 
80  |  |             { | 
81  |  |                 let _ = src;  | 
82  |  |                 loop {} | 
83  |  |             }  | 
84  |  |             loop {} | 
85  |  |             #[allow(unreachable_code)]  | 
86  |  |             transmute(e)  | 
87  |  |         } else { | 
88  |  |             use $crate::util::macro_util::core_reexport::mem::ManuallyDrop;  | 
89  |  |  | 
90  |  |             // NOTE: `repr(packed)` is important! It ensures that the size of  | 
91  |  |             // `Transmute` won't be rounded up to accommodate `Src`'s or `Dst`'s  | 
92  |  |             // alignment, which would break the size comparison logic below.  | 
93  |  |             //  | 
94  |  |             // As an example of why this is problematic, consider `Src = [u8;  | 
95  |  |             // 5]`, `Dst = u32`. The total size of `Transmute<Src, Dst>` would  | 
96  |  |             // be 8, and so we would reject a `[u8; 5]` to `u32` transmute as  | 
97  |  |             // being size-increasing, which it isn't.  | 
98  |  |             #[repr(C, packed)]  | 
99  |  |             union Transmute<Src, Dst> { | 
100  |  |                 src: ManuallyDrop<Src>,  | 
101  |  |                 dst: ManuallyDrop<Dst>,  | 
102  |  |             }  | 
103  |  |  | 
104  |  |             // SAFETY: `Transmute` is a `reper(C)` union whose `src` field has  | 
105  |  |             // type `ManuallyDrop<Src>`. Thus, the `src` field starts at byte  | 
106  |  |             // offset 0 within `Transmute` [1]. `ManuallyDrop<T>` has the same  | 
107  |  |             // layout and bit validity as `T`, so it is sound to transmute `Src`  | 
108  |  |             // to `Transmute`.  | 
109  |  |             //  | 
110  |  |             // [1] https://doc.rust-lang.org/1.85.0/reference/type-layout.html#reprc-unions  | 
111  |  |             //  | 
112  |  |             // [2] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:  | 
113  |  |             //  | 
114  |  |             //   `ManuallyDrop<T>` is guaranteed to have the same layout and bit  | 
115  |  |             //   validity as `T`  | 
116  |  |             let u: Transmute<_, _> = unsafe { | 
117  |  |                 // Clippy: We can't annotate the types; this macro is designed  | 
118  |  |                 // to infer the types from the calling context.  | 
119  |  |                 #[allow(clippy::missing_transmute_annotations)]  | 
120  |  |                 $crate::util::macro_util::core_reexport::mem::transmute(e)  | 
121  |  |             };  | 
122  |  |  | 
123  |  |             if false { | 
124  |  |                 // SAFETY: This code is never executed.  | 
125  |  |                 e = ManuallyDrop::into_inner(unsafe { u.src }); | 
126  |  |                 // Suppress the `unused_assignments` lint on the previous line.  | 
127  |  |                 let _ = e;  | 
128  |  |                 loop {} | 
129  |  |             } else { | 
130  |  |                 // SAFETY: Per the safety comment on `let u` above, the `dst`  | 
131  |  |                 // field in `Transmute` starts at byte offset 0, and has the  | 
132  |  |                 // same layout and bit validity as `Dst`.  | 
133  |  |                 //  | 
134  |  |                 // Transmuting `Src` to `Transmute<Src, Dst>` above using  | 
135  |  |                 // `core::mem::transmute` ensures that `size_of::<Src>() ==  | 
136  |  |                 // size_of::<Transmute<Src, Dst>>()`. A `#[repr(C, packed)]`  | 
137  |  |                 // union has the maximum size of all of its fields [1], so this  | 
138  |  |                 // is equivalent to `size_of::<Src>() >= size_of::<Dst>()`.  | 
139  |  |                 //  | 
140  |  |                 // The outer `if`'s `false` branch ensures that `Src: IntoBytes`  | 
141  |  |                 // and `Dst: FromBytes`. This, combined with the size bound,  | 
142  |  |                 // ensures that this transmute is sound.  | 
143  |  |                 //  | 
144  |  |                 // [1] Per https://doc.rust-lang.org/1.85.0/reference/type-layout.html#reprc-unions:  | 
145  |  |                 //  | 
146  |  |                 //   The union will have a size of the maximum size of all of  | 
147  |  |                 //   its fields rounded to its alignment  | 
148  |  |                 let dst = unsafe { u.dst }; | 
149  |  |                 $crate::util::macro_util::must_use(ManuallyDrop::into_inner(dst))  | 
150  |  |             }  | 
151  |  |         }  | 
152  |  |     }};  | 
153  |  |     ($e:expr) => {{ | 
154  |  |         let e = $e;  | 
155  |  |         if false { | 
156  |  |             // This branch, though never taken, ensures that the type of `e` is  | 
157  |  |             // `IntoBytes` and that the type of the  outer macro invocation  | 
158  |  |             // expression is `FromBytes`.  | 
159  |  |  | 
160  | 0  |             fn transmute<Src, Dst>(src: Src) -> Dst  | 
161  | 0  |             where  | 
162  | 0  |                 Src: $crate::IntoBytes,  | 
163  | 0  |                 Dst: $crate::FromBytes,  | 
164  |  |             { | 
165  | 0  |                 let _ = src;  | 
166  | 0  |                 loop {}Unexecuted instantiation: half::bfloat::convert::bf16_to_f32::transmute::<_, _> Unexecuted instantiation: half::bfloat::convert::bf16_to_f32::transmute::<_, _> Unexecuted instantiation: half::bfloat::convert::bf16_to_f64::transmute::<_, _> Unexecuted instantiation: half::bfloat::convert::bf16_to_f64::transmute::<_, _> Unexecuted instantiation: half::bfloat::convert::bf16_to_f64::transmute::<_, _> Unexecuted instantiation: half::bfloat::convert::bf16_to_f64::transmute::<_, _> Unexecuted instantiation: half::bfloat::convert::bf16_to_f64::transmute::<_, _> Unexecuted instantiation: half::bfloat::convert::f32_to_bf16::transmute::<_, _> Unexecuted instantiation: half::bfloat::convert::f64_to_bf16::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f16_to_f32_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f16_to_f32_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f32_to_f16_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f32_to_f16_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f16x4_to_f32x4_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f16x4_to_f32x4_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f16x8_to_f32x8_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f16x8_to_f32x8_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f32x4_to_f16x4_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f32x4_to_f16x4_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f32x8_to_f16x8_x86_f16c::transmute::<_, _> Unexecuted instantiation: half::binary16::arch::x86::f32x8_to_f16x8_x86_f16c::transmute::<_, _> Unexecuted instantiation: zerocopy::byteorder::f32_ext::to_be_bytes::transmute::<_, _> Unexecuted instantiation: zerocopy::byteorder::f32_ext::to_le_bytes::transmute::<_, _> Unexecuted instantiation: zerocopy::byteorder::f32_ext::from_be_bytes::transmute::<_, _> Unexecuted instantiation: zerocopy::byteorder::f32_ext::from_le_bytes::transmute::<_, _> Unexecuted instantiation: zerocopy::byteorder::f64_ext::to_be_bytes::transmute::<_, _> Unexecuted instantiation: zerocopy::byteorder::f64_ext::to_le_bytes::transmute::<_, _> Unexecuted instantiation: zerocopy::byteorder::f64_ext::from_be_bytes::transmute::<_, _> Unexecuted instantiation: zerocopy::byteorder::f64_ext::from_le_bytes::transmute::<_, _>  | 
167  |  |             }  | 
168  |  |             loop {} | 
169  |  |             #[allow(unreachable_code)]  | 
170  |  |             transmute(e)  | 
171  |  |         } else { | 
172  |  |             // SAFETY: `core::mem::transmute` ensures that the type of `e` and  | 
173  |  |             // the type of this macro invocation expression have the same size.  | 
174  |  |             // We know this transmute is safe thanks to the `IntoBytes` and  | 
175  |  |             // `FromBytes` bounds enforced by the `false` branch.  | 
176  |  |             let u = unsafe { | 
177  |  |                 // Clippy: We can't annotate the types; this macro is designed  | 
178  |  |                 // to infer the types from the calling context.  | 
179  |  |                 #[allow(clippy::missing_transmute_annotations, unnecessary_transmutes)]  | 
180  |  |                 $crate::util::macro_util::core_reexport::mem::transmute(e)  | 
181  |  |             };  | 
182  |  |             $crate::util::macro_util::must_use(u)  | 
183  |  |         }  | 
184  |  |     }};  | 
185  |  | }  | 
186  |  |  | 
187  |  | /// Safely transmutes a mutable or immutable reference of one type to an  | 
188  |  | /// immutable reference of another type of the same size and compatible  | 
189  |  | /// alignment.  | 
190  |  | ///  | 
191  |  | /// This macro behaves like an invocation of this function:  | 
192  |  | ///  | 
193  |  | /// ```ignore  | 
194  |  | /// fn transmute_ref<'src, 'dst, Src, Dst>(src: &'src Src) -> &'dst Dst  | 
195  |  | /// where  | 
196  |  | ///     'src: 'dst,  | 
197  |  | ///     Src: IntoBytes + Immutable + ?Sized,  | 
198  |  | ///     Dst: FromBytes + Immutable + ?Sized,  | 
199  |  | ///     align_of::<Src>() >= align_of::<Dst>(),  | 
200  |  | ///     size_compatible::<Src, Dst>(),  | 
201  |  | /// { | 
202  |  | /// # /*  | 
203  |  | ///     ...  | 
204  |  | /// # */  | 
205  |  | /// }  | 
206  |  | /// ```  | 
207  |  | ///  | 
208  |  | /// The types `Src` and `Dst` are inferred from the calling context; they cannot  | 
209  |  | /// be explicitly specified in the macro invocation.  | 
210  |  | ///  | 
211  |  | /// # Size compatibility  | 
212  |  | ///  | 
213  |  | /// `transmute_ref!` supports transmuting between `Sized` types or between  | 
214  |  | /// unsized (i.e., `?Sized`) types. It supports any transmutation that preserves  | 
215  |  | /// the number of bytes of the referent, even if doing so requires updating the  | 
216  |  | /// metadata stored in an unsized "fat" reference:  | 
217  |  | ///  | 
218  |  | /// ```  | 
219  |  | /// # use zerocopy::transmute_ref;  | 
220  |  | /// # use core::mem::size_of_val; // Not in the prelude on our MSRV  | 
221  |  | /// let src: &[[u8; 2]] = &[[0, 1], [2, 3]][..];  | 
222  |  | /// let dst: &[u8] = transmute_ref!(src);  | 
223  |  | ///  | 
224  |  | /// assert_eq!(src.len(), 2);  | 
225  |  | /// assert_eq!(dst.len(), 4);  | 
226  |  | /// assert_eq!(dst, [0, 1, 2, 3]);  | 
227  |  | /// assert_eq!(size_of_val(src), size_of_val(dst));  | 
228  |  | /// ```  | 
229  |  | ///  | 
230  |  | /// # Errors  | 
231  |  | ///  | 
232  |  | /// Violations of the alignment and size compatibility checks are detected  | 
233  |  | /// *after* the compiler performs monomorphization. This has two important  | 
234  |  | /// consequences.  | 
235  |  | ///  | 
236  |  | /// First, it means that generic code will *never* fail these conditions:  | 
237  |  | ///  | 
238  |  | /// ```  | 
239  |  | /// # use zerocopy::{transmute_ref, FromBytes, IntoBytes, Immutable}; | 
240  |  | /// fn transmute_ref<Src, Dst>(src: &Src) -> &Dst  | 
241  |  | /// where  | 
242  |  | ///     Src: IntoBytes + Immutable,  | 
243  |  | ///     Dst: FromBytes + Immutable,  | 
244  |  | /// { | 
245  |  | ///     transmute_ref!(src)  | 
246  |  | /// }  | 
247  |  | /// ```  | 
248  |  | ///  | 
249  |  | /// Instead, failures will only be detected once generic code is instantiated  | 
250  |  | /// with concrete types:  | 
251  |  | ///  | 
252  |  | /// ```compile_fail,E0080  | 
253  |  | /// # use zerocopy::{transmute_ref, FromBytes, IntoBytes, Immutable}; | 
254  |  | /// #  | 
255  |  | /// # fn transmute_ref<Src, Dst>(src: &Src) -> &Dst  | 
256  |  | /// # where  | 
257  |  | /// #     Src: IntoBytes + Immutable,  | 
258  |  | /// #     Dst: FromBytes + Immutable,  | 
259  |  | /// # { | 
260  |  | /// #     transmute_ref!(src)  | 
261  |  | /// # }  | 
262  |  | /// let src: &u16 = &0;  | 
263  |  | /// let dst: &u8 = transmute_ref(src);  | 
264  |  | /// ```  | 
265  |  | ///  | 
266  |  | /// Second, the fact that violations are detected after monomorphization means  | 
267  |  | /// that `cargo check` will usually not detect errors, even when types are  | 
268  |  | /// concrete. Instead, `cargo build` must be used to detect such errors.  | 
269  |  | ///  | 
270  |  | /// # Examples  | 
271  |  | ///  | 
272  |  | /// Transmuting between `Sized` types:  | 
273  |  | ///  | 
274  |  | /// ```  | 
275  |  | /// # use zerocopy::transmute_ref;  | 
276  |  | /// let one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];  | 
277  |  | ///  | 
278  |  | /// let two_dimensional: &[[u8; 4]; 2] = transmute_ref!(&one_dimensional);  | 
279  |  | ///  | 
280  |  | /// assert_eq!(two_dimensional, &[[0, 1, 2, 3], [4, 5, 6, 7]]);  | 
281  |  | /// ```  | 
282  |  | ///  | 
283  |  | /// Transmuting between unsized types:  | 
284  |  | ///  | 
285  |  | /// ```  | 
286  |  | /// # use {zerocopy::*, zerocopy_derive::*}; | 
287  |  | /// # type u16 = zerocopy::byteorder::native_endian::U16;  | 
288  |  | /// # type u32 = zerocopy::byteorder::native_endian::U32;  | 
289  |  | /// #[derive(KnownLayout, FromBytes, IntoBytes, Immutable)]  | 
290  |  | /// #[repr(C)]  | 
291  |  | /// struct SliceDst<T, U> { | 
292  |  | ///     t: T,  | 
293  |  | ///     u: [U],  | 
294  |  | /// }  | 
295  |  | ///  | 
296  |  | /// type Src = SliceDst<u32, u16>;  | 
297  |  | /// type Dst = SliceDst<u16, u8>;  | 
298  |  | ///  | 
299  |  | /// let src = Src::ref_from_bytes(&[0, 1, 2, 3, 4, 5, 6, 7]).unwrap();  | 
300  |  | /// let dst: &Dst = transmute_ref!(src);  | 
301  |  | ///  | 
302  |  | /// assert_eq!(src.t.as_bytes(), [0, 1, 2, 3]);  | 
303  |  | /// assert_eq!(src.u.len(), 2);  | 
304  |  | /// assert_eq!(src.u.as_bytes(), [4, 5, 6, 7]);  | 
305  |  | ///  | 
306  |  | /// assert_eq!(dst.t.as_bytes(), [0, 1]);  | 
307  |  | /// assert_eq!(dst.u, [2, 3, 4, 5, 6, 7]);  | 
308  |  | /// ```  | 
309  |  | ///  | 
310  |  | /// # Use in `const` contexts  | 
311  |  | ///  | 
312  |  | /// This macro can be invoked in `const` contexts only when `Src: Sized` and  | 
313  |  | /// `Dst: Sized`.  | 
314  |  | #[macro_export]  | 
315  |  | macro_rules! transmute_ref { | 
316  |  |     ($e:expr) => {{ | 
317  |  |         // NOTE: This must be a macro (rather than a function with trait bounds)  | 
318  |  |         // because there's no way, in a generic context, to enforce that two  | 
319  |  |         // types have the same size or alignment.  | 
320  |  |  | 
321  |  |         // Ensure that the source type is a reference or a mutable reference  | 
322  |  |         // (note that mutable references are implicitly reborrowed here).  | 
323  |  |         let e: &_ = $e;  | 
324  |  |  | 
325  |  |         #[allow(unused, clippy::diverging_sub_expression)]  | 
326  |  |         if false { | 
327  |  |             // This branch, though never taken, ensures that the type of `e` is  | 
328  |  |             // `&T` where `T: IntoBytes + Immutable`, and that the type of this  | 
329  |  |             // macro expression is `&U` where `U: FromBytes + Immutable`.  | 
330  |  |  | 
331  |  |             struct AssertSrcIsIntoBytes<'a, T: ?::core::marker::Sized + $crate::IntoBytes>(&'a T);  | 
332  |  |             struct AssertSrcIsImmutable<'a, T: ?::core::marker::Sized + $crate::Immutable>(&'a T);  | 
333  |  |             struct AssertDstIsFromBytes<'a, U: ?::core::marker::Sized + $crate::FromBytes>(&'a U);  | 
334  |  |             struct AssertDstIsImmutable<'a, T: ?::core::marker::Sized + $crate::Immutable>(&'a T);  | 
335  |  |  | 
336  |  |             let _ = AssertSrcIsIntoBytes(e);  | 
337  |  |             let _ = AssertSrcIsImmutable(e);  | 
338  |  |  | 
339  |  |             if true { | 
340  |  |                 #[allow(unused, unreachable_code)]  | 
341  |  |                 let u = AssertDstIsFromBytes(loop {}); | 
342  |  |                 u.0  | 
343  |  |             } else { | 
344  |  |                 #[allow(unused, unreachable_code)]  | 
345  |  |                 let u = AssertDstIsImmutable(loop {}); | 
346  |  |                 u.0  | 
347  |  |             }  | 
348  |  |         } else { | 
349  |  |             use $crate::util::macro_util::TransmuteRefDst;  | 
350  |  |             let t = $crate::util::macro_util::Wrap::new(e);  | 
351  |  |             // SAFETY: The `if false` branch ensures that:  | 
352  |  |             // - `Src: IntoBytes + Immutable`  | 
353  |  |             // - `Dst: FromBytes + Immutable`  | 
354  |  |             unsafe { | 
355  |  |                 t.transmute_ref()  | 
356  |  |             }  | 
357  |  |         }  | 
358  |  |     }}  | 
359  |  | }  | 
360  |  |  | 
361  |  | /// Safely transmutes a mutable reference of one type to a mutable reference of  | 
362  |  | /// another type of the same size and compatible alignment.  | 
363  |  | ///  | 
364  |  | /// This macro behaves like an invocation of this function:  | 
365  |  | ///  | 
366  |  | /// ```ignore  | 
367  |  | /// const fn transmute_mut<'src, 'dst, Src, Dst>(src: &'src mut Src) -> &'dst mut Dst  | 
368  |  | /// where  | 
369  |  | ///     'src: 'dst,  | 
370  |  | ///     Src: FromBytes + IntoBytes,  | 
371  |  | ///     Dst: FromBytes + IntoBytes,  | 
372  |  | ///     align_of::<Src>() >= align_of::<Dst>(),  | 
373  |  | ///     size_compatible::<Src, Dst>(),  | 
374  |  | /// { | 
375  |  | /// # /*  | 
376  |  | ///     ...  | 
377  |  | /// # */  | 
378  |  | /// }  | 
379  |  | /// ```  | 
380  |  | ///  | 
381  |  | /// The types `Src` and `Dst` are inferred from the calling context; they cannot  | 
382  |  | /// be explicitly specified in the macro invocation.  | 
383  |  | ///  | 
384  |  | /// # Size compatibility  | 
385  |  | ///  | 
386  |  | /// `transmute_mut!` supports transmuting between `Sized` types or between  | 
387  |  | /// unsized (i.e., `?Sized`) types. It supports any transmutation that preserves  | 
388  |  | /// the number of bytes of the referent, even if doing so requires updating the  | 
389  |  | /// metadata stored in an unsized "fat" reference:  | 
390  |  | ///  | 
391  |  | /// ```  | 
392  |  | /// # use zerocopy::transmute_mut;  | 
393  |  | /// # use core::mem::size_of_val; // Not in the prelude on our MSRV  | 
394  |  | /// let src: &mut [[u8; 2]] = &mut [[0, 1], [2, 3]][..];  | 
395  |  | /// let dst: &mut [u8] = transmute_mut!(src);  | 
396  |  | ///  | 
397  |  | /// assert_eq!(dst.len(), 4);  | 
398  |  | /// assert_eq!(dst, [0, 1, 2, 3]);  | 
399  |  | /// let dst_size = size_of_val(dst);  | 
400  |  | /// assert_eq!(src.len(), 2);  | 
401  |  | /// assert_eq!(size_of_val(src), dst_size);  | 
402  |  | /// ```  | 
403  |  | ///  | 
404  |  | /// # Errors  | 
405  |  | ///  | 
406  |  | /// Violations of the alignment and size compatibility checks are detected  | 
407  |  | /// *after* the compiler performs monomorphization. This has two important  | 
408  |  | /// consequences.  | 
409  |  | ///  | 
410  |  | /// First, it means that generic code will *never* fail these conditions:  | 
411  |  | ///  | 
412  |  | /// ```  | 
413  |  | /// # use zerocopy::{transmute_mut, FromBytes, IntoBytes, Immutable}; | 
414  |  | /// fn transmute_mut<Src, Dst>(src: &mut Src) -> &mut Dst  | 
415  |  | /// where  | 
416  |  | ///     Src: FromBytes + IntoBytes,  | 
417  |  | ///     Dst: FromBytes + IntoBytes,  | 
418  |  | /// { | 
419  |  | ///     transmute_mut!(src)  | 
420  |  | /// }  | 
421  |  | /// ```  | 
422  |  | ///  | 
423  |  | /// Instead, failures will only be detected once generic code is instantiated  | 
424  |  | /// with concrete types:  | 
425  |  | ///  | 
426  |  | /// ```compile_fail,E0080  | 
427  |  | /// # use zerocopy::{transmute_mut, FromBytes, IntoBytes, Immutable}; | 
428  |  | /// #  | 
429  |  | /// # fn transmute_mut<Src, Dst>(src: &mut Src) -> &mut Dst  | 
430  |  | /// # where  | 
431  |  | /// #     Src: FromBytes + IntoBytes,  | 
432  |  | /// #     Dst: FromBytes + IntoBytes,  | 
433  |  | /// # { | 
434  |  | /// #     transmute_mut!(src)  | 
435  |  | /// # }  | 
436  |  | /// let src: &mut u16 = &mut 0;  | 
437  |  | /// let dst: &mut u8 = transmute_mut(src);  | 
438  |  | /// ```  | 
439  |  | ///  | 
440  |  | /// Second, the fact that violations are detected after monomorphization means  | 
441  |  | /// that `cargo check` will usually not detect errors, even when types are  | 
442  |  | /// concrete. Instead, `cargo build` must be used to detect such errors.  | 
443  |  | ///  | 
444  |  | ///  | 
445  |  | /// # Examples  | 
446  |  | ///  | 
447  |  | /// Transmuting between `Sized` types:  | 
448  |  | ///  | 
449  |  | /// ```  | 
450  |  | /// # use zerocopy::transmute_mut;  | 
451  |  | /// let mut one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];  | 
452  |  | ///  | 
453  |  | /// let two_dimensional: &mut [[u8; 4]; 2] = transmute_mut!(&mut one_dimensional);  | 
454  |  | ///  | 
455  |  | /// assert_eq!(two_dimensional, &[[0, 1, 2, 3], [4, 5, 6, 7]]);  | 
456  |  | ///  | 
457  |  | /// two_dimensional.reverse();  | 
458  |  | ///  | 
459  |  | /// assert_eq!(one_dimensional, [4, 5, 6, 7, 0, 1, 2, 3]);  | 
460  |  | /// ```  | 
461  |  | ///  | 
462  |  | /// Transmuting between unsized types:  | 
463  |  | ///  | 
464  |  | /// ```  | 
465  |  | /// # use {zerocopy::*, zerocopy_derive::*}; | 
466  |  | /// # type u16 = zerocopy::byteorder::native_endian::U16;  | 
467  |  | /// # type u32 = zerocopy::byteorder::native_endian::U32;  | 
468  |  | /// #[derive(KnownLayout, FromBytes, IntoBytes, Immutable)]  | 
469  |  | /// #[repr(C)]  | 
470  |  | /// struct SliceDst<T, U> { | 
471  |  | ///     t: T,  | 
472  |  | ///     u: [U],  | 
473  |  | /// }  | 
474  |  | ///  | 
475  |  | /// type Src = SliceDst<u32, u16>;  | 
476  |  | /// type Dst = SliceDst<u16, u8>;  | 
477  |  | ///  | 
478  |  | /// let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7];  | 
479  |  | /// let src = Src::mut_from_bytes(&mut bytes[..]).unwrap();  | 
480  |  | /// let dst: &mut Dst = transmute_mut!(src);  | 
481  |  | ///  | 
482  |  | /// assert_eq!(dst.t.as_bytes(), [0, 1]);  | 
483  |  | /// assert_eq!(dst.u, [2, 3, 4, 5, 6, 7]);  | 
484  |  | ///  | 
485  |  | /// assert_eq!(src.t.as_bytes(), [0, 1, 2, 3]);  | 
486  |  | /// assert_eq!(src.u.len(), 2);  | 
487  |  | /// assert_eq!(src.u.as_bytes(), [4, 5, 6, 7]);  | 
488  |  | ///  | 
489  |  | /// ```  | 
490  |  | #[macro_export]  | 
491  |  | macro_rules! transmute_mut { | 
492  |  |     ($e:expr) => {{ | 
493  |  |         // NOTE: This must be a macro (rather than a function with trait bounds)  | 
494  |  |         // because, for backwards-compatibility on v0.8.x, we use the autoref  | 
495  |  |         // specialization trick to dispatch to different `transmute_mut`  | 
496  |  |         // implementations: one which doesn't require `Src: KnownLayout + Dst:  | 
497  |  |         // KnownLayout` when `Src: Sized + Dst: Sized`, and one which requires  | 
498  |  |         // `KnownLayout` bounds otherwise.  | 
499  |  |  | 
500  |  |         // Ensure that the source type is a mutable reference.  | 
501  |  |         let e: &mut _ = $e;  | 
502  |  |  | 
503  |  |         #[allow(unused)]  | 
504  |  |         use $crate::util::macro_util::TransmuteMutDst as _;  | 
505  |  |         let t = $crate::util::macro_util::Wrap::new(e);  | 
506  |  |         t.transmute_mut()  | 
507  |  |     }}  | 
508  |  | }  | 
509  |  |  | 
510  |  | /// Conditionally transmutes a value of one type to a value of another type of  | 
511  |  | /// the same size.  | 
512  |  | ///  | 
513  |  | /// This macro behaves like an invocation of this function:  | 
514  |  | ///  | 
515  |  | /// ```ignore  | 
516  |  | /// fn try_transmute<Src, Dst>(src: Src) -> Result<Dst, ValidityError<Src, Dst>>  | 
517  |  | /// where  | 
518  |  | ///     Src: IntoBytes,  | 
519  |  | ///     Dst: TryFromBytes,  | 
520  |  | ///     size_of::<Src>() == size_of::<Dst>(),  | 
521  |  | /// { | 
522  |  | /// # /*  | 
523  |  | ///     ...  | 
524  |  | /// # */  | 
525  |  | /// }  | 
526  |  | /// ```  | 
527  |  | ///  | 
528  |  | /// However, unlike a function, this macro can only be invoked when the types of  | 
529  |  | /// `Src` and `Dst` are completely concrete. The types `Src` and `Dst` are  | 
530  |  | /// inferred from the calling context; they cannot be explicitly specified in  | 
531  |  | /// the macro invocation.  | 
532  |  | ///  | 
533  |  | /// Note that the `Src` produced by the expression `$e` will *not* be dropped.  | 
534  |  | /// Semantically, its bits will be copied into a new value of type `Dst`, the  | 
535  |  | /// original `Src` will be forgotten, and the value of type `Dst` will be  | 
536  |  | /// returned.  | 
537  |  | ///  | 
538  |  | /// # Examples  | 
539  |  | ///  | 
540  |  | /// ```  | 
541  |  | /// # use zerocopy::*;  | 
542  |  | /// // 0u8 → bool = false  | 
543  |  | /// assert_eq!(try_transmute!(0u8), Ok(false));  | 
544  |  | ///  | 
545  |  | /// // 1u8 → bool = true  | 
546  |  | ///  assert_eq!(try_transmute!(1u8), Ok(true));  | 
547  |  | ///  | 
548  |  | /// // 2u8 → bool = error  | 
549  |  | /// assert!(matches!(  | 
550  |  | ///     try_transmute!(2u8),  | 
551  |  | ///     Result::<bool, _>::Err(ValidityError { .. }) | 
552  |  | /// ));  | 
553  |  | /// ```  | 
554  |  | #[macro_export]  | 
555  |  | macro_rules! try_transmute { | 
556  |  |     ($e:expr) => {{ | 
557  |  |         // NOTE: This must be a macro (rather than a function with trait bounds)  | 
558  |  |         // because there's no way, in a generic context, to enforce that two  | 
559  |  |         // types have the same size. `core::mem::transmute` uses compiler magic  | 
560  |  |         // to enforce this so long as the types are concrete.  | 
561  |  |  | 
562  |  |         let e = $e;  | 
563  |  |         if false { | 
564  |  |             // Check that the sizes of the source and destination types are  | 
565  |  |             // equal.  | 
566  |  |  | 
567  |  |             // SAFETY: This code is never executed.  | 
568  |  |             Ok(unsafe { | 
569  |  |                 // Clippy: We can't annotate the types; this macro is designed  | 
570  |  |                 // to infer the types from the calling context.  | 
571  |  |                 #[allow(clippy::missing_transmute_annotations)]  | 
572  |  |                 $crate::util::macro_util::core_reexport::mem::transmute(e)  | 
573  |  |             })  | 
574  |  |         } else { | 
575  |  |             $crate::util::macro_util::try_transmute::<_, _>(e)  | 
576  |  |         }  | 
577  |  |     }}  | 
578  |  | }  | 
579  |  |  | 
580  |  | /// Conditionally transmutes a mutable or immutable reference of one type to an  | 
581  |  | /// immutable reference of another type of the same size and compatible  | 
582  |  | /// alignment.  | 
583  |  | ///  | 
584  |  | /// This macro behaves like an invocation of this function:  | 
585  |  | ///  | 
586  |  | /// ```ignore  | 
587  |  | /// fn try_transmute_ref<Src, Dst>(src: &Src) -> Result<&Dst, ValidityError<&Src, Dst>>  | 
588  |  | /// where  | 
589  |  | ///     Src: IntoBytes + Immutable,  | 
590  |  | ///     Dst: TryFromBytes + Immutable,  | 
591  |  | ///     size_of::<Src>() == size_of::<Dst>(),  | 
592  |  | ///     align_of::<Src>() >= align_of::<Dst>(),  | 
593  |  | /// { | 
594  |  | /// # /*  | 
595  |  | ///     ...  | 
596  |  | /// # */  | 
597  |  | /// }  | 
598  |  | /// ```  | 
599  |  | ///  | 
600  |  | /// However, unlike a function, this macro can only be invoked when the types of  | 
601  |  | /// `Src` and `Dst` are completely concrete. The types `Src` and `Dst` are  | 
602  |  | /// inferred from the calling context; they cannot be explicitly specified in  | 
603  |  | /// the macro invocation.  | 
604  |  | ///  | 
605  |  | /// # Examples  | 
606  |  | ///  | 
607  |  | /// ```  | 
608  |  | /// # use zerocopy::*;  | 
609  |  | /// // 0u8 → bool = false  | 
610  |  | /// assert_eq!(try_transmute_ref!(&0u8), Ok(&false));  | 
611  |  | ///  | 
612  |  | /// // 1u8 → bool = true  | 
613  |  | ///  assert_eq!(try_transmute_ref!(&1u8), Ok(&true));  | 
614  |  | ///  | 
615  |  | /// // 2u8 → bool = error  | 
616  |  | /// assert!(matches!(  | 
617  |  | ///     try_transmute_ref!(&2u8),  | 
618  |  | ///     Result::<&bool, _>::Err(ValidityError { .. }) | 
619  |  | /// ));  | 
620  |  | /// ```  | 
621  |  | ///  | 
622  |  | /// # Alignment increase error message  | 
623  |  | ///  | 
624  |  | /// Because of limitations on macros, the error message generated when  | 
625  |  | /// `try_transmute_ref!` is used to transmute from a type of lower alignment to  | 
626  |  | /// a type of higher alignment is somewhat confusing. For example, the following  | 
627  |  | /// code:  | 
628  |  | ///  | 
629  |  | /// ```compile_fail  | 
630  |  | /// let increase_alignment: Result<&u16, _> = zerocopy::try_transmute_ref!(&[0u8; 2]);  | 
631  |  | /// ```  | 
632  |  | ///  | 
633  |  | /// ...generates the following error:  | 
634  |  | ///  | 
635  |  | /// ```text  | 
636  |  | /// error[E0512]: cannot transmute between types of different sizes, or dependently-sized types  | 
637  |  | ///  --> example.rs:1:47  | 
638  |  | ///   |  | 
639  |  | /// 1 |     let increase_alignment: Result<&u16, _> = zerocopy::try_transmute_ref!(&[0u8; 2]);  | 
640  |  | ///   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  | 
641  |  | ///   |  | 
642  |  | ///   = note: source type: `AlignOf<[u8; 2]>` (8 bits)  | 
643  |  | ///   = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)  | 
644  |  | ///   = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `zerocopy::try_transmute_ref` (in Nightly builds, run with -Z macro-backtrace for more info)/// ```  | 
645  |  | /// ```  | 
646  |  | ///  | 
647  |  | /// This is saying that `max(align_of::<T>(), align_of::<U>()) !=  | 
648  |  | /// align_of::<T>()`, which is equivalent to `align_of::<T>() <  | 
649  |  | /// align_of::<U>()`.  | 
650  |  | #[macro_export]  | 
651  |  | macro_rules! try_transmute_ref { | 
652  |  |     ($e:expr) => {{ | 
653  |  |         // NOTE: This must be a macro (rather than a function with trait bounds)  | 
654  |  |         // because there's no way, in a generic context, to enforce that two  | 
655  |  |         // types have the same size. `core::mem::transmute` uses compiler magic  | 
656  |  |         // to enforce this so long as the types are concrete.  | 
657  |  |  | 
658  |  |         // Ensure that the source type is a reference or a mutable reference  | 
659  |  |         // (note that mutable references are implicitly reborrowed here).  | 
660  |  |         let e: &_ = $e;  | 
661  |  |  | 
662  |  |         #[allow(unreachable_code, unused, clippy::diverging_sub_expression)]  | 
663  |  |         if false { | 
664  |  |             // This branch, though never taken, ensures that `size_of::<T>() ==  | 
665  |  |             // size_of::<U>()` and that that `align_of::<T>() >=  | 
666  |  |             // align_of::<U>()`.  | 
667  |  |  | 
668  |  |             // `t` is inferred to have type `T` because it's assigned to `e` (of  | 
669  |  |             // type `&T`) as `&t`.  | 
670  |  |             let mut t = loop {}; | 
671  |  |             e = &t;  | 
672  |  |  | 
673  |  |             // `u` is inferred to have type `U` because it's used as `Ok(&u)` as  | 
674  |  |             // the value returned from this branch.  | 
675  |  |             let u;  | 
676  |  |  | 
677  |  |             $crate::assert_size_eq!(t, u);  | 
678  |  |             $crate::assert_align_gt_eq!(t, u);  | 
679  |  |  | 
680  |  |             Ok(&u)  | 
681  |  |         } else { | 
682  |  |             $crate::util::macro_util::try_transmute_ref::<_, _>(e)  | 
683  |  |         }  | 
684  |  |     }}  | 
685  |  | }  | 
686  |  |  | 
687  |  | /// Conditionally transmutes a mutable reference of one type to a mutable  | 
688  |  | /// reference of another type of the same size and compatible alignment.  | 
689  |  | ///  | 
690  |  | /// This macro behaves like an invocation of this function:  | 
691  |  | ///  | 
692  |  | /// ```ignore  | 
693  |  | /// fn try_transmute_mut<Src, Dst>(src: &mut Src) -> Result<&mut Dst, ValidityError<&mut Src, Dst>>  | 
694  |  | /// where  | 
695  |  | ///     Src: FromBytes + IntoBytes,  | 
696  |  | ///     Dst: TryFromBytes + IntoBytes,  | 
697  |  | ///     size_of::<Src>() == size_of::<Dst>(),  | 
698  |  | ///     align_of::<Src>() >= align_of::<Dst>(),  | 
699  |  | /// { | 
700  |  | /// # /*  | 
701  |  | ///     ...  | 
702  |  | /// # */  | 
703  |  | /// }  | 
704  |  | /// ```  | 
705  |  | ///  | 
706  |  | /// However, unlike a function, this macro can only be invoked when the types of  | 
707  |  | /// `Src` and `Dst` are completely concrete. The types `Src` and `Dst` are  | 
708  |  | /// inferred from the calling context; they cannot be explicitly specified in  | 
709  |  | /// the macro invocation.  | 
710  |  | ///  | 
711  |  | /// # Examples  | 
712  |  | ///  | 
713  |  | /// ```  | 
714  |  | /// # use zerocopy::*;  | 
715  |  | /// // 0u8 → bool = false  | 
716  |  | /// let src = &mut 0u8;  | 
717  |  | /// assert_eq!(try_transmute_mut!(src), Ok(&mut false));  | 
718  |  | ///  | 
719  |  | /// // 1u8 → bool = true  | 
720  |  | /// let src = &mut 1u8;  | 
721  |  | ///  assert_eq!(try_transmute_mut!(src), Ok(&mut true));  | 
722  |  | ///  | 
723  |  | /// // 2u8 → bool = error  | 
724  |  | /// let src = &mut 2u8;  | 
725  |  | /// assert!(matches!(  | 
726  |  | ///     try_transmute_mut!(src),  | 
727  |  | ///     Result::<&mut bool, _>::Err(ValidityError { .. }) | 
728  |  | /// ));  | 
729  |  | /// ```  | 
730  |  | ///  | 
731  |  | /// # Alignment increase error message  | 
732  |  | ///  | 
733  |  | /// Because of limitations on macros, the error message generated when  | 
734  |  | /// `try_transmute_ref!` is used to transmute from a type of lower alignment to  | 
735  |  | /// a type of higher alignment is somewhat confusing. For example, the following  | 
736  |  | /// code:  | 
737  |  | ///  | 
738  |  | /// ```compile_fail  | 
739  |  | /// let src = &mut [0u8; 2];  | 
740  |  | /// let increase_alignment: Result<&mut u16, _> = zerocopy::try_transmute_mut!(src);  | 
741  |  | /// ```  | 
742  |  | ///  | 
743  |  | /// ...generates the following error:  | 
744  |  | ///  | 
745  |  | /// ```text  | 
746  |  | /// error[E0512]: cannot transmute between types of different sizes, or dependently-sized types  | 
747  |  | ///  --> example.rs:2:51  | 
748  |  | ///   |  | 
749  |  | /// 2 |     let increase_alignment: Result<&mut u16, _> = zerocopy::try_transmute_mut!(src);  | 
750  |  | ///   |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  | 
751  |  | ///   |  | 
752  |  | ///   = note: source type: `AlignOf<[u8; 2]>` (8 bits)  | 
753  |  | ///   = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)  | 
754  |  | ///   = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `zerocopy::try_transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)  | 
755  |  | /// ```  | 
756  |  | ///  | 
757  |  | /// This is saying that `max(align_of::<T>(), align_of::<U>()) !=  | 
758  |  | /// align_of::<T>()`, which is equivalent to `align_of::<T>() <  | 
759  |  | /// align_of::<U>()`.  | 
760  |  | #[macro_export]  | 
761  |  | macro_rules! try_transmute_mut { | 
762  |  |     ($e:expr) => {{ | 
763  |  |         // NOTE: This must be a macro (rather than a function with trait bounds)  | 
764  |  |         // because there's no way, in a generic context, to enforce that two  | 
765  |  |         // types have the same size. `core::mem::transmute` uses compiler magic  | 
766  |  |         // to enforce this so long as the types are concrete.  | 
767  |  |  | 
768  |  |         // Ensure that the source type is a mutable reference.  | 
769  |  |         let e: &mut _ = $e;  | 
770  |  |  | 
771  |  |         #[allow(unreachable_code, unused, clippy::diverging_sub_expression)]  | 
772  |  |         if false { | 
773  |  |             // This branch, though never taken, ensures that `size_of::<T>() ==  | 
774  |  |             // size_of::<U>()` and that that `align_of::<T>() >=  | 
775  |  |             // align_of::<U>()`.  | 
776  |  |  | 
777  |  |             // `t` is inferred to have type `T` because it's assigned to `e` (of  | 
778  |  |             // type `&mut T`) as `&mut t`.  | 
779  |  |             let mut t = loop {}; | 
780  |  |             e = &mut t;  | 
781  |  |  | 
782  |  |             // `u` is inferred to have type `U` because it's used as `Ok(&mut  | 
783  |  |             // u)` as the value returned from this branch.  | 
784  |  |             let u;  | 
785  |  |  | 
786  |  |             $crate::assert_size_eq!(t, u);  | 
787  |  |             $crate::assert_align_gt_eq!(t, u);  | 
788  |  |  | 
789  |  |             Ok(&mut u)  | 
790  |  |         } else { | 
791  |  |             $crate::util::macro_util::try_transmute_mut::<_, _>(e)  | 
792  |  |         }  | 
793  |  |     }}  | 
794  |  | }  | 
795  |  |  | 
796  |  | /// Includes a file and safely transmutes it to a value of an arbitrary type.  | 
797  |  | ///  | 
798  |  | /// The file will be included as a byte array, `[u8; N]`, which will be  | 
799  |  | /// transmuted to another type, `T`. `T` is inferred from the calling context,  | 
800  |  | /// and must implement [`FromBytes`].  | 
801  |  | ///  | 
802  |  | /// The file is located relative to the current file (similarly to how modules  | 
803  |  | /// are found). The provided path is interpreted in a platform-specific way at  | 
804  |  | /// compile time. So, for instance, an invocation with a Windows path containing  | 
805  |  | /// backslashes `\` would not compile correctly on Unix.  | 
806  |  | ///  | 
807  |  | /// `include_value!` is ignorant of byte order. For byte order-aware types, see  | 
808  |  | /// the [`byteorder`] module.  | 
809  |  | ///  | 
810  |  | /// [`FromBytes`]: crate::FromBytes  | 
811  |  | /// [`byteorder`]: crate::byteorder  | 
812  |  | ///  | 
813  |  | /// # Examples  | 
814  |  | ///  | 
815  |  | /// Assume there are two files in the same directory with the following  | 
816  |  | /// contents:  | 
817  |  | ///  | 
818  |  | /// File `data` (no trailing newline):  | 
819  |  | ///  | 
820  |  | /// ```text  | 
821  |  | /// abcd  | 
822  |  | /// ```  | 
823  |  | ///  | 
824  |  | /// File `main.rs`:  | 
825  |  | ///  | 
826  |  | /// ```rust  | 
827  |  | /// use zerocopy::include_value;  | 
828  |  | /// # macro_rules! include_value { | 
829  |  | /// # ($file:expr) => { zerocopy::include_value!(concat!("../testdata/include_value/", $file)) }; | 
830  |  | /// # }  | 
831  |  | ///  | 
832  |  | /// fn main() { | 
833  |  | ///     let as_u32: u32 = include_value!("data"); | 
834  |  | ///     assert_eq!(as_u32, u32::from_ne_bytes([b'a', b'b', b'c', b'd']));  | 
835  |  | ///     let as_i32: i32 = include_value!("data"); | 
836  |  | ///     assert_eq!(as_i32, i32::from_ne_bytes([b'a', b'b', b'c', b'd']));  | 
837  |  | /// }  | 
838  |  | /// ```  | 
839  |  | ///  | 
840  |  | /// # Use in `const` contexts  | 
841  |  | ///  | 
842  |  | /// This macro can be invoked in `const` contexts.  | 
843  |  | #[doc(alias("include_bytes", "include_data", "include_type"))] | 
844  |  | #[macro_export]  | 
845  |  | macro_rules! include_value { | 
846  |  |     ($file:expr $(,)?) => { | 
847  |  |         $crate::transmute!(*::core::include_bytes!($file))  | 
848  |  |     };  | 
849  |  | }  | 
850  |  |  | 
851  |  | #[doc(hidden)]  | 
852  |  | #[macro_export]  | 
853  |  | macro_rules! cryptocorrosion_derive_traits { | 
854  |  |     (  | 
855  |  |         #[repr($repr:ident)]  | 
856  |  |         $(#[$attr:meta])*  | 
857  |  |         $vis:vis struct $name:ident $(<$($tyvar:ident),*>)?  | 
858  |  |         $(  | 
859  |  |             (  | 
860  |  |                 $($tuple_field_vis:vis $tuple_field_ty:ty),*  | 
861  |  |             );  | 
862  |  |         )?  | 
863  |  |  | 
864  |  |         $(  | 
865  |  |             { | 
866  |  |                 $($field_vis:vis $field_name:ident: $field_ty:ty,)*  | 
867  |  |             }  | 
868  |  |         )?  | 
869  |  |     ) => { | 
870  |  |         $crate::cryptocorrosion_derive_traits!(@assert_allowed_struct_repr #[repr($repr)]);  | 
871  |  |  | 
872  |  |         $(#[$attr])*  | 
873  |  |         #[repr($repr)]  | 
874  |  |         $vis struct $name $(<$($tyvar),*>)?  | 
875  |  |         $(  | 
876  |  |             (  | 
877  |  |                 $($tuple_field_vis $tuple_field_ty),*  | 
878  |  |             );  | 
879  |  |         )?  | 
880  |  |  | 
881  |  |         $(  | 
882  |  |             { | 
883  |  |                 $($field_vis $field_name: $field_ty,)*  | 
884  |  |             }  | 
885  |  |         )?  | 
886  |  |  | 
887  |  |         // SAFETY: See inline.  | 
888  |  |         unsafe impl $(<$($tyvar),*>)? $crate::TryFromBytes for $name$(<$($tyvar),*>)?  | 
889  |  |         where  | 
890  |  |             $(  | 
891  |  |                 $($tuple_field_ty: $crate::FromBytes,)*  | 
892  |  |             )?  | 
893  |  |  | 
894  |  |             $(  | 
895  |  |                 $($field_ty: $crate::FromBytes,)*  | 
896  |  |             )?  | 
897  |  |         { | 
898  |  |             fn is_bit_valid<A>(_c: $crate::Maybe<'_, Self, A>) -> bool  | 
899  |  |             where  | 
900  |  |                 A: $crate::pointer::invariant::Reference  | 
901  |  |             { | 
902  |  |                 // SAFETY: This macro only accepts `#[repr(C)]` and  | 
903  |  |                 // `#[repr(transparent)]` structs, and this `impl` block  | 
904  |  |                 // requires all field types to be `FromBytes`. Thus, all  | 
905  |  |                 // initialized byte sequences constitutes valid instances of  | 
906  |  |                 // `Self`.  | 
907  |  |                 true  | 
908  |  |             }  | 
909  |  |  | 
910  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
911  |  |         }  | 
912  |  |  | 
913  |  |         // SAFETY: This macro only accepts `#[repr(C)]` and  | 
914  |  |         // `#[repr(transparent)]` structs, and this `impl` block requires all  | 
915  |  |         // field types to be `FromBytes`, which is a sub-trait of `FromZeros`.  | 
916  |  |         unsafe impl $(<$($tyvar),*>)? $crate::FromZeros for $name$(<$($tyvar),*>)?  | 
917  |  |         where  | 
918  |  |             $(  | 
919  |  |                 $($tuple_field_ty: $crate::FromBytes,)*  | 
920  |  |             )?  | 
921  |  |  | 
922  |  |             $(  | 
923  |  |                 $($field_ty: $crate::FromBytes,)*  | 
924  |  |             )?  | 
925  |  |         { | 
926  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
927  |  |         }  | 
928  |  |  | 
929  |  |         // SAFETY: This macro only accepts `#[repr(C)]` and  | 
930  |  |         // `#[repr(transparent)]` structs, and this `impl` block requires all  | 
931  |  |         // field types to be `FromBytes`.  | 
932  |  |         unsafe impl $(<$($tyvar),*>)? $crate::FromBytes for $name$(<$($tyvar),*>)?  | 
933  |  |         where  | 
934  |  |             $(  | 
935  |  |                 $($tuple_field_ty: $crate::FromBytes,)*  | 
936  |  |             )?  | 
937  |  |  | 
938  |  |             $(  | 
939  |  |                 $($field_ty: $crate::FromBytes,)*  | 
940  |  |             )?  | 
941  |  |         { | 
942  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
943  |  |         }  | 
944  |  |  | 
945  |  |         // SAFETY: This macro only accepts `#[repr(C)]` and  | 
946  |  |         // `#[repr(transparent)]` structs, this `impl` block requires all field  | 
947  |  |         // types to be `IntoBytes`, and a padding check is used to ensures that  | 
948  |  |         // there are no padding bytes.  | 
949  |  |         unsafe impl $(<$($tyvar),*>)? $crate::IntoBytes for $name$(<$($tyvar),*>)?  | 
950  |  |         where  | 
951  |  |             $(  | 
952  |  |                 $($tuple_field_ty: $crate::IntoBytes,)*  | 
953  |  |             )?  | 
954  |  |  | 
955  |  |             $(  | 
956  |  |                 $($field_ty: $crate::IntoBytes,)*  | 
957  |  |             )?  | 
958  |  |  | 
959  |  |             (): $crate::util::macro_util::PaddingFree<  | 
960  |  |                 Self,  | 
961  |  |                 { | 
962  |  |                     $crate::cryptocorrosion_derive_traits!(  | 
963  |  |                         @struct_padding_check #[repr($repr)]  | 
964  |  |                         $(($($tuple_field_ty),*))?  | 
965  |  |                         $({$($field_ty),*})? | 
966  |  |                     )  | 
967  |  |                 },  | 
968  |  |             >,  | 
969  |  |         { | 
970  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
971  |  |         }  | 
972  |  |  | 
973  |  |         // SAFETY: This macro only accepts `#[repr(C)]` and  | 
974  |  |         // `#[repr(transparent)]` structs, and this `impl` block requires all  | 
975  |  |         // field types to be `Immutable`.  | 
976  |  |         unsafe impl $(<$($tyvar),*>)? $crate::Immutable for $name$(<$($tyvar),*>)?  | 
977  |  |         where  | 
978  |  |             $(  | 
979  |  |                 $($tuple_field_ty: $crate::Immutable,)*  | 
980  |  |             )?  | 
981  |  |  | 
982  |  |             $(  | 
983  |  |                 $($field_ty: $crate::Immutable,)*  | 
984  |  |             )?  | 
985  |  |         { | 
986  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
987  |  |         }  | 
988  |  |     };  | 
989  |  |     (@assert_allowed_struct_repr #[repr(transparent)]) => {}; | 
990  |  |     (@assert_allowed_struct_repr #[repr(C)]) => {}; | 
991  |  |     (@assert_allowed_struct_repr #[$_attr:meta]) => { | 
992  |  |         compile_error!("repr must be `#[repr(transparent)]` or `#[repr(C)]`"); | 
993  |  |     };  | 
994  |  |     (  | 
995  |  |         @struct_padding_check #[repr(transparent)]  | 
996  |  |         $(($($tuple_field_ty:ty),*))?  | 
997  |  |         $({$($field_ty:ty),*})? | 
998  |  |     ) => { | 
999  |  |         // SAFETY: `#[repr(transparent)]` structs cannot have the same layout as  | 
1000  |  |         // their single non-zero-sized field, and so cannot have any padding  | 
1001  |  |         // outside of that field.  | 
1002  |  |         0  | 
1003  |  |     };  | 
1004  |  |     (  | 
1005  |  |         @struct_padding_check #[repr(C)]  | 
1006  |  |         $(($($tuple_field_ty:ty),*))?  | 
1007  |  |         $({$($field_ty:ty),*})? | 
1008  |  |     ) => { | 
1009  |  |         $crate::struct_padding!(  | 
1010  |  |             Self,  | 
1011  |  |             [  | 
1012  |  |                 $($($tuple_field_ty),*)?  | 
1013  |  |                 $($($field_ty),*)?  | 
1014  |  |             ]  | 
1015  |  |         )  | 
1016  |  |     };  | 
1017  |  |     (  | 
1018  |  |         #[repr(C)]  | 
1019  |  |         $(#[$attr:meta])*  | 
1020  |  |         $vis:vis union $name:ident { | 
1021  |  |             $(  | 
1022  |  |                 $field_name:ident: $field_ty:ty,  | 
1023  |  |             )*  | 
1024  |  |         }  | 
1025  |  |     ) => { | 
1026  |  |         $(#[$attr])*  | 
1027  |  |         #[repr(C)]  | 
1028  |  |         $vis union $name { | 
1029  |  |             $(  | 
1030  |  |                 $field_name: $field_ty,  | 
1031  |  |             )*  | 
1032  |  |         }  | 
1033  |  |  | 
1034  |  |         // SAFETY: See inline.  | 
1035  |  |         unsafe impl $crate::TryFromBytes for $name  | 
1036  |  |         where  | 
1037  |  |             $(  | 
1038  |  |                 $field_ty: $crate::FromBytes,  | 
1039  |  |             )*  | 
1040  |  |         { | 
1041  |  |             fn is_bit_valid<A>(_c: $crate::Maybe<'_, Self, A>) -> bool  | 
1042  |  |             where  | 
1043  |  |                 A: $crate::pointer::invariant::Reference  | 
1044  |  |             { | 
1045  |  |                 // SAFETY: This macro only accepts `#[repr(C)]` unions, and this  | 
1046  |  |                 // `impl` block requires all field types to be `FromBytes`.  | 
1047  |  |                 // Thus, all initialized byte sequences constitutes valid  | 
1048  |  |                 // instances of `Self`.  | 
1049  |  |                 true  | 
1050  |  |             }  | 
1051  |  |  | 
1052  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
1053  |  |         }  | 
1054  |  |  | 
1055  |  |         // SAFETY: This macro only accepts `#[repr(C)]` unions, and this `impl`  | 
1056  |  |         // block requires all field types to be `FromBytes`, which is a  | 
1057  |  |         // sub-trait of `FromZeros`.  | 
1058  |  |         unsafe impl $crate::FromZeros for $name  | 
1059  |  |         where  | 
1060  |  |             $(  | 
1061  |  |                 $field_ty: $crate::FromBytes,  | 
1062  |  |             )*  | 
1063  |  |         { | 
1064  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
1065  |  |         }  | 
1066  |  |  | 
1067  |  |         // SAFETY: This macro only accepts `#[repr(C)]` unions, and this `impl`  | 
1068  |  |         // block requires all field types to be `FromBytes`.  | 
1069  |  |         unsafe impl $crate::FromBytes for $name  | 
1070  |  |         where  | 
1071  |  |             $(  | 
1072  |  |                 $field_ty: $crate::FromBytes,  | 
1073  |  |             )*  | 
1074  |  |         { | 
1075  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
1076  |  |         }  | 
1077  |  |  | 
1078  |  |         // SAFETY: This macro only accepts `#[repr(C)]` unions, this `impl`  | 
1079  |  |         // block requires all field types to be `IntoBytes`, and a padding check  | 
1080  |  |         // is used to ensures that there are no padding bytes before or after  | 
1081  |  |         // any field.  | 
1082  |  |         unsafe impl $crate::IntoBytes for $name  | 
1083  |  |         where  | 
1084  |  |             $(  | 
1085  |  |                 $field_ty: $crate::IntoBytes,  | 
1086  |  |             )*  | 
1087  |  |             (): $crate::util::macro_util::PaddingFree<  | 
1088  |  |                 Self,  | 
1089  |  |                 { | 
1090  |  |                     $crate::union_padding!(  | 
1091  |  |                         Self,  | 
1092  |  |                         [$($field_ty),*]  | 
1093  |  |                     )  | 
1094  |  |                 },  | 
1095  |  |             >,  | 
1096  |  |         { | 
1097  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
1098  |  |         }  | 
1099  |  |  | 
1100  |  |         // SAFETY: This macro only accepts `#[repr(C)]` unions, and this `impl`  | 
1101  |  |         // block requires all field types to be `Immutable`.  | 
1102  |  |         unsafe impl $crate::Immutable for $name  | 
1103  |  |         where  | 
1104  |  |             $(  | 
1105  |  |                 $field_ty: $crate::Immutable,  | 
1106  |  |             )*  | 
1107  |  |         { | 
1108  |  |             fn only_derive_is_allowed_to_implement_this_trait() {} | 
1109  |  |         }  | 
1110  |  |     };  | 
1111  |  | }  | 
1112  |  |  | 
1113  |  | #[cfg(test)]  | 
1114  |  | mod tests { | 
1115  |  |     use crate::{ | 
1116  |  |         byteorder::native_endian::{U16, U32}, | 
1117  |  |         util::testutil::*,  | 
1118  |  |         *,  | 
1119  |  |     };  | 
1120  |  |  | 
1121  |  |     #[derive(KnownLayout, Immutable, FromBytes, IntoBytes, PartialEq, Debug)]  | 
1122  |  |     #[repr(C)]  | 
1123  |  |     struct SliceDst<T, U> { | 
1124  |  |         a: T,  | 
1125  |  |         b: [U],  | 
1126  |  |     }  | 
1127  |  |  | 
1128  |  |     #[test]  | 
1129  |  |     fn test_transmute() { | 
1130  |  |         // Test that memory is transmuted as expected.  | 
1131  |  |         let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];  | 
1132  |  |         let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];  | 
1133  |  |         let x: [[u8; 2]; 4] = transmute!(array_of_u8s);  | 
1134  |  |         assert_eq!(x, array_of_arrays);  | 
1135  |  |         let x: [u8; 8] = transmute!(array_of_arrays);  | 
1136  |  |         assert_eq!(x, array_of_u8s);  | 
1137  |  |  | 
1138  |  |         // Test that memory is transmuted as expected when shrinking.  | 
1139  |  |         let x: [[u8; 2]; 3] = transmute!(#![allow(shrink)] array_of_u8s);  | 
1140  |  |         assert_eq!(x, [[0u8, 1], [2, 3], [4, 5]]);  | 
1141  |  |  | 
1142  |  |         // Test that the source expression's value is forgotten rather than  | 
1143  |  |         // dropped.  | 
1144  |  |         #[derive(IntoBytes)]  | 
1145  |  |         #[repr(transparent)]  | 
1146  |  |         struct PanicOnDrop(());  | 
1147  |  |         impl Drop for PanicOnDrop { | 
1148  |  |             fn drop(&mut self) { | 
1149  |  |                 panic!("PanicOnDrop::drop"); | 
1150  |  |             }  | 
1151  |  |         }  | 
1152  |  |         #[allow(clippy::let_unit_value)]  | 
1153  |  |         let _: () = transmute!(PanicOnDrop(()));  | 
1154  |  |         #[allow(clippy::let_unit_value)]  | 
1155  |  |         let _: () = transmute!(#![allow(shrink)] PanicOnDrop(()));  | 
1156  |  |  | 
1157  |  |         // Test that `transmute!` is legal in a const context.  | 
1158  |  |         const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];  | 
1159  |  |         const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];  | 
1160  |  |         const X: [[u8; 2]; 4] = transmute!(ARRAY_OF_U8S);  | 
1161  |  |         assert_eq!(X, ARRAY_OF_ARRAYS);  | 
1162  |  |         const X_SHRINK: [[u8; 2]; 3] = transmute!(#![allow(shrink)] ARRAY_OF_U8S);  | 
1163  |  |         assert_eq!(X_SHRINK, [[0u8, 1], [2, 3], [4, 5]]);  | 
1164  |  |  | 
1165  |  |         // Test that `transmute!` works with `!Immutable` types.  | 
1166  |  |         let x: usize = transmute!(UnsafeCell::new(1usize));  | 
1167  |  |         assert_eq!(x, 1);  | 
1168  |  |         let x: UnsafeCell<usize> = transmute!(1usize);  | 
1169  |  |         assert_eq!(x.into_inner(), 1);  | 
1170  |  |         let x: UnsafeCell<isize> = transmute!(UnsafeCell::new(1usize));  | 
1171  |  |         assert_eq!(x.into_inner(), 1);  | 
1172  |  |     }  | 
1173  |  |  | 
1174  |  |     // A `Sized` type which doesn't implement `KnownLayout` (it is "not  | 
1175  |  |     // `KnownLayout`", or `Nkl`).  | 
1176  |  |     //  | 
1177  |  |     // This permits us to test that `transmute_ref!` and `transmute_mut!` work  | 
1178  |  |     // for types which are `Sized + !KnownLayout`. When we added support for  | 
1179  |  |     // slice DSTs in #1924, this new support relied on `KnownLayout`, but we  | 
1180  |  |     // need to make sure to remain backwards-compatible with code which uses  | 
1181  |  |     // these macros with types which are `!KnownLayout`.  | 
1182  |  |     #[derive(FromBytes, IntoBytes, Immutable, PartialEq, Eq, Debug)]  | 
1183  |  |     #[repr(transparent)]  | 
1184  |  |     struct Nkl<T>(T);  | 
1185  |  |  | 
1186  |  |     #[test]  | 
1187  |  |     fn test_transmute_ref() { | 
1188  |  |         // Test that memory is transmuted as expected.  | 
1189  |  |         let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];  | 
1190  |  |         let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];  | 
1191  |  |         let x: &[[u8; 2]; 4] = transmute_ref!(&array_of_u8s);  | 
1192  |  |         assert_eq!(*x, array_of_arrays);  | 
1193  |  |         let x: &[u8; 8] = transmute_ref!(&array_of_arrays);  | 
1194  |  |         assert_eq!(*x, array_of_u8s);  | 
1195  |  |  | 
1196  |  |         // Test that `transmute_ref!` is legal in a const context.  | 
1197  |  |         const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];  | 
1198  |  |         const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];  | 
1199  |  |         #[allow(clippy::redundant_static_lifetimes)]  | 
1200  |  |         const X: &'static [[u8; 2]; 4] = transmute_ref!(&ARRAY_OF_U8S);  | 
1201  |  |         assert_eq!(*X, ARRAY_OF_ARRAYS);  | 
1202  |  |  | 
1203  |  |         // Before 1.61.0, we can't define the `const fn transmute_ref` function  | 
1204  |  |         // that we do on and after 1.61.0.  | 
1205  |  |         #[cfg(not(zerocopy_generic_bounds_in_const_fn_1_61_0))]  | 
1206  |  |         { | 
1207  |  |             // Test that `transmute_ref!` supports non-`KnownLayout` `Sized` types.  | 
1208  |  |             const ARRAY_OF_NKL_U8S: Nkl<[u8; 8]> = Nkl([0u8, 1, 2, 3, 4, 5, 6, 7]);  | 
1209  |  |             const ARRAY_OF_NKL_ARRAYS: Nkl<[[u8; 2]; 4]> = Nkl([[0, 1], [2, 3], [4, 5], [6, 7]]);  | 
1210  |  |             const X_NKL: &Nkl<[[u8; 2]; 4]> = transmute_ref!(&ARRAY_OF_NKL_U8S);  | 
1211  |  |             assert_eq!(*X_NKL, ARRAY_OF_NKL_ARRAYS);  | 
1212  |  |         }  | 
1213  |  |  | 
1214  |  |         #[cfg(zerocopy_generic_bounds_in_const_fn_1_61_0)]  | 
1215  |  |         { | 
1216  |  |             // Call through a generic function to make sure our autoref  | 
1217  |  |             // specialization trick works even when types are generic.  | 
1218  |  |             const fn transmute_ref<T, U>(t: &T) -> &U  | 
1219  |  |             where  | 
1220  |  |                 T: IntoBytes + Immutable,  | 
1221  |  |                 U: FromBytes + Immutable,  | 
1222  |  |             { | 
1223  |  |                 transmute_ref!(t)  | 
1224  |  |             }  | 
1225  |  |  | 
1226  |  |             // Test that `transmute_ref!` supports non-`KnownLayout` `Sized` types.  | 
1227  |  |             const ARRAY_OF_NKL_U8S: Nkl<[u8; 8]> = Nkl([0u8, 1, 2, 3, 4, 5, 6, 7]);  | 
1228  |  |             const ARRAY_OF_NKL_ARRAYS: Nkl<[[u8; 2]; 4]> = Nkl([[0, 1], [2, 3], [4, 5], [6, 7]]);  | 
1229  |  |             const X_NKL: &Nkl<[[u8; 2]; 4]> = transmute_ref(&ARRAY_OF_NKL_U8S);  | 
1230  |  |             assert_eq!(*X_NKL, ARRAY_OF_NKL_ARRAYS);  | 
1231  |  |         }  | 
1232  |  |  | 
1233  |  |         // Test that `transmute_ref!` works on slice DSTs in and that memory is  | 
1234  |  |         // transmuted as expected.  | 
1235  |  |         let slice_dst_of_u8s =  | 
1236  |  |             SliceDst::<U16, [u8; 2]>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();  | 
1237  |  |         let slice_dst_of_u16s =  | 
1238  |  |             SliceDst::<U16, U16>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();  | 
1239  |  |         let x: &SliceDst<U16, U16> = transmute_ref!(slice_dst_of_u8s);  | 
1240  |  |         assert_eq!(x, slice_dst_of_u16s);  | 
1241  |  |  | 
1242  |  |         let slice_dst_of_u8s =  | 
1243  |  |             SliceDst::<U16, u8>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();  | 
1244  |  |         let x: &[u8] = transmute_ref!(slice_dst_of_u8s);  | 
1245  |  |         assert_eq!(x, [0, 1, 2, 3, 4, 5]);  | 
1246  |  |  | 
1247  |  |         let x: &[u8] = transmute_ref!(slice_dst_of_u16s);  | 
1248  |  |         assert_eq!(x, [0, 1, 2, 3, 4, 5]);  | 
1249  |  |  | 
1250  |  |         let x: &[U16] = transmute_ref!(slice_dst_of_u16s);  | 
1251  |  |         let slice_of_u16s: &[U16] = <[U16]>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();  | 
1252  |  |         assert_eq!(x, slice_of_u16s);  | 
1253  |  |  | 
1254  |  |         // Test that transmuting from a type with larger trailing slice offset  | 
1255  |  |         // and larger trailing slice element works.  | 
1256  |  |         let bytes = &[0, 1, 2, 3, 4, 5, 6, 7][..];  | 
1257  |  |         let slice_dst_big = SliceDst::<U32, U16>::ref_from_bytes(bytes).unwrap();  | 
1258  |  |         let slice_dst_small = SliceDst::<U16, u8>::ref_from_bytes(bytes).unwrap();  | 
1259  |  |         let x: &SliceDst<U16, u8> = transmute_ref!(slice_dst_big);  | 
1260  |  |         assert_eq!(x, slice_dst_small);  | 
1261  |  |  | 
1262  |  |         // Test that it's legal to transmute a reference while shrinking the  | 
1263  |  |         // lifetime (note that `X` has the lifetime `'static`).  | 
1264  |  |         let x: &[u8; 8] = transmute_ref!(X);  | 
1265  |  |         assert_eq!(*x, ARRAY_OF_U8S);  | 
1266  |  |  | 
1267  |  |         // Test that `transmute_ref!` supports decreasing alignment.  | 
1268  |  |         let u = AU64(0);  | 
1269  |  |         let array = [0, 0, 0, 0, 0, 0, 0, 0];  | 
1270  |  |         let x: &[u8; 8] = transmute_ref!(&u);  | 
1271  |  |         assert_eq!(*x, array);  | 
1272  |  |  | 
1273  |  |         // Test that a mutable reference can be turned into an immutable one.  | 
1274  |  |         let mut x = 0u8;  | 
1275  |  |         #[allow(clippy::useless_transmute)]  | 
1276  |  |         let y: &u8 = transmute_ref!(&mut x);  | 
1277  |  |         assert_eq!(*y, 0);  | 
1278  |  |     }  | 
1279  |  |  | 
1280  |  |     #[test]  | 
1281  |  |     fn test_try_transmute() { | 
1282  |  |         // Test that memory is transmuted with `try_transmute` as expected.  | 
1283  |  |         let array_of_bools = [false, true, false, true, false, true, false, true];  | 
1284  |  |         let array_of_arrays = [[0, 1], [0, 1], [0, 1], [0, 1]];  | 
1285  |  |         let x: Result<[[u8; 2]; 4], _> = try_transmute!(array_of_bools);  | 
1286  |  |         assert_eq!(x, Ok(array_of_arrays));  | 
1287  |  |         let x: Result<[bool; 8], _> = try_transmute!(array_of_arrays);  | 
1288  |  |         assert_eq!(x, Ok(array_of_bools));  | 
1289  |  |  | 
1290  |  |         // Test that `try_transmute!` works with `!Immutable` types.  | 
1291  |  |         let x: Result<usize, _> = try_transmute!(UnsafeCell::new(1usize));  | 
1292  |  |         assert_eq!(x.unwrap(), 1);  | 
1293  |  |         let x: Result<UnsafeCell<usize>, _> = try_transmute!(1usize);  | 
1294  |  |         assert_eq!(x.unwrap().into_inner(), 1);  | 
1295  |  |         let x: Result<UnsafeCell<isize>, _> = try_transmute!(UnsafeCell::new(1usize));  | 
1296  |  |         assert_eq!(x.unwrap().into_inner(), 1);  | 
1297  |  |  | 
1298  |  |         #[derive(FromBytes, IntoBytes, Debug, PartialEq)]  | 
1299  |  |         #[repr(transparent)]  | 
1300  |  |         struct PanicOnDrop<T>(T);  | 
1301  |  |  | 
1302  |  |         impl<T> Drop for PanicOnDrop<T> { | 
1303  |  |             fn drop(&mut self) { | 
1304  |  |                 panic!("PanicOnDrop dropped"); | 
1305  |  |             }  | 
1306  |  |         }  | 
1307  |  |  | 
1308  |  |         // Since `try_transmute!` semantically moves its argument on failure,  | 
1309  |  |         // the `PanicOnDrop` is not dropped, and thus this shouldn't panic.  | 
1310  |  |         let x: Result<usize, _> = try_transmute!(PanicOnDrop(1usize));  | 
1311  |  |         assert_eq!(x, Ok(1));  | 
1312  |  |  | 
1313  |  |         // Since `try_transmute!` semantically returns ownership of its argument  | 
1314  |  |         // on failure, the `PanicOnDrop` is returned rather than dropped, and  | 
1315  |  |         // thus this shouldn't panic.  | 
1316  |  |         let y: Result<bool, _> = try_transmute!(PanicOnDrop(2u8));  | 
1317  |  |         // We have to use `map_err` instead of comparing against  | 
1318  |  |         // `Err(PanicOnDrop(2u8))` because the latter would create and then drop  | 
1319  |  |         // its `PanicOnDrop` temporary, which would cause a panic.  | 
1320  |  |         assert_eq!(y.as_ref().map_err(|p| &p.src.0), Err::<&bool, _>(&2u8));  | 
1321  |  |         mem::forget(y);  | 
1322  |  |     }  | 
1323  |  |  | 
1324  |  |     #[test]  | 
1325  |  |     fn test_try_transmute_ref() { | 
1326  |  |         // Test that memory is transmuted with `try_transmute_ref` as expected.  | 
1327  |  |         let array_of_bools = &[false, true, false, true, false, true, false, true];  | 
1328  |  |         let array_of_arrays = &[[0, 1], [0, 1], [0, 1], [0, 1]];  | 
1329  |  |         let x: Result<&[[u8; 2]; 4], _> = try_transmute_ref!(array_of_bools);  | 
1330  |  |         assert_eq!(x, Ok(array_of_arrays));  | 
1331  |  |         let x: Result<&[bool; 8], _> = try_transmute_ref!(array_of_arrays);  | 
1332  |  |         assert_eq!(x, Ok(array_of_bools));  | 
1333  |  |  | 
1334  |  |         // Test that it's legal to transmute a reference while shrinking the  | 
1335  |  |         // lifetime.  | 
1336  |  |         { | 
1337  |  |             let x: Result<&[[u8; 2]; 4], _> = try_transmute_ref!(array_of_bools);  | 
1338  |  |             assert_eq!(x, Ok(array_of_arrays));  | 
1339  |  |         }  | 
1340  |  |  | 
1341  |  |         // Test that `try_transmute_ref!` supports decreasing alignment.  | 
1342  |  |         let u = AU64(0);  | 
1343  |  |         let array = [0u8, 0, 0, 0, 0, 0, 0, 0];  | 
1344  |  |         let x: Result<&[u8; 8], _> = try_transmute_ref!(&u);  | 
1345  |  |         assert_eq!(x, Ok(&array));  | 
1346  |  |  | 
1347  |  |         // Test that a mutable reference can be turned into an immutable one.  | 
1348  |  |         let mut x = 0u8;  | 
1349  |  |         #[allow(clippy::useless_transmute)]  | 
1350  |  |         let y: Result<&u8, _> = try_transmute_ref!(&mut x);  | 
1351  |  |         assert_eq!(y, Ok(&0));  | 
1352  |  |     }  | 
1353  |  |  | 
1354  |  |     #[test]  | 
1355  |  |     fn test_try_transmute_mut() { | 
1356  |  |         // Test that memory is transmuted with `try_transmute_mut` as expected.  | 
1357  |  |         let array_of_u8s = &mut [0u8, 1, 0, 1, 0, 1, 0, 1];  | 
1358  |  |         let array_of_arrays = &mut [[0u8, 1], [0, 1], [0, 1], [0, 1]];  | 
1359  |  |         let x: Result<&mut [[u8; 2]; 4], _> = try_transmute_mut!(array_of_u8s);  | 
1360  |  |         assert_eq!(x, Ok(array_of_arrays));  | 
1361  |  |  | 
1362  |  |         let array_of_bools = &mut [false, true, false, true, false, true, false, true];  | 
1363  |  |         let array_of_arrays = &mut [[0u8, 1], [0, 1], [0, 1], [0, 1]];  | 
1364  |  |         let x: Result<&mut [bool; 8], _> = try_transmute_mut!(array_of_arrays);  | 
1365  |  |         assert_eq!(x, Ok(array_of_bools));  | 
1366  |  |  | 
1367  |  |         // Test that it's legal to transmute a reference while shrinking the  | 
1368  |  |         // lifetime.  | 
1369  |  |         let array_of_bools = &mut [false, true, false, true, false, true, false, true];  | 
1370  |  |         let array_of_arrays = &mut [[0u8, 1], [0, 1], [0, 1], [0, 1]];  | 
1371  |  |         { | 
1372  |  |             let x: Result<&mut [bool; 8], _> = try_transmute_mut!(array_of_arrays);  | 
1373  |  |             assert_eq!(x, Ok(array_of_bools));  | 
1374  |  |         }  | 
1375  |  |  | 
1376  |  |         // Test that `try_transmute_mut!` supports decreasing alignment.  | 
1377  |  |         let u = &mut AU64(0);  | 
1378  |  |         let array = &mut [0u8, 0, 0, 0, 0, 0, 0, 0];  | 
1379  |  |         let x: Result<&mut [u8; 8], _> = try_transmute_mut!(u);  | 
1380  |  |         assert_eq!(x, Ok(array));  | 
1381  |  |  | 
1382  |  |         // Test that a mutable reference can be turned into an immutable one.  | 
1383  |  |         let mut x = 0u8;  | 
1384  |  |         #[allow(clippy::useless_transmute)]  | 
1385  |  |         let y: Result<&mut u8, _> = try_transmute_mut!(&mut x);  | 
1386  |  |         assert_eq!(y, Ok(&mut 0));  | 
1387  |  |     }  | 
1388  |  |  | 
1389  |  |     #[test]  | 
1390  |  |     fn test_transmute_mut() { | 
1391  |  |         // Test that memory is transmuted as expected.  | 
1392  |  |         let mut array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];  | 
1393  |  |         let mut array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];  | 
1394  |  |         let x: &mut [[u8; 2]; 4] = transmute_mut!(&mut array_of_u8s);  | 
1395  |  |         assert_eq!(*x, array_of_arrays);  | 
1396  |  |         let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);  | 
1397  |  |         assert_eq!(*x, array_of_u8s);  | 
1398  |  |  | 
1399  |  |         { | 
1400  |  |             // Test that it's legal to transmute a reference while shrinking the  | 
1401  |  |             // lifetime.  | 
1402  |  |             let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);  | 
1403  |  |             assert_eq!(*x, array_of_u8s);  | 
1404  |  |         }  | 
1405  |  |  | 
1406  |  |         // Test that `transmute_mut!` supports non-`KnownLayout` types.  | 
1407  |  |         let mut array_of_u8s = Nkl([0u8, 1, 2, 3, 4, 5, 6, 7]);  | 
1408  |  |         let mut array_of_arrays = Nkl([[0, 1], [2, 3], [4, 5], [6, 7]]);  | 
1409  |  |         let x: &mut Nkl<[[u8; 2]; 4]> = transmute_mut!(&mut array_of_u8s);  | 
1410  |  |         assert_eq!(*x, array_of_arrays);  | 
1411  |  |         let x: &mut Nkl<[u8; 8]> = transmute_mut!(&mut array_of_arrays);  | 
1412  |  |         assert_eq!(*x, array_of_u8s);  | 
1413  |  |  | 
1414  |  |         // Test that `transmute_mut!` supports decreasing alignment.  | 
1415  |  |         let mut u = AU64(0);  | 
1416  |  |         let array = [0, 0, 0, 0, 0, 0, 0, 0];  | 
1417  |  |         let x: &[u8; 8] = transmute_mut!(&mut u);  | 
1418  |  |         assert_eq!(*x, array);  | 
1419  |  |  | 
1420  |  |         // Test that a mutable reference can be turned into an immutable one.  | 
1421  |  |         let mut x = 0u8;  | 
1422  |  |         #[allow(clippy::useless_transmute)]  | 
1423  |  |         let y: &u8 = transmute_mut!(&mut x);  | 
1424  |  |         assert_eq!(*y, 0);  | 
1425  |  |  | 
1426  |  |         // Test that `transmute_mut!` works on slice DSTs in and that memory is  | 
1427  |  |         // transmuted as expected.  | 
1428  |  |         let mut bytes = [0, 1, 2, 3, 4, 5, 6];  | 
1429  |  |         let slice_dst_of_u8s = SliceDst::<u8, [u8; 2]>::mut_from_bytes(&mut bytes[..]).unwrap();  | 
1430  |  |         let mut bytes = [0, 1, 2, 3, 4, 5, 6];  | 
1431  |  |         let slice_dst_of_u16s = SliceDst::<u8, U16>::mut_from_bytes(&mut bytes[..]).unwrap();  | 
1432  |  |         let x: &mut SliceDst<u8, U16> = transmute_mut!(slice_dst_of_u8s);  | 
1433  |  |         assert_eq!(x, slice_dst_of_u16s);  | 
1434  |  |  | 
1435  |  |         // Test that `transmute_mut!` works on slices that memory is transmuted  | 
1436  |  |         // as expected.  | 
1437  |  |         let array_of_u16s: &mut [u16] = &mut [0u16, 1, 2];  | 
1438  |  |         let array_of_i16s: &mut [i16] = &mut [0i16, 1, 2];  | 
1439  |  |         let x: &mut [i16] = transmute_mut!(array_of_u16s);  | 
1440  |  |         assert_eq!(x, array_of_i16s);  | 
1441  |  |  | 
1442  |  |         // Test that transmuting from a type with larger trailing slice offset  | 
1443  |  |         // and larger trailing slice element works.  | 
1444  |  |         let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7];  | 
1445  |  |         let slice_dst_big = SliceDst::<U32, U16>::mut_from_bytes(&mut bytes[..]).unwrap();  | 
1446  |  |         let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7];  | 
1447  |  |         let slice_dst_small = SliceDst::<U16, u8>::mut_from_bytes(&mut bytes[..]).unwrap();  | 
1448  |  |         let x: &mut SliceDst<U16, u8> = transmute_mut!(slice_dst_big);  | 
1449  |  |         assert_eq!(x, slice_dst_small);  | 
1450  |  |     }  | 
1451  |  |  | 
1452  |  |     #[test]  | 
1453  |  |     fn test_macros_evaluate_args_once() { | 
1454  |  |         let mut ctr = 0;  | 
1455  |  |         #[allow(clippy::useless_transmute)]  | 
1456  |  |         let _: usize = transmute!({ | 
1457  |  |             ctr += 1;  | 
1458  |  |             0usize  | 
1459  |  |         });  | 
1460  |  |         assert_eq!(ctr, 1);  | 
1461  |  |  | 
1462  |  |         let mut ctr = 0;  | 
1463  |  |         let _: &usize = transmute_ref!({ | 
1464  |  |             ctr += 1;  | 
1465  |  |             &0usize  | 
1466  |  |         });  | 
1467  |  |         assert_eq!(ctr, 1);  | 
1468  |  |  | 
1469  |  |         let mut ctr: usize = 0;  | 
1470  |  |         let _: &mut usize = transmute_mut!({ | 
1471  |  |             ctr += 1;  | 
1472  |  |             &mut ctr  | 
1473  |  |         });  | 
1474  |  |         assert_eq!(ctr, 1);  | 
1475  |  |  | 
1476  |  |         let mut ctr = 0;  | 
1477  |  |         #[allow(clippy::useless_transmute)]  | 
1478  |  |         let _: usize = try_transmute!({ | 
1479  |  |             ctr += 1;  | 
1480  |  |             0usize  | 
1481  |  |         })  | 
1482  |  |         .unwrap();  | 
1483  |  |         assert_eq!(ctr, 1);  | 
1484  |  |     }  | 
1485  |  |  | 
1486  |  |     #[test]  | 
1487  |  |     fn test_include_value() { | 
1488  |  |         const AS_U32: u32 = include_value!("../testdata/include_value/data"); | 
1489  |  |         assert_eq!(AS_U32, u32::from_ne_bytes([b'a', b'b', b'c', b'd']));  | 
1490  |  |         const AS_I32: i32 = include_value!("../testdata/include_value/data"); | 
1491  |  |         assert_eq!(AS_I32, i32::from_ne_bytes([b'a', b'b', b'c', b'd']));  | 
1492  |  |     }  | 
1493  |  |  | 
1494  |  |     #[test]  | 
1495  |  |     #[allow(non_camel_case_types, unreachable_pub, dead_code)]  | 
1496  |  |     fn test_cryptocorrosion_derive_traits() { | 
1497  |  |         // Test the set of invocations added in  | 
1498  |  |         // https://github.com/cryptocorrosion/cryptocorrosion/pull/85  | 
1499  |  |  | 
1500  |  |         fn assert_impls<T: FromBytes + IntoBytes + Immutable>() {} | 
1501  |  |  | 
1502  |  |         cryptocorrosion_derive_traits! { | 
1503  |  |             #[repr(C)]  | 
1504  |  |             #[derive(Clone, Copy)]  | 
1505  |  |             pub union vec128_storage { | 
1506  |  |                 d: [u32; 4],  | 
1507  |  |                 q: [u64; 2],  | 
1508  |  |             }  | 
1509  |  |         }  | 
1510  |  |  | 
1511  |  |         assert_impls::<vec128_storage>();  | 
1512  |  |  | 
1513  |  |         cryptocorrosion_derive_traits! { | 
1514  |  |             #[repr(transparent)]  | 
1515  |  |             #[derive(Copy, Clone, Debug, PartialEq)]  | 
1516  |  |             pub struct u32x4_generic([u32; 4]);  | 
1517  |  |         }  | 
1518  |  |  | 
1519  |  |         assert_impls::<u32x4_generic>();  | 
1520  |  |  | 
1521  |  |         cryptocorrosion_derive_traits! { | 
1522  |  |             #[repr(transparent)]  | 
1523  |  |             #[derive(Copy, Clone, Debug, PartialEq)]  | 
1524  |  |             pub struct u64x2_generic([u64; 2]);  | 
1525  |  |         }  | 
1526  |  |  | 
1527  |  |         assert_impls::<u64x2_generic>();  | 
1528  |  |  | 
1529  |  |         cryptocorrosion_derive_traits! { | 
1530  |  |             #[repr(transparent)]  | 
1531  |  |             #[derive(Copy, Clone, Debug, PartialEq)]  | 
1532  |  |             pub struct u128x1_generic([u128; 1]);  | 
1533  |  |         }  | 
1534  |  |  | 
1535  |  |         assert_impls::<u128x1_generic>();  | 
1536  |  |  | 
1537  |  |         cryptocorrosion_derive_traits! { | 
1538  |  |             #[repr(transparent)]  | 
1539  |  |             #[derive(Copy, Clone, Default)]  | 
1540  |  |             #[allow(non_camel_case_types)]  | 
1541  |  |             pub struct x2<W, G>(pub [W; 2], PhantomData<G>);  | 
1542  |  |         }  | 
1543  |  |  | 
1544  |  |         enum NotZerocopy {} | 
1545  |  |         assert_impls::<x2<(), NotZerocopy>>();  | 
1546  |  |  | 
1547  |  |         cryptocorrosion_derive_traits! { | 
1548  |  |             #[repr(transparent)]  | 
1549  |  |             #[derive(Copy, Clone, Default)]  | 
1550  |  |             #[allow(non_camel_case_types)]  | 
1551  |  |             pub struct x4<W>(pub [W; 4]);  | 
1552  |  |         }  | 
1553  |  |  | 
1554  |  |         assert_impls::<x4<()>>();  | 
1555  |  |  | 
1556  |  |         #[cfg(feature = "simd")]  | 
1557  |  |         #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]  | 
1558  |  |         { | 
1559  |  |             #[cfg(target_arch = "x86")]  | 
1560  |  |             use core::arch::x86::{__m128i, __m256i}; | 
1561  |  |             #[cfg(target_arch = "x86_64")]  | 
1562  |  |             use core::arch::x86_64::{__m128i, __m256i}; | 
1563  |  |  | 
1564  |  |             cryptocorrosion_derive_traits! { | 
1565  |  |                 #[repr(C)]  | 
1566  |  |                 #[derive(Copy, Clone)]  | 
1567  |  |                 pub struct X4(__m128i, __m128i, __m128i, __m128i);  | 
1568  |  |             }  | 
1569  |  |  | 
1570  |  |             assert_impls::<X4>();  | 
1571  |  |  | 
1572  |  |             cryptocorrosion_derive_traits! { | 
1573  |  |                 #[repr(C)]  | 
1574  |  |                 /// Generic wrapper for unparameterized storage of any of the possible impls.  | 
1575  |  |                 /// Converting into and out of this type should be essentially free, although it may be more  | 
1576  |  |                 /// aligned than a particular impl requires.  | 
1577  |  |                 #[allow(non_camel_case_types)]  | 
1578  |  |                 #[derive(Copy, Clone)]  | 
1579  |  |                 pub union vec128_storage { | 
1580  |  |                     u32x4: [u32; 4],  | 
1581  |  |                     u64x2: [u64; 2],  | 
1582  |  |                     u128x1: [u128; 1],  | 
1583  |  |                     sse2: __m128i,  | 
1584  |  |                 }  | 
1585  |  |             }  | 
1586  |  |  | 
1587  |  |             assert_impls::<vec128_storage>();  | 
1588  |  |  | 
1589  |  |             cryptocorrosion_derive_traits! { | 
1590  |  |                 #[repr(transparent)]  | 
1591  |  |                 #[allow(non_camel_case_types)]  | 
1592  |  |                 #[derive(Copy, Clone)]  | 
1593  |  |                 pub struct vec<S3, S4, NI> { | 
1594  |  |                     x: __m128i,  | 
1595  |  |                     s3: PhantomData<S3>,  | 
1596  |  |                     s4: PhantomData<S4>,  | 
1597  |  |                     ni: PhantomData<NI>,  | 
1598  |  |                 }  | 
1599  |  |             }  | 
1600  |  |  | 
1601  |  |             assert_impls::<vec<NotZerocopy, NotZerocopy, NotZerocopy>>();  | 
1602  |  |  | 
1603  |  |             cryptocorrosion_derive_traits! { | 
1604  |  |                 #[repr(transparent)]  | 
1605  |  |                 #[derive(Copy, Clone)]  | 
1606  |  |                 pub struct u32x4x2_avx2<NI> { | 
1607  |  |                     x: __m256i,  | 
1608  |  |                     ni: PhantomData<NI>,  | 
1609  |  |                 }  | 
1610  |  |             }  | 
1611  |  |  | 
1612  |  |             assert_impls::<u32x4x2_avx2<NotZerocopy>>();  | 
1613  |  |         }  | 
1614  |  |  | 
1615  |  |         // Make sure that our derive works for `#[repr(C)]` structs even though  | 
1616  |  |         // cryptocorrosion doesn't currently have any.  | 
1617  |  |         cryptocorrosion_derive_traits! { | 
1618  |  |             #[repr(C)]  | 
1619  |  |             #[derive(Copy, Clone, Debug, PartialEq)]  | 
1620  |  |             pub struct ReprC(u8, u8, u16);  | 
1621  |  |         }  | 
1622  |  |     }  | 
1623  |  | }  |