Auto merge of #1203 - RalfJung:generator, r=RalfJung

try even harder to catch invalid generator fields
This commit is contained in:
bors
2020-03-03 14:02:55 +00:00
+11 -2
View File
@@ -4,6 +4,8 @@
use std::pin::Pin;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::fmt::Debug;
use std::mem::ManuallyDrop;
use std::ptr;
fn basic() {
fn finish<T>(mut amt: usize, mut t: T) -> T::Return
@@ -12,8 +14,13 @@ fn finish<T>(mut amt: usize, mut t: T) -> T::Return
// We are not moving the `t` around until it gets dropped, so this is okay.
let mut t = unsafe { Pin::new_unchecked(&mut t) };
loop {
match t.as_mut().resume(()) {
GeneratorState::Yielded(y) => amt -= y,
let state = t.as_mut().resume(());
// Test if the generator is valid (according to type invariants).
let _ = unsafe { ManuallyDrop::new(ptr::read(t.as_mut().get_unchecked_mut())) };
match state {
GeneratorState::Yielded(y) => {
amt -= y;
}
GeneratorState::Complete(ret) => {
assert_eq!(amt, 0);
return ret
@@ -109,6 +116,8 @@ fn drain<G: Generator<R, Yield = Y> + Unpin, R, Y>(
for (input, out) in inout {
assert_eq!(gen.as_mut().resume(input), out);
// Test if the generator is valid (according to type invariants).
let _ = unsafe { ManuallyDrop::new(ptr::read(gen.as_mut().get_unchecked_mut())) };
}
}