Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created September 21, 2018 19: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 rust-play/6cbd15c151bf621d8a4b6ea3d8b1c04b to your computer and use it in GitHub Desktop.
Save rust-play/6cbd15c151bf621d8a4b6ea3d8b1c04b to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
#![feature(unsize, nll)]
use std::ptr;
use std::mem::{self, ManuallyDrop};
use std::marker::{PhantomData, Unsize};
struct PartialArray<T, A>
where
A: Unsize<[T]>
{
array: ManuallyDrop<A>,
idx: usize,
marker: PhantomData<T>
}
impl <T, A> PartialArray<T, A>
where
A: Unsize<[T]>
{
unsafe fn new() -> Self {
Self {
array: ManuallyDrop::new(mem::uninitialized()),
idx: 0,
marker: PhantomData,
}
}
fn from_iter<I: Iterator<Item = T>>(mut self, iter: I) -> Result<A, ()> {
unsafe {
let arr: &mut A = &mut self.array;
let slice: &mut [T] = arr;
for (dst, src) in slice.iter_mut().zip(iter) {
ptr::write(dst, src);
self.idx += 1;
}
if self.idx != slice.len() {
ptr::drop_in_place(&mut slice[..self.idx]);
mem::forget(self);
return Err(())
}
let ret = ManuallyDrop::into_inner(ptr::read(&mut self.array));
mem::forget(self);
Ok(ret)
}
}
}
impl <T, A> Drop for PartialArray<T, A>
where
A: Unsize<[T]>
{
fn drop(&mut self) {
unsafe {
let array: &mut A = &mut self.array;
let slice: &mut [T] = array;
ptr::drop_in_place::<[T]>(&mut slice[..self.idx]);
}
}
}
#[derive(Debug)]
struct Foo(usize);
impl Drop for Foo {
fn drop(&mut self) {
println!("dropping foo {}", self.0);
}
}
struct PanicIter {
n: usize
}
impl Iterator for PanicIter {
type Item = Foo;
fn next(&mut self) -> Option<Self::Item> {
self.n += 1;
if self.n == 5 { panic!() }
Some(Foo(self.n))
}
}
fn main() {
let mut paniciter = PanicIter { n: 0 };
unsafe {
let array: Result<[Foo; 10], ()> = PartialArray::new().from_iter(paniciter);
println!("{:?}", array.as_ref());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment