Created
June 2, 2017 00:10
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![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