1 // Currently this test doesn't actually check the output of the functions.
2 // It's only here for miri to check for any potential undefined behaviour.
3 // TODO: check function results
4
5 #[test]
test_transparent_wrapper()6 fn test_transparent_wrapper() {
7 // An external type defined in a different crate.
8 #[derive(Debug, Copy, Clone, Default)]
9 struct Foreign(u8);
10
11 use bytemuck::TransparentWrapper;
12
13 #[derive(Debug, Copy, Clone)]
14 #[repr(transparent)]
15 struct Wrapper(Foreign);
16
17 unsafe impl TransparentWrapper<Foreign> for Wrapper {}
18
19 // Traits can be implemented on crate-local wrapper.
20 unsafe impl bytemuck::Zeroable for Wrapper {}
21 unsafe impl bytemuck::Pod for Wrapper {}
22
23 impl PartialEq<u8> for Foreign {
24 fn eq(&self, &other: &u8) -> bool {
25 self.0 == other
26 }
27 }
28
29 impl PartialEq<u8> for Wrapper {
30 fn eq(&self, &other: &u8) -> bool {
31 self.0 == other
32 }
33 }
34
35 let _: u8 = bytemuck::cast(Wrapper::wrap(Foreign::default()));
36 let _: Foreign = Wrapper::peel(bytemuck::cast(u8::default()));
37
38 let _: &u8 = bytemuck::cast_ref(Wrapper::wrap_ref(&Foreign::default()));
39 let _: &Foreign = Wrapper::peel_ref(bytemuck::cast_ref(&u8::default()));
40
41 let _: &mut u8 =
42 bytemuck::cast_mut(Wrapper::wrap_mut(&mut Foreign::default()));
43 let _: &mut Foreign =
44 Wrapper::peel_mut(bytemuck::cast_mut(&mut u8::default()));
45
46 let _: &[u8] =
47 bytemuck::cast_slice(Wrapper::wrap_slice(&[Foreign::default()]));
48 let _: &[Foreign] =
49 Wrapper::peel_slice(bytemuck::cast_slice(&[u8::default()]));
50
51 let _: &mut [u8] =
52 bytemuck::cast_slice_mut(Wrapper::wrap_slice_mut(
53 &mut [Foreign::default()],
54 ));
55 let _: &mut [Foreign] =
56 Wrapper::peel_slice_mut(bytemuck::cast_slice_mut(&mut [u8::default()]));
57
58 let _: &[u8] = bytemuck::bytes_of(Wrapper::wrap_ref(&Foreign::default()));
59 let _: &Foreign = Wrapper::peel_ref(bytemuck::from_bytes(&[u8::default()]));
60
61 let _: &mut [u8] =
62 bytemuck::bytes_of_mut(Wrapper::wrap_mut(&mut Foreign::default()));
63 let _: &mut Foreign =
64 Wrapper::peel_mut(bytemuck::from_bytes_mut(&mut [u8::default()]));
65
66 // not sure if this is the right usage
67 let _ =
68 bytemuck::pod_align_to::<_, u8>(Wrapper::wrap_slice(&[Foreign::default()]));
69 // counterpart?
70
71 // not sure if this is the right usage
72 let _ = bytemuck::pod_align_to_mut::<_, u8>(Wrapper::wrap_slice_mut(&mut [
73 Foreign::default(),
74 ]));
75 // counterpart?
76
77 #[cfg(feature = "extern_crate_alloc")]
78 {
79 use bytemuck::allocation::TransparentWrapperAlloc;
80 use std::rc::Rc;
81
82 let a: Vec<Foreign> = vec![Foreign::default(); 2];
83
84 let b: Vec<Wrapper> = Wrapper::wrap_vec(a);
85 assert_eq!(b, [0, 0]);
86
87 let c: Vec<Foreign> = Wrapper::peel_vec(b);
88 assert_eq!(c, [0, 0]);
89
90 let d: Box<Foreign> = Box::new(Foreign::default());
91
92 let e: Box<Wrapper> = Wrapper::wrap_box(d);
93 assert_eq!(&*e, &0);
94 let f: Box<Foreign> = Wrapper::peel_box(e);
95 assert_eq!(&*f, &0);
96
97 let g: Rc<Foreign> = Rc::new(Foreign::default());
98
99 let h: Rc<Wrapper> = Wrapper::wrap_rc(g);
100 assert_eq!(&*h, &0);
101 let i: Rc<Foreign> = Wrapper::peel_rc(h);
102 assert_eq!(&*i, &0);
103
104 #[cfg(target_has_atomic = "ptr")]
105 {
106 use std::sync::Arc;
107
108 let j: Arc<Foreign> = Arc::new(Foreign::default());
109
110 let k: Arc<Wrapper> = Wrapper::wrap_arc(j);
111 assert_eq!(&*k, &0);
112 let l: Arc<Foreign> = Wrapper::peel_arc(k);
113 assert_eq!(&*l, &0);
114 }
115 }
116 }
117