Skip to content

Instantly share code, notes, and snippets.

@mikeyhew
Created June 2, 2017 00:10
Show Gist options
  • Save mikeyhew/ead5e4b2a954e0b857d67171423a5b36 to your computer and use it in GitHub Desktop.
Save mikeyhew/ead5e4b2a954e0b857d67171423a5b36 to your computer and use it in GitHub Desktop.
Demonstrates that std::mem::size_of_val and std::mem::align_of_val do not need to take a `&`-reference (a `*const` raw pointer is all that is needed)
#![feature(raw)]
use std::mem;
use std::ptr;
use std::raw::TraitObject;
use std::slice;
trait Foo {}
impl<T: ?Sized> Foo for T {}
unsafe fn assemble(data: *const (), vtable: *const ()) -> *const Foo {
mem::transmute(TraitObject{
data: data as *mut (),
vtable: vtable as *mut (),
})
}
fn disassemble<'a>(ptr: *const (Foo + 'a)) -> (*const (), *const ()) {
unsafe {
let TraitObject { data, vtable } = mem::transmute(ptr);
(data, vtable)
}
}
fn check_foo<'a>(foo: &(Foo + 'a)) {
let (_, vtable) = disassemble(foo);
let foo_null = unsafe { &*assemble(ptr::null(), vtable) };
println!("{} == {}", mem::size_of_val(foo), mem::size_of_val(foo_null));
println!("{} == {}", mem::align_of_val(foo), mem::align_of_val(foo_null));
}
fn check_slice<T>(slice: &[T]) {
let slice_null: &[T] = unsafe { slice::from_raw_parts(ptr::null(), slice.len()) };
println!("{} == {}", mem::size_of_val(slice), mem::size_of_val(slice_null));
println!("{} == {}", mem::align_of_val(slice), mem::align_of_val(slice_null));
}
fn main() {
check_foo(&"abc");
check_foo(&1u8);
check_foo(&1usize);
check_foo(&||{});
let x = 1;
check_foo(&||{x});
check_slice(&[1,2,3]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment