2018-09-06 14:41:12 +02:00
|
|
|
// run-pass
|
|
|
|
|
2020-04-28 08:22:08 +02:00
|
|
|
// revisions: default nomiropt
|
|
|
|
//[nomiropt]compile-flags: -Z mir-opt-level=0
|
|
|
|
|
2017-10-17 18:45:42 -07:00
|
|
|
// ignore-emscripten no threads support
|
2017-07-07 16:12:44 -07:00
|
|
|
// compile-flags: --test
|
|
|
|
|
2023-10-19 21:46:28 +00:00
|
|
|
#![feature(coroutines, coroutine_trait)]
|
2017-07-07 16:12:44 -07:00
|
|
|
|
2023-10-19 16:06:43 +00:00
|
|
|
use std::ops::{CoroutineState, Coroutine};
|
2018-10-04 20:49:38 +02:00
|
|
|
use std::pin::Pin;
|
2017-07-07 16:12:44 -07:00
|
|
|
use std::thread;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn simple() {
|
|
|
|
let mut foo = || {
|
|
|
|
if false {
|
|
|
|
yield;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Complete(()) => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn return_capture() {
|
|
|
|
let a = String::from("foo");
|
|
|
|
let mut foo = || {
|
|
|
|
if false {
|
|
|
|
yield;
|
|
|
|
}
|
|
|
|
a
|
|
|
|
};
|
|
|
|
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Complete(ref s) if *s == "foo" => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn simple_yield() {
|
|
|
|
let mut foo = || {
|
|
|
|
yield;
|
|
|
|
};
|
|
|
|
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Yielded(()) => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Complete(()) => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn yield_capture() {
|
|
|
|
let b = String::from("foo");
|
|
|
|
let mut foo = || {
|
|
|
|
yield b;
|
|
|
|
};
|
|
|
|
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Yielded(ref s) if *s == "foo" => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Complete(()) => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn simple_yield_value() {
|
|
|
|
let mut foo = || {
|
|
|
|
yield String::from("bar");
|
|
|
|
return String::from("foo")
|
|
|
|
};
|
|
|
|
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Yielded(ref s) if *s == "bar" => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Complete(ref s) if *s == "foo" => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn return_after_yield() {
|
|
|
|
let a = String::from("foo");
|
|
|
|
let mut foo = || {
|
|
|
|
yield;
|
|
|
|
return a
|
|
|
|
};
|
|
|
|
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Yielded(()) => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Complete(ref s) if *s == "foo" => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn send_and_sync() {
|
|
|
|
assert_send_sync(|| {
|
|
|
|
yield
|
|
|
|
});
|
|
|
|
assert_send_sync(|| {
|
|
|
|
yield String::from("foo");
|
|
|
|
});
|
|
|
|
assert_send_sync(|| {
|
|
|
|
yield;
|
|
|
|
return String::from("foo");
|
|
|
|
});
|
|
|
|
let a = 3;
|
|
|
|
assert_send_sync(|| {
|
|
|
|
yield a;
|
|
|
|
return
|
|
|
|
});
|
|
|
|
let a = 3;
|
|
|
|
assert_send_sync(move || {
|
|
|
|
yield a;
|
|
|
|
return
|
|
|
|
});
|
|
|
|
let a = String::from("a");
|
|
|
|
assert_send_sync(|| {
|
|
|
|
yield ;
|
|
|
|
drop(a);
|
|
|
|
return
|
|
|
|
});
|
|
|
|
let a = String::from("a");
|
|
|
|
assert_send_sync(move || {
|
|
|
|
yield ;
|
|
|
|
drop(a);
|
|
|
|
return
|
|
|
|
});
|
|
|
|
|
|
|
|
fn assert_send_sync<T: Send + Sync>(_: T) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn send_over_threads() {
|
|
|
|
let mut foo = || { yield };
|
|
|
|
thread::spawn(move || {
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Yielded(()) => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Complete(()) => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
|
|
|
}).join().unwrap();
|
|
|
|
|
|
|
|
let a = String::from("a");
|
|
|
|
let mut foo = || { yield a };
|
|
|
|
thread::spawn(move || {
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Yielded(ref s) if *s == "a" => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
2020-01-25 20:03:10 +01:00
|
|
|
match Pin::new(&mut foo).resume(()) {
|
2023-10-19 16:06:43 +00:00
|
|
|
CoroutineState::Complete(()) => {}
|
2017-07-07 16:12:44 -07:00
|
|
|
s => panic!("bad state: {:?}", s),
|
|
|
|
}
|
|
|
|
}).join().unwrap();
|
|
|
|
}
|