• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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