about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2020-02-04 13:18:29 +0100
committerJonas Schievink <jonasschievink@gmail.com>2020-02-04 13:18:29 +0100
commit341eaf5f55c2fcf5f58a04cb4184306d0263b4f5 (patch)
treeb2392779d508a05ea551926beb76088e94b29b7f
parent392e59500a96be718383e127d38bf74300f521c0 (diff)
downloadrust-341eaf5f55c2fcf5f58a04cb4184306d0263b4f5.tar.gz
rust-341eaf5f55c2fcf5f58a04cb4184306d0263b4f5.zip
Add more tests for generator resume arguments
-rw-r--r--src/test/ui/generator/panic-drops-resume.rs35
-rw-r--r--src/test/ui/generator/resume-arg-late-bound.rs17
-rw-r--r--src/test/ui/generator/resume-arg-late-bound.stderr15
3 files changed, 67 insertions, 0 deletions
diff --git a/src/test/ui/generator/panic-drops-resume.rs b/src/test/ui/generator/panic-drops-resume.rs
new file mode 100644
index 00000000000..4a482d3f6df
--- /dev/null
+++ b/src/test/ui/generator/panic-drops-resume.rs
@@ -0,0 +1,35 @@
+//! Tests that panics inside a generator will correctly drop the initial resume argument.
+
+// run-pass
+
+#![feature(generators, generator_trait)]
+
+use std::ops::Generator;
+use std::panic::{catch_unwind, AssertUnwindSafe};
+use std::pin::Pin;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+static DROP: AtomicUsize = AtomicUsize::new(0);
+
+struct Dropper {}
+
+impl Drop for Dropper {
+    fn drop(&mut self) {
+        DROP.fetch_add(1, Ordering::SeqCst);
+    }
+}
+
+fn main() {
+    let mut gen = |_arg| {
+        if true {
+            panic!();
+        }
+        yield ();
+    };
+    let mut gen = Pin::new(&mut gen);
+
+    assert_eq!(DROP.load(Ordering::Acquire), 0);
+    let res = catch_unwind(AssertUnwindSafe(|| gen.as_mut().resume(Dropper {})));
+    assert!(res.is_err());
+    assert_eq!(DROP.load(Ordering::Acquire), 1);
+}
diff --git a/src/test/ui/generator/resume-arg-late-bound.rs b/src/test/ui/generator/resume-arg-late-bound.rs
new file mode 100644
index 00000000000..87b1f1a065b
--- /dev/null
+++ b/src/test/ui/generator/resume-arg-late-bound.rs
@@ -0,0 +1,17 @@
+//! Tests that we cannot produce a generator that accepts a resume argument
+//! with any lifetime and then stores it across a `yield`.
+
+#![feature(generators, generator_trait)]
+
+use std::ops::Generator;
+
+fn test(a: impl for<'a> Generator<&'a mut bool>) {}
+
+fn main() {
+    let gen = |arg: &mut bool| {
+        yield ();
+        *arg = true;
+    };
+    test(gen);
+    //~^ ERROR type mismatch in function arguments
+}
diff --git a/src/test/ui/generator/resume-arg-late-bound.stderr b/src/test/ui/generator/resume-arg-late-bound.stderr
new file mode 100644
index 00000000000..7719d5123f4
--- /dev/null
+++ b/src/test/ui/generator/resume-arg-late-bound.stderr
@@ -0,0 +1,15 @@
+error[E0631]: type mismatch in function arguments
+  --> $DIR/resume-arg-late-bound.rs:15:10
+   |
+LL | fn test(a: impl for<'a> Generator<&'a mut bool>) {}
+   |    ----         ------------------------------- required by this bound in `test`
+...
+LL |     test(gen);
+   |          ^^^
+   |          |
+   |          expected signature of `for<'a> fn(&'a mut bool) -> _`
+   |          found signature of `fn(&mut bool) -> _`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0631`.