Ensure that the closure outlives the generator [breaking-change]
Previously, it was possible to cause unsafety by having the closure refer to values with lifetimes that weren't enclosed by the generator's lifetime.
This commit is contained in:
parent
adb29eade7
commit
59f28e92cb
|
@ -80,22 +80,22 @@ pub enum State {
|
||||||
/// println!("{:?}", nat.next()); // prints Some(2)
|
/// println!("{:?}", nat.next()); // prints Some(2)
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Generator<Input: Send, Output: Send, Stack: stack::Stack> {
|
pub struct Generator<'a, Input: Send, Output: Send, Stack: stack::Stack> {
|
||||||
state: State,
|
state: State,
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
stack_id: debug::StackId,
|
stack_id: debug::StackId,
|
||||||
stack_ptr: arch::StackPointer,
|
stack_ptr: arch::StackPointer,
|
||||||
phantom: PhantomData<(*mut Input, *const Output)>
|
phantom: PhantomData<(&'a (), *mut Input, *const Output)>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Input, Output, Stack> Generator<Input, Output, Stack>
|
impl<'a, Input, Output, Stack> Generator<'a, Input, Output, Stack>
|
||||||
where Input: Send, Output: Send, Stack: stack::Stack {
|
where Input: Send, Output: Send, Stack: stack::Stack {
|
||||||
/// Creates a new generator.
|
/// Creates a new generator.
|
||||||
///
|
///
|
||||||
/// See also the [contract](../trait.GuardedStack.html) that needs to be fulfilled by `stack`.
|
/// See also the [contract](../trait.GuardedStack.html) that needs to be fulfilled by `stack`.
|
||||||
pub fn new<F>(stack: Stack, f: F) -> Generator<Input, Output, Stack>
|
pub fn new<F>(stack: Stack, f: F) -> Generator<'a, Input, Output, Stack>
|
||||||
where Stack: stack::GuardedStack,
|
where Stack: stack::GuardedStack,
|
||||||
F: FnOnce(&mut Yielder<Input, Output>, Input) + Send {
|
F: FnOnce(&mut Yielder<Input, Output>, Input) + Send + 'a {
|
||||||
unsafe { Generator::unsafe_new(stack, f) }
|
unsafe { Generator::unsafe_new(stack, f) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +106,8 @@ impl<Input, Output, Stack> Generator<Input, Output, Stack>
|
||||||
/// guarded stacks do not exist, e.g. in absence of an MMU.
|
/// guarded stacks do not exist, e.g. in absence of an MMU.
|
||||||
///
|
///
|
||||||
/// See also the [contract](../trait.Stack.html) that needs to be fulfilled by `stack`.
|
/// See also the [contract](../trait.Stack.html) that needs to be fulfilled by `stack`.
|
||||||
pub unsafe fn unsafe_new<F>(stack: Stack, f: F) -> Generator<Input, Output, Stack>
|
pub unsafe fn unsafe_new<F>(stack: Stack, f: F) -> Generator<'a, Input, Output, Stack>
|
||||||
where F: FnOnce(&mut Yielder<Input, Output>, Input) + Send {
|
where F: FnOnce(&mut Yielder<Input, Output>, Input) + Send + 'a {
|
||||||
unsafe extern "C" fn generator_wrapper<Input, Output, Stack, F>(env: usize, stack_ptr: StackPointer) -> !
|
unsafe extern "C" fn generator_wrapper<Input, Output, Stack, F>(env: usize, stack_ptr: StackPointer) -> !
|
||||||
where Input: Send, Output: Send, Stack: stack::Stack,
|
where Input: Send, Output: Send, Stack: stack::Stack,
|
||||||
F: FnOnce(&mut Yielder<Input, Output>, Input) {
|
F: FnOnce(&mut Yielder<Input, Output>, Input) {
|
||||||
|
@ -218,7 +218,7 @@ impl<Input, Output> Yielder<Input, Output>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Output, Stack> Iterator for Generator<(), Output, Stack>
|
impl<'a, Output, Stack> Iterator for Generator<'a, (), Output, Stack>
|
||||||
where Output: Send, Stack: stack::Stack {
|
where Output: Send, Stack: stack::Stack {
|
||||||
type Item = Output;
|
type Item = Output;
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn add_one_fn(yielder: &mut Yielder<i32, i32>, mut input: i32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_add_one() -> Generator<i32, i32, OsStack> {
|
fn new_add_one() -> Generator<'static, i32, i32, OsStack> {
|
||||||
let stack = OsStack::new(0).unwrap();
|
let stack = OsStack::new(0).unwrap();
|
||||||
Generator::new(stack, add_one_fn)
|
Generator::new(stack, add_one_fn)
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ fn move_after_new() {
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn panic_safety() {
|
fn panic_safety() {
|
||||||
struct Wrapper {
|
struct Wrapper {
|
||||||
gen: Generator<(), (), OsStack>
|
gen: Generator<'static, (), (), OsStack>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Wrapper {
|
impl Drop for Wrapper {
|
||||||
|
|
Loading…
Reference in New Issue