From 277e786d3fec3174c714c35c28062cd6ae76b771 Mon Sep 17 00:00:00 2001 From: edef Date: Sat, 25 Feb 2017 23:43:08 +0100 Subject: [PATCH] Panic when an unfinished Generator is dropped --- benches/generator.rs | 2 ++ src/generator.rs | 4 +++- tests/generator.rs | 2 ++ tests/iterator.rs | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/benches/generator.rs b/benches/generator.rs index bbc5f76..accb631 100644 --- a/benches/generator.rs +++ b/benches/generator.rs @@ -8,6 +8,7 @@ extern crate test; extern crate fringe; +use std::mem; use fringe::{OsStack, Generator}; #[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))); }); + mem::forget(identity); } diff --git a/src/generator.rs b/src/generator.rs index 2a9ca4b..b2ba5f5 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -70,6 +70,7 @@ pub enum State { /// /// ``` /// use fringe::{OsStack, Generator}; +/// use std::mem; /// /// let stack = OsStack::new(0).unwrap(); /// 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(1) /// println!("{:?}", nat.next()); // prints Some(2) +/// mem::forget(nat); // we can't drop a running Generator, so we leak it /// ``` #[derive(Debug)] 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 { ptr::drop_in_place(&mut self.stack_id.value); match self.state { - State::Runnable => {} // leak the stack + State::Runnable => panic!("dropped unfinished Generator"), State::Unavailable => ptr::drop_in_place(&mut self.stack.value) } } diff --git a/tests/generator.rs b/tests/generator.rs index 002615b..d230153 100644 --- a/tests/generator.rs +++ b/tests/generator.rs @@ -73,6 +73,7 @@ fn with_slice_stack() { 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(2), Some(3)); + assert_eq!(add_one.resume(0), None); } #[test] @@ -81,6 +82,7 @@ fn with_owned_stack() { 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(2), Some(3)); + assert_eq!(add_one.resume(0), None); } #[test] diff --git a/tests/iterator.rs b/tests/iterator.rs index 6a51b38..c09ef16 100644 --- a/tests/iterator.rs +++ b/tests/iterator.rs @@ -8,6 +8,7 @@ extern crate fringe; use fringe::OsStack; use fringe::generator::Generator; +use std::mem; #[test] fn producer() { @@ -18,4 +19,5 @@ fn producer() { assert_eq!(gen.next(), Some(0)); assert_eq!(gen.next(), Some(1)); assert_eq!(gen.next(), Some(2)); + mem::forget(gen); }