Skip to content

Instantly share code, notes, and snippets.

@dadhi
Forked from rust-play/playground.rs
Last active July 20, 2022 11:02
Show Gist options
  • Save dadhi/0e8d114ae9bc4c6e8224f4f4c5df6035 to your computer and use it in GitHub Desktop.
Save dadhi/0e8d114ae9bc4c6e8224f4f4c5df6035 to your computer and use it in GitHub Desktop.
MaybeUninit and type_name implemented as AnyExt
#![allow(unused)]
fn main() {
use std::mem::{self, MaybeUninit};
let data = {
// Create an uninitialized array of `MaybeUninit`. The `assume_init` is
// safe because the type we are claiming to have initialized here is a
// bunch of `MaybeUninit`s, which do not require initialization.
let mut data: [MaybeUninit<Vec<u32>>; 1000] = unsafe {
MaybeUninit::uninit().assume_init()
};
// Dropping a `MaybeUninit` does nothing. Thus using raw pointer
// assignment instead of `ptr::write` does not cause the old
// uninitialized value to be dropped. Also if there is a panic during
// this loop, we have a memory leak, but there is no memory safety
// issue.
for elem in &mut data[..] {
elem.write(vec![42]);
}
// Everything is initialized. Transmute the array to the
// initialized type.
unsafe { mem::transmute::<_, [Vec<u32>; 1000]>(data) }
};
pub trait AnyExt {
fn type_name(&self) -> &'static str;
}
impl<T> AnyExt for T {
fn type_name(&self) -> &'static str {
std::any::type_name::<T>()
}
}
assert_eq!(&data[0], &[42]);
println!("{:?}", &[42].type_name());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment