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