Skip to content

Instantly share code, notes, and snippets.

@snoyberg
Created November 27, 2018 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snoyberg/c6f8a66b71f61c3fa07f637066918b45 to your computer and use it in GitHub Desktop.
Save snoyberg/c6f8a66b71f61c3fa07f637066918b45 to your computer and use it in GitHub Desktop.
Safely initialize fix length arrays in Rust (WIP!)
#[derive(Debug)]
struct Foo(usize);
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropping: {}", self.0);
}
}
enum MakeArray<T> {
Nothing,
Just([T;
}
struct MakeArray<T> {
array: *mut T,
filled: usize,
}
impl<T> Drop for MakeArray<T> {
fn drop(&mut self) {
for i in 0..self.filled {
unsafe {
self.array.add(i).read();
}
}
}
}
fn init_array10<T, F>(mut f: F) -> [T; 10]
where F: FnMut(usize) -> T, T: std::fmt::Debug,
{
unsafe {
let mut array: [T; 10] = std::mem::uninitialized();
let array_ptr = array.as_mut_ptr();
let mut ma: MakeArray<T> = MakeArray {
array: array_ptr,
filled: 0,
};
for i in 0..10 {
let x = f(i);
ma.array.add(i).write(x);
println!("{} {:?}", i, array);
ma.filled += 1;
}
ma.filled = 0;
println!("Finished filling {:?}", array);
array
}
}
fn main() {
/*
let mut arr: [Foo; 10] = unsafe { std::mem::uninitialized() };
for (i, element) in arr.iter_mut().enumerate() {
unsafe {
std::ptr::write(element, Foo(i));
}
}
*/
{
println!("{:?}", init_array10(|i| Foo(i)));
}
println!("\n\n\nPanic case\n\n\n");
let _arr = init_array10(|i| {
if i < 3 {
Foo(i)
} else {
panic!("Testing panics");
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment