use std::ptr;
#[allow(dead_code)]
struct Sample(usize);
trait SomeTrait {
fn call_me(&self) -> bool {
true
}
}
impl SomeTrait for Sample {}
fn layout_broken(what: &str) {
panic!(
concat!(
"Assumptions on layout are broken, this crate relies on ",
"`unsafe code guidelines` layout specification, ",
"now layout of {:?} is broken, report about it on github"
),
what
);
}
fn test_ptr_layouts() {
{
#[repr(C)]
struct DynObj {
data_ptr: *const u8,
vtable: *const u8,
}
let sample = Box::new(Sample(100));
let data_ptr = Box::into_raw(sample);
let trait_obj: *const dyn SomeTrait = data_ptr;
let dyn_obj_repr: DynObj = unsafe { ptr::read(ptr::addr_of!(trait_obj) as *const DynObj) };
if dyn_obj_repr.data_ptr != data_ptr as *const u8 {
layout_broken("trait objects");
}
let out = unsafe { Box::from_raw(data_ptr) };
out.call_me();
}
{
let array = [1, 2, 3];
let slice: &[u8] = &array;
#[repr(C)]
struct Slice {
data_ptr: *const u8,
size: usize,
}
let slice_repr: Slice = unsafe { ptr::read(ptr::addr_of!(slice) as *const Slice) };
if slice_repr.data_ptr != slice.as_ptr() || slice_repr.size != slice.len() {
layout_broken("slices");
}
}
}
fn main() {
test_ptr_layouts();
}