• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(dead_code)]
2 
3 use bytemuck::{
4   AnyBitPattern, CheckedBitPattern, Contiguous, NoUninit, Pod,
5   TransparentWrapper, Zeroable,
6 };
7 use std::marker::{PhantomData, PhantomPinned};
8 
9 #[derive(Copy, Clone, Pod, Zeroable)]
10 #[repr(C)]
11 struct Test {
12   a: u16,
13   b: u16,
14 }
15 
16 #[derive(Pod, Zeroable)]
17 #[repr(C, packed)]
18 struct GenericPackedStruct<T: Pod> {
19   a: u32,
20   b: T,
21   c: u32,
22 }
23 
24 impl<T: Pod> Clone for GenericPackedStruct<T> {
clone(&self) -> Self25   fn clone(&self) -> Self {
26     *self
27   }
28 }
29 
30 impl<T: Pod> Copy for GenericPackedStruct<T> {}
31 
32 #[derive(Pod, Zeroable)]
33 #[repr(C, packed(1))]
34 struct GenericPackedStructExplicitPackedAlignment<T: Pod> {
35   a: u32,
36   b: T,
37   c: u32,
38 }
39 
40 impl<T: Pod> Clone for GenericPackedStructExplicitPackedAlignment<T> {
clone(&self) -> Self41   fn clone(&self) -> Self {
42     *self
43   }
44 }
45 
46 impl<T: Pod> Copy for GenericPackedStructExplicitPackedAlignment<T> {}
47 
48 #[derive(Zeroable)]
49 struct ZeroGeneric<T: bytemuck::Zeroable> {
50   a: T,
51 }
52 
53 #[derive(TransparentWrapper)]
54 #[repr(transparent)]
55 struct TransparentSingle {
56   a: u16,
57 }
58 
59 #[derive(TransparentWrapper)]
60 #[repr(transparent)]
61 #[transparent(u16)]
62 struct TransparentWithZeroSized<T> {
63   a: u16,
64   b: PhantomData<T>,
65 }
66 
67 struct MyZst<T>(PhantomData<T>, [u8; 0], PhantomPinned);
68 unsafe impl<T> Zeroable for MyZst<T> {}
69 
70 #[derive(TransparentWrapper)]
71 #[repr(transparent)]
72 #[transparent(u16)]
73 struct TransparentTupleWithCustomZeroSized<T>(u16, MyZst<T>);
74 
75 #[repr(u8)]
76 #[derive(Clone, Copy, Contiguous)]
77 enum ContiguousWithValues {
78   A = 0,
79   B = 1,
80   C = 2,
81   D = 3,
82   E = 4,
83 }
84 
85 #[repr(i8)]
86 #[derive(Clone, Copy, Contiguous)]
87 enum ContiguousWithImplicitValues {
88   A = -10,
89   B,
90   C,
91   D,
92   E,
93 }
94 
95 #[derive(Copy, Clone, NoUninit)]
96 #[repr(C)]
97 struct NoUninitTest {
98   a: u16,
99   b: u16,
100 }
101 
102 #[derive(Copy, Clone, AnyBitPattern)]
103 #[repr(C)]
104 union UnionTestAnyBitPattern {
105   a: u8,
106   b: u16,
107 }
108 
109 #[repr(u8)]
110 #[derive(Debug, Clone, Copy, NoUninit, CheckedBitPattern, PartialEq, Eq)]
111 enum CheckedBitPatternEnumWithValues {
112   A = 0,
113   B = 1,
114   C = 2,
115   D = 3,
116   E = 4,
117 }
118 
119 #[repr(i8)]
120 #[derive(Clone, Copy, NoUninit, CheckedBitPattern)]
121 enum CheckedBitPatternEnumWithImplicitValues {
122   A = -10,
123   B,
124   C,
125   D,
126   E,
127 }
128 
129 #[repr(u8)]
130 #[derive(Debug, Clone, Copy, NoUninit, CheckedBitPattern, PartialEq, Eq)]
131 enum CheckedBitPatternEnumNonContiguous {
132   A = 1,
133   B = 8,
134   C = 2,
135   D = 3,
136   E = 56,
137 }
138 
139 #[repr(u8)]
140 #[derive(Debug, Clone, Copy, NoUninit, CheckedBitPattern, PartialEq, Eq)]
141 enum CheckedBitPatternEnumByteLit {
142   A = b'A',
143   B = b'B',
144   C = b'C',
145   D = b'D',
146   E = b'E',
147 }
148 
149 #[derive(Debug, Copy, Clone, NoUninit, CheckedBitPattern, PartialEq, Eq)]
150 #[repr(C)]
151 struct CheckedBitPatternStruct {
152   a: u8,
153   b: CheckedBitPatternEnumNonContiguous,
154 }
155 
156 #[derive(Debug, Copy, Clone, AnyBitPattern, PartialEq, Eq)]
157 #[repr(C)]
158 struct AnyBitPatternTest<A: AnyBitPattern, B: AnyBitPattern> {
159   a: A,
160   b: B,
161 }
162 
163 #[test]
fails_cast_contiguous()164 fn fails_cast_contiguous() {
165   let can_cast = CheckedBitPatternEnumWithValues::is_valid_bit_pattern(&5);
166   assert!(!can_cast);
167 }
168 
169 #[test]
passes_cast_contiguous()170 fn passes_cast_contiguous() {
171   let res =
172     bytemuck::checked::from_bytes::<CheckedBitPatternEnumWithValues>(&[2u8]);
173   assert_eq!(*res, CheckedBitPatternEnumWithValues::C);
174 }
175 
176 #[test]
fails_cast_noncontiguous()177 fn fails_cast_noncontiguous() {
178   let can_cast = CheckedBitPatternEnumNonContiguous::is_valid_bit_pattern(&4);
179   assert!(!can_cast);
180 }
181 
182 #[test]
passes_cast_noncontiguous()183 fn passes_cast_noncontiguous() {
184   let res =
185     bytemuck::checked::from_bytes::<CheckedBitPatternEnumNonContiguous>(&[
186       56u8,
187     ]);
188   assert_eq!(*res, CheckedBitPatternEnumNonContiguous::E);
189 }
190 
191 #[test]
fails_cast_bytelit()192 fn fails_cast_bytelit() {
193   let can_cast = CheckedBitPatternEnumByteLit::is_valid_bit_pattern(&b'a');
194   assert!(!can_cast);
195 }
196 
197 #[test]
passes_cast_bytelit()198 fn passes_cast_bytelit() {
199   let res =
200     bytemuck::checked::cast_slice::<u8, CheckedBitPatternEnumByteLit>(b"CAB");
201   assert_eq!(
202     res,
203     [
204       CheckedBitPatternEnumByteLit::C,
205       CheckedBitPatternEnumByteLit::A,
206       CheckedBitPatternEnumByteLit::B
207     ]
208   );
209 }
210 
211 #[test]
fails_cast_struct()212 fn fails_cast_struct() {
213   let pod = [0u8, 24u8];
214   let res = bytemuck::checked::try_from_bytes::<CheckedBitPatternStruct>(&pod);
215   assert!(res.is_err());
216 }
217 
218 #[test]
passes_cast_struct()219 fn passes_cast_struct() {
220   let pod = [0u8, 8u8];
221   let res = bytemuck::checked::from_bytes::<CheckedBitPatternStruct>(&pod);
222   assert_eq!(
223     *res,
224     CheckedBitPatternStruct { a: 0, b: CheckedBitPatternEnumNonContiguous::B }
225   );
226 }
227 
228 #[test]
anybitpattern_implies_zeroable()229 fn anybitpattern_implies_zeroable() {
230   let test = AnyBitPatternTest::<isize, usize>::zeroed();
231   assert_eq!(test, AnyBitPatternTest { a: 0isize, b: 0usize });
232 }
233 
234 #[test]
checkedbitpattern_try_pod_read_unaligned()235 fn checkedbitpattern_try_pod_read_unaligned() {
236   let pod = [0u8];
237   let res = bytemuck::checked::try_pod_read_unaligned::<
238     CheckedBitPatternEnumWithValues,
239   >(&pod);
240   assert!(res.is_ok());
241 
242   let pod = [5u8];
243   let res = bytemuck::checked::try_pod_read_unaligned::<
244     CheckedBitPatternEnumWithValues,
245   >(&pod);
246   assert!(res.is_err());
247 }
248 
249 #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
250 #[repr(C, align(16))]
251 struct Issue127 {}
252