diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2017-07-07 16:12:44 -0700 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2017-07-28 15:46:23 +0200 |
| commit | 5efb0cbe046127d074fd2c85b7cafb5a4d5aea44 (patch) | |
| tree | 6736bbaf8eac112a672735fcbb0106d1ecea624b /src/test/run-pass | |
| parent | 51bb31ad2551c0bf82a556792303ec1de5b76dbc (diff) | |
| download | rust-5efb0cbe046127d074fd2c85b7cafb5a4d5aea44.tar.gz rust-5efb0cbe046127d074fd2c85b7cafb5a4d5aea44.zip | |
Add some generator pass/fail tests
Diffstat (limited to 'src/test/run-pass')
| -rw-r--r-- | src/test/run-pass/generator/control-flow.rs | 56 | ||||
| -rw-r--r-- | src/test/run-pass/generator/drop-env.rs | 73 | ||||
| -rw-r--r-- | src/test/run-pass/generator/panic-drops.rs | 58 | ||||
| -rw-r--r-- | src/test/run-pass/generator/panic-safe.rs | 35 | ||||
| -rw-r--r-- | src/test/run-pass/generator/resume-after-return.rs | 33 | ||||
| -rw-r--r-- | src/test/run-pass/generator/smoke.rs | 187 |
6 files changed, 442 insertions, 0 deletions
diff --git a/src/test/run-pass/generator/control-flow.rs b/src/test/run-pass/generator/control-flow.rs new file mode 100644 index 00000000000..911bb96b582 --- /dev/null +++ b/src/test/run-pass/generator/control-flow.rs @@ -0,0 +1,56 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::{State, Generator}; + +fn finish<T>(mut amt: usize, mut t: T) -> T::Return + where T: Generator<(), Yield = ()> +{ + loop { + match t.resume(()) { + State::Yielded(()) => amt = amt.checked_sub(1).unwrap(), + State::Complete(ret) => { + assert_eq!(amt, 0); + return ret + } + } + } + +} + +fn main() { + finish(1, || yield); + finish(8, || { + for _ in 0..8 { + yield; + } + }); + finish(1, || { + if true { + yield; + } else { + } + }); + finish(1, || { + if false { + } else { + yield; + } + }); + finish(2, || { + if { yield; false } { + yield; + panic!() + } + yield + }); +} diff --git a/src/test/run-pass/generator/drop-env.rs b/src/test/run-pass/generator/drop-env.rs new file mode 100644 index 00000000000..43d0af7a073 --- /dev/null +++ b/src/test/run-pass/generator/drop-env.rs @@ -0,0 +1,73 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; + +static A: AtomicUsize = ATOMIC_USIZE_INIT; + +struct B; + +impl Drop for B { + fn drop(&mut self) { + A.fetch_add(1, Ordering::SeqCst); + } +} + +fn main() { + t1(); + t2(); + t3(); +} + +fn t1() { + let b = B; + let mut foo = || { + yield; + drop(b); + }; + + let n = A.load(Ordering::SeqCst); + drop(foo.resume(())); + assert_eq!(A.load(Ordering::SeqCst), n); + drop(foo); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + +fn t2() { + let b = B; + let mut foo = || { + yield b; + }; + + let n = A.load(Ordering::SeqCst); + drop(foo.resume(())); + assert_eq!(A.load(Ordering::SeqCst), n + 1); + drop(foo); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + +fn t3() { + let b = B; + let mut foo = || { + let _: () = gen arg; // TODO: this line should not be necessary + yield; + drop(b); + }; + + let n = A.load(Ordering::SeqCst); + assert_eq!(A.load(Ordering::SeqCst), n); + drop(foo); + // TODO: we should assert n+1 here, not n + // assert_eq!(A.load(Ordering::SeqCst), n + 1); + assert_eq!(A.load(Ordering::SeqCst), n); +} diff --git a/src/test/run-pass/generator/panic-drops.rs b/src/test/run-pass/generator/panic-drops.rs new file mode 100644 index 00000000000..6b9d7da197f --- /dev/null +++ b/src/test/run-pass/generator/panic-drops.rs @@ -0,0 +1,58 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::panic; +use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; + +static A: AtomicUsize = ATOMIC_USIZE_INIT; + +struct B; + +impl Drop for B { + fn drop(&mut self) { + A.fetch_add(1, Ordering::SeqCst); + } +} + +fn main() { + let b = B; + let mut foo = || { + if true { + panic!(); + } + drop(b); + yield; + }; + + assert_eq!(A.load(Ordering::SeqCst), 0); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + foo.resume(()) + })); + assert!(res.is_err()); + assert_eq!(A.load(Ordering::SeqCst), 1); + + let mut foo = || { + if true { + panic!(); + } + drop(B); + yield; + }; + + assert_eq!(A.load(Ordering::SeqCst), 1); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + foo.resume(()) + })); + assert!(res.is_err()); + assert_eq!(A.load(Ordering::SeqCst), 1); +} diff --git a/src/test/run-pass/generator/panic-safe.rs b/src/test/run-pass/generator/panic-safe.rs new file mode 100644 index 00000000000..7d86d7b6d94 --- /dev/null +++ b/src/test/run-pass/generator/panic-safe.rs @@ -0,0 +1,35 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::panic; + +fn main() { + let mut foo = || { + if true { + panic!(); + } + yield; + }; + + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + foo.resume(()) + })); + assert!(res.is_err()); + + for _ in 0..10 { + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + foo.resume(()) + })); + assert!(res.is_err()); + } +} diff --git a/src/test/run-pass/generator/resume-after-return.rs b/src/test/run-pass/generator/resume-after-return.rs new file mode 100644 index 00000000000..ca85d2545c8 --- /dev/null +++ b/src/test/run-pass/generator/resume-after-return.rs @@ -0,0 +1,33 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::{State, Generator}; +use std::panic; + +fn main() { + let mut foo = || { + if true { + return + } + yield; + }; + + match foo.resume(()) { + State::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + + match panic::catch_unwind(move || foo.resume(())) { + Ok(_) => panic!("generator successfully resumed"), + Err(_) => {} + } +} diff --git a/src/test/run-pass/generator/smoke.rs b/src/test/run-pass/generator/smoke.rs new file mode 100644 index 00000000000..daa32aa3213 --- /dev/null +++ b/src/test/run-pass/generator/smoke.rs @@ -0,0 +1,187 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --test + +#![feature(generators, generator_trait)] + +use std::ops::{State, Generator}; +use std::thread; + +#[test] +fn simple() { + let mut foo = || { + if false { + yield; + } + }; + + match foo.resume(()) { + State::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn return_capture() { + let a = String::from("foo"); + let mut foo = || { + if false { + yield; + } + a + }; + + match foo.resume(()) { + State::Complete(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn simple_yield() { + let mut foo = || { + yield; + }; + + match foo.resume(()) { + State::Yielded(()) => {} + s => panic!("bad state: {:?}", s), + } + match foo.resume(()) { + State::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn yield_capture() { + let b = String::from("foo"); + let mut foo = || { + yield b; + }; + + match foo.resume(()) { + State::Yielded(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } + match foo.resume(()) { + State::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn simple_yield_value() { + let mut foo = || { + yield String::from("bar"); + return String::from("foo") + }; + + match foo.resume(()) { + State::Yielded(ref s) if *s == "bar" => {} + s => panic!("bad state: {:?}", s), + } + match foo.resume(()) { + State::Complete(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn return_after_yield() { + let a = String::from("foo"); + let mut foo = || { + yield; + return a + }; + + match foo.resume(()) { + State::Yielded(()) => {} + s => panic!("bad state: {:?}", s), + } + match foo.resume(()) { + State::Complete(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn send_and_sync() { + assert_send_sync(|| { + let _: () = gen arg; + yield + }); + assert_send_sync(|| { + let _: () = gen arg; + yield String::from("foo"); + }); + assert_send_sync(|| { + let _: () = gen arg; + yield; + return String::from("foo"); + }); + let a = 3; + assert_send_sync(|| { + let _: () = gen arg; + yield a; + return + }); + let a = 3; + assert_send_sync(move || { + let _: () = gen arg; + yield a; + return + }); + let a = String::from("a"); + assert_send_sync(|| { + let _: () = gen arg; + yield ; + drop(a); + return + }); + let a = String::from("a"); + assert_send_sync(move || { + let _: () = gen arg; + yield ; + drop(a); + return + }); + + fn assert_send_sync<T: Send + Sync>(_: T) {} +} + +#[test] +fn send_over_threads() { + let mut foo = || { yield }; + thread::spawn(move || { + match foo.resume(()) { + State::Yielded(()) => {} + s => panic!("bad state: {:?}", s), + } + match foo.resume(()) { + State::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + }).join().unwrap(); + + let a = String::from("a"); + let mut foo = || { yield a }; + thread::spawn(move || { + match foo.resume(()) { + State::Yielded(ref s) if *s == "a" => {} + s => panic!("bad state: {:?}", s), + } + match foo.resume(()) { + State::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + }).join().unwrap(); +} |
