From 341eaf5f55c2fcf5f58a04cb4184306d0263b4f5 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 4 Feb 2020 13:18:29 +0100 Subject: [PATCH] Add more tests for generator resume arguments --- src/test/ui/generator/panic-drops-resume.rs | 35 +++++++++++++++++++ .../ui/generator/resume-arg-late-bound.rs | 17 +++++++++ .../ui/generator/resume-arg-late-bound.stderr | 15 ++++++++ 3 files changed, 67 insertions(+) create mode 100644 src/test/ui/generator/panic-drops-resume.rs create mode 100644 src/test/ui/generator/resume-arg-late-bound.rs create mode 100644 src/test/ui/generator/resume-arg-late-bound.stderr 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 000000000000..4a482d3f6df3 --- /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 000000000000..87b1f1a065bc --- /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 000000000000..7719d5123f46 --- /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`.