| //@ run-pass | |
| //@ revisions: default nomiropt | |
| //@[nomiropt]compile-flags: -Z mir-opt-level=0 | |
| //@ needs-threads | |
| //@ compile-flags: --test | |
| #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] | |
| use std::ops::{CoroutineState, Coroutine}; | |
| use std::pin::Pin; | |
| use std::thread; | |
| #[test] | |
| fn simple() { | |
| let mut foo = #[coroutine] || { | |
| if false { | |
| yield; | |
| } | |
| }; | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Complete(()) => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| } | |
| #[test] | |
| fn return_capture() { | |
| let a = String::from("foo"); | |
| let mut foo = #[coroutine] || { | |
| if false { | |
| yield; | |
| } | |
| a | |
| }; | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Complete(ref s) if *s == "foo" => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| } | |
| #[test] | |
| fn simple_yield() { | |
| let mut foo = #[coroutine] || { | |
| yield; | |
| }; | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Yielded(()) => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Complete(()) => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| } | |
| #[test] | |
| fn yield_capture() { | |
| let b = String::from("foo"); | |
| let mut foo = #[coroutine] || { | |
| yield b; | |
| }; | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Yielded(ref s) if *s == "foo" => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Complete(()) => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| } | |
| #[test] | |
| fn simple_yield_value() { | |
| let mut foo = #[coroutine] || { | |
| yield String::from("bar"); | |
| return String::from("foo") | |
| }; | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Yielded(ref s) if *s == "bar" => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Complete(ref s) if *s == "foo" => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| } | |
| #[test] | |
| fn return_after_yield() { | |
| let a = String::from("foo"); | |
| let mut foo = #[coroutine] || { | |
| yield; | |
| return a | |
| }; | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Yielded(()) => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Complete(ref s) if *s == "foo" => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| } | |
| #[test] | |
| fn send_and_sync() { | |
| assert_send_sync(#[coroutine] || { | |
| yield | |
| }); | |
| assert_send_sync(#[coroutine] || { | |
| yield String::from("foo"); | |
| }); | |
| assert_send_sync(#[coroutine] || { | |
| yield; | |
| return String::from("foo"); | |
| }); | |
| let a = 3; | |
| assert_send_sync(#[coroutine] || { | |
| yield a; | |
| return | |
| }); | |
| let a = 3; | |
| assert_send_sync(#[coroutine] move || { | |
| yield a; | |
| return | |
| }); | |
| let a = String::from("a"); | |
| assert_send_sync(#[coroutine] || { | |
| yield ; | |
| drop(a); | |
| return | |
| }); | |
| let a = String::from("a"); | |
| assert_send_sync(#[coroutine] move || { | |
| yield ; | |
| drop(a); | |
| return | |
| }); | |
| fn assert_send_sync<T: Send + Sync>(_: T) {} | |
| } | |
| #[test] | |
| fn send_over_threads() { | |
| let mut foo = #[coroutine] || { yield }; | |
| thread::spawn(move || { | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Yielded(()) => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Complete(()) => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| }).join().unwrap(); | |
| let a = String::from("a"); | |
| let mut foo = #[coroutine] || { yield a }; | |
| thread::spawn(move || { | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Yielded(ref s) if *s == "a" => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| match Pin::new(&mut foo).resume(()) { | |
| CoroutineState::Complete(()) => {} | |
| s => panic!("bad state: {:?}", s), | |
| } | |
| }).join().unwrap(); | |
| } |