]> git.lizzy.rs Git - rust.git/commitdiff
try even harder to catch invalid generator fields
authorRalf Jung <post@ralfj.de>
Tue, 3 Mar 2020 14:00:19 +0000 (15:00 +0100)
committerRalf Jung <post@ralfj.de>
Tue, 3 Mar 2020 14:02:06 +0000 (15:02 +0100)
tests/run-pass/generator.rs

index e85d2cf8f29a8006a5ea23185f1784ed26ec85bb..18eaf5e55c15d0bbbfcd31cac900a637060f2a67 100644 (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())) };
         }
     }