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