2021-03-29 05:11:13 +00:00
|
|
|
// Currently this test doesn't actually check the output of the functions.
|
|
|
|
// It's only here for miri to check for any potential undefined behaviour.
|
|
|
|
// TODO: check function results
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_transparent_wrapper() {
|
|
|
|
// An external type defined in a different crate.
|
2022-07-24 03:09:32 +00:00
|
|
|
#[derive(Debug, Copy, Clone, Default)]
|
2021-03-29 05:11:13 +00:00
|
|
|
struct Foreign(u8);
|
|
|
|
|
|
|
|
use bytemuck::TransparentWrapper;
|
|
|
|
|
2022-07-24 03:09:32 +00:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
2021-03-29 05:11:13 +00:00
|
|
|
#[repr(transparent)]
|
|
|
|
struct Wrapper(Foreign);
|
|
|
|
|
|
|
|
unsafe impl TransparentWrapper<Foreign> for Wrapper {}
|
|
|
|
|
|
|
|
// Traits can be implemented on crate-local wrapper.
|
|
|
|
unsafe impl bytemuck::Zeroable for Wrapper {}
|
|
|
|
unsafe impl bytemuck::Pod for Wrapper {}
|
|
|
|
|
2022-07-24 03:09:32 +00:00
|
|
|
impl PartialEq<u8> for Foreign {
|
2022-07-24 15:27:49 +00:00
|
|
|
fn eq(&self, &other: &u8) -> bool {
|
|
|
|
self.0 == other
|
|
|
|
}
|
2022-07-24 03:09:32 +00:00
|
|
|
}
|
2022-07-24 15:27:49 +00:00
|
|
|
|
2022-07-24 03:09:32 +00:00
|
|
|
impl PartialEq<u8> for Wrapper {
|
2022-07-24 15:27:49 +00:00
|
|
|
fn eq(&self, &other: &u8) -> bool {
|
|
|
|
self.0 == other
|
|
|
|
}
|
2022-07-24 03:09:32 +00:00
|
|
|
}
|
|
|
|
|
2021-03-29 05:11:13 +00:00
|
|
|
let _: u8 = bytemuck::cast(Wrapper::wrap(Foreign::default()));
|
2021-06-10 20:05:15 +00:00
|
|
|
let _: Foreign = Wrapper::peel(bytemuck::cast(u8::default()));
|
2021-03-29 05:11:13 +00:00
|
|
|
|
|
|
|
let _: &u8 = bytemuck::cast_ref(Wrapper::wrap_ref(&Foreign::default()));
|
2021-06-10 20:05:15 +00:00
|
|
|
let _: &Foreign = Wrapper::peel_ref(bytemuck::cast_ref(&u8::default()));
|
2021-03-29 05:11:13 +00:00
|
|
|
|
|
|
|
let _: &mut u8 =
|
|
|
|
bytemuck::cast_mut(Wrapper::wrap_mut(&mut Foreign::default()));
|
|
|
|
let _: &mut Foreign =
|
2021-06-10 20:05:15 +00:00
|
|
|
Wrapper::peel_mut(bytemuck::cast_mut(&mut u8::default()));
|
2021-03-29 05:11:13 +00:00
|
|
|
|
|
|
|
let _: &[u8] =
|
|
|
|
bytemuck::cast_slice(Wrapper::wrap_slice(&[Foreign::default()]));
|
|
|
|
let _: &[Foreign] =
|
2021-06-10 20:05:15 +00:00
|
|
|
Wrapper::peel_slice(bytemuck::cast_slice(&[u8::default()]));
|
2021-03-29 05:11:13 +00:00
|
|
|
|
|
|
|
let _: &mut [u8] =
|
|
|
|
bytemuck::cast_slice_mut(Wrapper::wrap_slice_mut(
|
|
|
|
&mut [Foreign::default()],
|
|
|
|
));
|
|
|
|
let _: &mut [Foreign] =
|
2021-06-10 20:05:15 +00:00
|
|
|
Wrapper::peel_slice_mut(bytemuck::cast_slice_mut(&mut [u8::default()]));
|
2021-03-29 05:11:13 +00:00
|
|
|
|
|
|
|
let _: &[u8] = bytemuck::bytes_of(Wrapper::wrap_ref(&Foreign::default()));
|
2021-06-10 20:05:15 +00:00
|
|
|
let _: &Foreign = Wrapper::peel_ref(bytemuck::from_bytes(&[u8::default()]));
|
2021-03-29 05:11:13 +00:00
|
|
|
|
|
|
|
let _: &mut [u8] =
|
|
|
|
bytemuck::bytes_of_mut(Wrapper::wrap_mut(&mut Foreign::default()));
|
|
|
|
let _: &mut Foreign =
|
2021-06-10 20:05:15 +00:00
|
|
|
Wrapper::peel_mut(bytemuck::from_bytes_mut(&mut [u8::default()]));
|
2021-03-29 05:11:13 +00:00
|
|
|
|
|
|
|
// not sure if this is the right usage
|
|
|
|
let _ =
|
|
|
|
bytemuck::pod_align_to::<_, u8>(Wrapper::wrap_slice(&[Foreign::default()]));
|
|
|
|
// counterpart?
|
|
|
|
|
|
|
|
// not sure if this is the right usage
|
|
|
|
let _ = bytemuck::pod_align_to_mut::<_, u8>(Wrapper::wrap_slice_mut(&mut [
|
|
|
|
Foreign::default(),
|
|
|
|
]));
|
|
|
|
// counterpart?
|
2022-06-28 23:55:31 +00:00
|
|
|
|
|
|
|
#[cfg(feature = "extern_crate_alloc")]
|
|
|
|
{
|
|
|
|
use bytemuck::allocation::TransparentWrapperAlloc;
|
2022-11-05 13:00:40 +00:00
|
|
|
use std::rc::Rc;
|
2022-06-28 23:55:31 +00:00
|
|
|
|
|
|
|
let a: Vec<Foreign> = vec![Foreign::default(); 2];
|
2022-07-24 15:27:49 +00:00
|
|
|
|
2022-06-28 23:55:31 +00:00
|
|
|
let b: Vec<Wrapper> = Wrapper::wrap_vec(a);
|
2022-07-24 03:09:32 +00:00
|
|
|
assert_eq!(b, [0, 0]);
|
2022-06-28 23:55:31 +00:00
|
|
|
|
|
|
|
let c: Vec<Foreign> = Wrapper::peel_vec(b);
|
2022-07-24 03:09:32 +00:00
|
|
|
assert_eq!(c, [0, 0]);
|
|
|
|
|
|
|
|
let d: Box<Foreign> = Box::new(Foreign::default());
|
2022-07-24 15:27:49 +00:00
|
|
|
|
2022-07-24 03:09:32 +00:00
|
|
|
let e: Box<Wrapper> = Wrapper::wrap_box(d);
|
|
|
|
assert_eq!(&*e, &0);
|
|
|
|
let f: Box<Foreign> = Wrapper::peel_box(e);
|
|
|
|
assert_eq!(&*f, &0);
|
Add `cast_{arc,rc}` (and slice and try), and `{wrap,peel}_{arc,rc}`. (#132)
* Add `allocation::{try_,}cast_{arc,rc}`, and add `{wrap,peel}_{arc,rc}` to `TransparentWrapperAlloc`.
* Avoid intermediate slice reference in `try_cast_slice_{arc,rc}`.
* remove `unsafe` block; run `cargo +nightly fmt` (ignoring files I didn't modify)
* Make `cast_rc` (etc) have the same bounds as `cast_mut`, due to the existence of `Rc::get_mut_unchecked`.
2022-09-01 23:23:28 +00:00
|
|
|
|
|
|
|
let g: Rc<Foreign> = Rc::new(Foreign::default());
|
|
|
|
|
|
|
|
let h: Rc<Wrapper> = Wrapper::wrap_rc(g);
|
|
|
|
assert_eq!(&*h, &0);
|
|
|
|
let i: Rc<Foreign> = Wrapper::peel_rc(h);
|
|
|
|
assert_eq!(&*i, &0);
|
|
|
|
|
2022-11-05 13:00:40 +00:00
|
|
|
#[cfg(target_has_atomic = "ptr")]
|
|
|
|
{
|
|
|
|
use std::sync::Arc;
|
Add `cast_{arc,rc}` (and slice and try), and `{wrap,peel}_{arc,rc}`. (#132)
* Add `allocation::{try_,}cast_{arc,rc}`, and add `{wrap,peel}_{arc,rc}` to `TransparentWrapperAlloc`.
* Avoid intermediate slice reference in `try_cast_slice_{arc,rc}`.
* remove `unsafe` block; run `cargo +nightly fmt` (ignoring files I didn't modify)
* Make `cast_rc` (etc) have the same bounds as `cast_mut`, due to the existence of `Rc::get_mut_unchecked`.
2022-09-01 23:23:28 +00:00
|
|
|
|
2022-11-05 13:00:40 +00:00
|
|
|
let j: Arc<Foreign> = Arc::new(Foreign::default());
|
|
|
|
|
|
|
|
let k: Arc<Wrapper> = Wrapper::wrap_arc(j);
|
|
|
|
assert_eq!(&*k, &0);
|
|
|
|
let l: Arc<Foreign> = Wrapper::peel_arc(k);
|
|
|
|
assert_eq!(&*l, &0);
|
|
|
|
}
|
2022-06-28 23:55:31 +00:00
|
|
|
}
|
2021-03-29 05:11:13 +00:00
|
|
|
}
|