-
-
Save dadhi/0e8d114ae9bc4c6e8224f4f4c5df6035 to your computer and use it in GitHub Desktop.
MaybeUninit and type_name implemented as AnyExt
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
#![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