Panic when an unfinished Generator is dropped

master
edef 2017-02-25 23:43:08 +01:00
parent 4813dd7411
commit 277e786d3f
4 changed files with 9 additions and 1 deletions

View File

@ -8,6 +8,7 @@
extern crate test; extern crate test;
extern crate fringe; extern crate fringe;
use std::mem;
use fringe::{OsStack, Generator}; use fringe::{OsStack, Generator};
#[bench] #[bench]
@ -18,4 +19,5 @@ fn generate(b: &mut test::Bencher) {
}); });
b.iter(|| for _ in 0..10 { test::black_box(identity.resume(test::black_box(0))); }); b.iter(|| for _ in 0..10 { test::black_box(identity.resume(test::black_box(0))); });
mem::forget(identity);
} }

View File

@ -70,6 +70,7 @@ pub enum State {
/// ///
/// ``` /// ```
/// use fringe::{OsStack, Generator}; /// use fringe::{OsStack, Generator};
/// use std::mem;
/// ///
/// let stack = OsStack::new(0).unwrap(); /// let stack = OsStack::new(0).unwrap();
/// let mut nat = Generator::new(stack, move |yielder, ()| { /// let mut nat = Generator::new(stack, move |yielder, ()| {
@ -78,6 +79,7 @@ pub enum State {
/// println!("{:?}", nat.next()); // prints Some(0) /// println!("{:?}", nat.next()); // prints Some(0)
/// println!("{:?}", nat.next()); // prints Some(1) /// println!("{:?}", nat.next()); // prints Some(1)
/// println!("{:?}", nat.next()); // prints Some(2) /// println!("{:?}", nat.next()); // prints Some(2)
/// mem::forget(nat); // we can't drop a running Generator, so we leak it
/// ``` /// ```
#[derive(Debug)] #[derive(Debug)]
pub struct Generator<'a, Input: 'a, Output: 'a, Stack: stack::Stack> { pub struct Generator<'a, Input: 'a, Output: 'a, Stack: stack::Stack> {
@ -213,7 +215,7 @@ impl<'a, Input, Output, Stack> Drop for Generator<'a, Input, Output, Stack>
unsafe { unsafe {
ptr::drop_in_place(&mut self.stack_id.value); ptr::drop_in_place(&mut self.stack_id.value);
match self.state { match self.state {
State::Runnable => {} // leak the stack State::Runnable => panic!("dropped unfinished Generator"),
State::Unavailable => ptr::drop_in_place(&mut self.stack.value) State::Unavailable => ptr::drop_in_place(&mut self.stack.value)
} }
} }

View File

@ -73,6 +73,7 @@ fn with_slice_stack() {
let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) }; let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
assert_eq!(add_one.resume(1), Some(2)); assert_eq!(add_one.resume(1), Some(2));
assert_eq!(add_one.resume(2), Some(3)); assert_eq!(add_one.resume(2), Some(3));
assert_eq!(add_one.resume(0), None);
} }
#[test] #[test]
@ -81,6 +82,7 @@ fn with_owned_stack() {
let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) }; let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
assert_eq!(add_one.resume(1), Some(2)); assert_eq!(add_one.resume(1), Some(2));
assert_eq!(add_one.resume(2), Some(3)); assert_eq!(add_one.resume(2), Some(3));
assert_eq!(add_one.resume(0), None);
} }
#[test] #[test]

View File

@ -8,6 +8,7 @@ extern crate fringe;
use fringe::OsStack; use fringe::OsStack;
use fringe::generator::Generator; use fringe::generator::Generator;
use std::mem;
#[test] #[test]
fn producer() { fn producer() {
@ -18,4 +19,5 @@ fn producer() {
assert_eq!(gen.next(), Some(0)); assert_eq!(gen.next(), Some(0));
assert_eq!(gen.next(), Some(1)); assert_eq!(gen.next(), Some(1));
assert_eq!(gen.next(), Some(2)); assert_eq!(gen.next(), Some(2));
mem::forget(gen);
} }