aef0f4024a
And suggest adding the `#[coroutine]` to the closure
139 lines
2.6 KiB
Rust
139 lines
2.6 KiB
Rust
//@ build-pass
|
|
|
|
// A test to ensure coroutines capture values that were conditionally dropped,
|
|
// and also that values that are dropped along all paths to a yield do not get
|
|
// included in the coroutine type.
|
|
|
|
#![feature(coroutines, negative_impls, stmt_expr_attributes)]
|
|
#![allow(unused_assignments, dead_code)]
|
|
|
|
struct Ptr;
|
|
impl<'a> Drop for Ptr {
|
|
fn drop(&mut self) {}
|
|
}
|
|
|
|
struct NonSend;
|
|
impl !Send for NonSend {}
|
|
|
|
fn assert_send<T: Send>(_: T) {}
|
|
|
|
// This test case is reduced from tests/ui/drop/dynamic-drop-async.rs
|
|
fn one_armed_if(arg: bool) {
|
|
let _ = #[coroutine] || {
|
|
let arr = [Ptr];
|
|
if arg {
|
|
drop(arr);
|
|
}
|
|
yield;
|
|
};
|
|
}
|
|
|
|
fn two_armed_if(arg: bool) {
|
|
assert_send(#[coroutine] || {
|
|
let arr = [Ptr];
|
|
if arg {
|
|
drop(arr);
|
|
} else {
|
|
drop(arr);
|
|
}
|
|
yield;
|
|
})
|
|
}
|
|
|
|
fn if_let(arg: Option<i32>) {
|
|
let _ = #[coroutine] || {
|
|
let arr = [Ptr];
|
|
if let Some(_) = arg {
|
|
drop(arr);
|
|
}
|
|
yield;
|
|
};
|
|
}
|
|
|
|
fn init_in_if(arg: bool) {
|
|
assert_send(#[coroutine] || {
|
|
let mut x = NonSend;
|
|
drop(x);
|
|
if arg {
|
|
x = NonSend;
|
|
} else {
|
|
yield;
|
|
}
|
|
})
|
|
}
|
|
|
|
fn init_in_match_arm(arg: Option<i32>) {
|
|
assert_send(#[coroutine] || {
|
|
let mut x = NonSend;
|
|
drop(x);
|
|
match arg {
|
|
Some(_) => x = NonSend,
|
|
None => yield,
|
|
}
|
|
})
|
|
}
|
|
|
|
fn reinit() {
|
|
let _ = #[coroutine] || {
|
|
let mut arr = [Ptr];
|
|
drop(arr);
|
|
arr = [Ptr];
|
|
yield;
|
|
};
|
|
}
|
|
|
|
fn loop_uninit() {
|
|
let _ = #[coroutine] || {
|
|
let mut arr = [Ptr];
|
|
let mut count = 0;
|
|
drop(arr);
|
|
while count < 3 {
|
|
yield;
|
|
arr = [Ptr];
|
|
count += 1;
|
|
}
|
|
};
|
|
}
|
|
|
|
fn nested_loop() {
|
|
let _ = #[coroutine] || {
|
|
let mut arr = [Ptr];
|
|
let mut count = 0;
|
|
drop(arr);
|
|
while count < 3 {
|
|
for _ in 0..3 {
|
|
yield;
|
|
}
|
|
arr = [Ptr];
|
|
count += 1;
|
|
}
|
|
};
|
|
}
|
|
|
|
fn loop_continue(b: bool) {
|
|
let _ = #[coroutine] || {
|
|
let mut arr = [Ptr];
|
|
let mut count = 0;
|
|
drop(arr);
|
|
while count < 3 {
|
|
count += 1;
|
|
yield;
|
|
if b {
|
|
arr = [Ptr];
|
|
continue;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
fn main() {
|
|
one_armed_if(true);
|
|
if_let(Some(41));
|
|
init_in_if(true);
|
|
init_in_match_arm(Some(41));
|
|
reinit();
|
|
loop_uninit();
|
|
nested_loop();
|
|
loop_continue(true);
|
|
}
|