From 17c41ce777a8484213b024d9ac3b6395fa8b188c Mon Sep 17 00:00:00 2001 From: edef Date: Fri, 8 Dec 2017 12:42:17 -0500 Subject: [PATCH] Use core::mem::ManuallyDrop instead of implementing our own NoDrop --- src/generator.rs | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/src/generator.rs b/src/generator.rs index e8adb8f..ad1ad4b 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -14,6 +14,7 @@ use core::marker::PhantomData; use core::{ptr, mem}; use core::cell::Cell; +use core::mem::ManuallyDrop; use stack; use debug; @@ -84,26 +85,12 @@ pub enum State { #[derive(Debug)] pub struct Generator<'a, Input: 'a, Output: 'a, Stack: stack::Stack> { state: State, - stack: NoDrop, - stack_id: NoDrop, + stack: ManuallyDrop, + stack_id: ManuallyDrop, stack_ptr: arch::StackPointer, phantom: PhantomData<(&'a (), *mut Input, *const Output)> } -#[allow(unions_with_drop_fields)] -union NoDrop { - inner: T -} - -impl ::core::fmt::Debug for NoDrop { - fn fmt(&self, w: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - unsafe { - // this is safe because we never invoke formatting on the empty variant - self.inner.fmt(w) - } - } -} - impl<'a, Input, Output, Stack> Generator<'a, Input, Output, Stack> where Input: 'a, Output: 'a, Stack: stack::Stack { /// Creates a new generator. @@ -147,8 +134,8 @@ impl<'a, Input, Output, Stack> Generator<'a, Input, Output, Stack> Generator { state: State::Runnable, - stack: NoDrop { inner: stack }, - stack_id: NoDrop { inner: stack_id }, + stack: ManuallyDrop::new(stack), + stack_id: ManuallyDrop::new(stack_id), stack_ptr: stack_ptr, phantom: PhantomData } @@ -167,7 +154,7 @@ impl<'a, Input, Output, Stack> Generator<'a, Input, Output, Stack> // Switch to the generator function, and retrieve the yielded value. let val = unsafe { - let (data_out, stack_ptr) = arch::swap(&input as *const Input as usize, self.stack_ptr, Some(&self.stack.inner)); + let (data_out, stack_ptr) = arch::swap(&input as *const Input as usize, self.stack_ptr, Some(&*self.stack)); self.stack_ptr = stack_ptr; mem::forget(input); ptr::read(data_out as *const Option) @@ -203,8 +190,8 @@ impl<'a, Input, Output, Stack> Generator<'a, Input, Output, Stack> /// Extracts the stack from a generator without checking if the generator function has returned. /// This will leave any pointers into the generator stack dangling, and won't run destructors. pub unsafe fn unsafe_unwrap(mut self) -> Stack { - ptr::drop_in_place(&mut self.stack_id.inner); - let stack = ptr::read(&mut self.stack.inner); + ManuallyDrop::drop(&mut self.stack_id); + let stack = ptr::read(&mut *self.stack); mem::forget(self); stack } @@ -214,10 +201,10 @@ impl<'a, Input, Output, Stack> Drop for Generator<'a, Input, Output, Stack> where Input: 'a, Output: 'a, Stack: stack::Stack { fn drop(&mut self) { unsafe { - ptr::drop_in_place(&mut self.stack_id.inner); + ManuallyDrop::drop(&mut self.stack_id); match self.state { State::Runnable => panic!("dropped unfinished Generator"), - State::Unavailable => ptr::drop_in_place(&mut self.stack.inner) + State::Unavailable => ManuallyDrop::drop(&mut self.stack) } } }