]> git.lizzy.rs Git - rust.git/commitdiff
add a failing test where an immovable generator gets moved
authorRalf Jung <post@ralfj.de>
Fri, 21 Jun 2019 19:48:27 +0000 (21:48 +0200)
committerRalf Jung <post@ralfj.de>
Fri, 21 Jun 2019 19:48:27 +0000 (21:48 +0200)
tests/compile-fail/generator-pinned-moved.rs [new file with mode: 0644]

diff --git a/tests/compile-fail/generator-pinned-moved.rs b/tests/compile-fail/generator-pinned-moved.rs
new file mode 100644 (file)
index 0000000..2ae98ad
--- /dev/null
@@ -0,0 +1,44 @@
+#![feature(generators, generator_trait)]
+
+use std::{
+    ops::{Generator, GeneratorState},
+    pin::Pin,
+};
+
+fn firstn() -> impl Generator<Yield = u64, Return = ()> {
+    static move || {
+        let mut num = 0;
+        let num = &mut num;
+
+        yield *num;
+        *num += 1; //~ ERROR dangling pointer was dereferenced
+    }
+}
+
+struct GeneratorIteratorAdapter<G>(G);
+
+impl<G> Iterator for GeneratorIteratorAdapter<G>
+where
+    G: Generator<Return = ()>,
+{
+    type Item = G::Yield;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let me = unsafe { Pin::new_unchecked(&mut self.0) };
+        match me.resume() {
+            GeneratorState::Yielded(x) => Some(x),
+            GeneratorState::Complete(_) => None,
+        }
+    }
+}
+
+fn main() {
+    let mut generator_iterator_2 = {
+        let mut generator_iterator = GeneratorIteratorAdapter(firstn());
+        generator_iterator.next(); // pin it
+
+        generator_iterator // move it
+    }; // *deallocate* generator_iterator
+
+    generator_iterator_2.next(); // and use moved value
+}