1 #![allow(clippy::disallowed_names)]
2 #![allow(dead_code)]
3
4 //! Cargo miri doesn't run doctests yet, so we duplicate these here. It's
5 //! probably not that important to sweat keeping these perfectly up to date, but
6 //! we should try to catch the cases where the primary tests are doctests.
7 use bytemuck::*;
8
9 // Miri doesn't run on doctests, so... copypaste to the rescue.
10 #[test]
test_transparent_slice()11 fn test_transparent_slice() {
12 #[repr(transparent)]
13 struct Slice<T>([T]);
14
15 unsafe impl<T> TransparentWrapper<[T]> for Slice<T> {}
16
17 let s = Slice::wrap_ref(&[1u32, 2, 3]);
18 assert_eq!(&s.0, &[1, 2, 3]);
19
20 let mut buf = [1, 2, 3u8];
21 let _sm = Slice::wrap_mut(&mut buf);
22 }
23
24 #[test]
test_transparent_basic()25 fn test_transparent_basic() {
26 #[derive(Default)]
27 struct SomeStruct(u32);
28
29 #[repr(transparent)]
30 struct MyWrapper(SomeStruct);
31
32 unsafe impl TransparentWrapper<SomeStruct> for MyWrapper {}
33
34 // interpret a reference to &SomeStruct as a &MyWrapper
35 let thing = SomeStruct::default();
36 let wrapped_ref: &MyWrapper = MyWrapper::wrap_ref(&thing);
37
38 // Works with &mut too.
39 let mut mut_thing = SomeStruct::default();
40 let wrapped_mut: &mut MyWrapper = MyWrapper::wrap_mut(&mut mut_thing);
41 let _ = (wrapped_ref, wrapped_mut);
42 }
43
44 // Work around miri not running doctests
45 #[test]
test_contiguous_doc()46 fn test_contiguous_doc() {
47 #[repr(u8)]
48 #[derive(Debug, Copy, Clone, PartialEq)]
49 enum Foo {
50 A = 0,
51 B = 1,
52 C = 2,
53 D = 3,
54 E = 4,
55 }
56 unsafe impl Contiguous for Foo {
57 type Int = u8;
58 const MIN_VALUE: u8 = Foo::A as u8;
59 const MAX_VALUE: u8 = Foo::E as u8;
60 }
61
62 assert_eq!(Foo::from_integer(3).unwrap(), Foo::D);
63 assert_eq!(Foo::from_integer(8), None);
64 assert_eq!(Foo::C.into_integer(), 2);
65 assert_eq!(Foo::B.into_integer(), Foo::B as u8);
66 }
67
68 #[test]
test_offsetof_vertex()69 fn test_offsetof_vertex() {
70 #[repr(C)]
71 struct Vertex {
72 pos: [f32; 2],
73 uv: [u16; 2],
74 color: [u8; 4],
75 }
76 unsafe impl Zeroable for Vertex {}
77
78 let pos = offset_of!(Zeroable::zeroed(), Vertex, pos);
79 let uv = offset_of!(Zeroable::zeroed(), Vertex, uv);
80 let color = offset_of!(Zeroable::zeroed(), Vertex, color);
81
82 assert_eq!(pos, 0);
83 assert_eq!(uv, 8);
84 assert_eq!(color, 12);
85 }
86
87 #[test]
test_offsetof_nonpod()88 fn test_offsetof_nonpod() {
89 #[derive(Default)]
90 struct Foo {
91 a: u8,
92 b: &'static str,
93 c: i32,
94 }
95
96 let a_offset = offset_of!(Default::default(), Foo, a);
97 let b_offset = offset_of!(Default::default(), Foo, b);
98 let c_offset = offset_of!(Default::default(), Foo, c);
99
100 assert_ne!(a_offset, b_offset);
101 assert_ne!(b_offset, c_offset);
102 // We can't check against hardcoded values for a repr(Rust) type,
103 // but prove to ourself this way.
104
105 let foo = Foo::default();
106 // Note: offsets are in bytes.
107 let as_bytes = &foo as *const _ as *const u8;
108
109 // We're using wrapping_offset here because it's not worth
110 // the unsafe block, but it would be valid to use `add` instead,
111 // as it cannot overflow.
112 assert_eq!(
113 &foo.a as *const _ as usize,
114 as_bytes.wrapping_add(a_offset) as usize
115 );
116 assert_eq!(
117 &foo.b as *const _ as usize,
118 as_bytes.wrapping_add(b_offset) as usize
119 );
120 assert_eq!(
121 &foo.c as *const _ as usize,
122 as_bytes.wrapping_add(c_offset) as usize
123 );
124 }
125