2021-11-03 18:28:07 -05:00
|
|
|
//@ build-pass
|
|
|
|
|
2023-10-19 16:46:28 -05:00
|
|
|
// A test to ensure coroutines capture values that were conditionally dropped,
|
2021-11-03 18:28:07 -05:00
|
|
|
// and also that values that are dropped along all paths to a yield do not get
|
2023-10-19 16:46:28 -05:00
|
|
|
// included in the coroutine type.
|
2021-11-03 18:28:07 -05:00
|
|
|
|
2023-10-19 16:46:28 -05:00
|
|
|
#![feature(coroutines, negative_impls)]
|
2021-11-03 18:28:07 -05:00
|
|
|
#![allow(unused_assignments, dead_code)]
|
|
|
|
|
|
|
|
struct Ptr;
|
|
|
|
impl<'a> Drop for Ptr {
|
|
|
|
fn drop(&mut self) {}
|
|
|
|
}
|
|
|
|
|
2021-11-04 18:38:47 -05:00
|
|
|
struct NonSend;
|
2021-11-03 18:28:07 -05:00
|
|
|
impl !Send for NonSend {}
|
|
|
|
|
|
|
|
fn assert_send<T: Send>(_: T) {}
|
|
|
|
|
2023-01-05 02:45:44 -06:00
|
|
|
// This test case is reduced from tests/ui/drop/dynamic-drop-async.rs
|
2021-11-03 18:28:07 -05:00
|
|
|
fn one_armed_if(arg: bool) {
|
|
|
|
let _ = || {
|
|
|
|
let arr = [Ptr];
|
|
|
|
if arg {
|
|
|
|
drop(arr);
|
|
|
|
}
|
|
|
|
yield;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
fn two_armed_if(arg: bool) {
|
|
|
|
assert_send(|| {
|
|
|
|
let arr = [Ptr];
|
|
|
|
if arg {
|
|
|
|
drop(arr);
|
|
|
|
} else {
|
|
|
|
drop(arr);
|
|
|
|
}
|
|
|
|
yield;
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn if_let(arg: Option<i32>) {
|
|
|
|
let _ = || {
|
|
|
|
let arr = [Ptr];
|
|
|
|
if let Some(_) = arg {
|
|
|
|
drop(arr);
|
|
|
|
}
|
|
|
|
yield;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-11-04 18:38:47 -05:00
|
|
|
fn init_in_if(arg: bool) {
|
|
|
|
assert_send(|| {
|
|
|
|
let mut x = NonSend;
|
|
|
|
drop(x);
|
|
|
|
if arg {
|
|
|
|
x = NonSend;
|
|
|
|
} else {
|
|
|
|
yield;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn init_in_match_arm(arg: Option<i32>) {
|
|
|
|
assert_send(|| {
|
|
|
|
let mut x = NonSend;
|
|
|
|
drop(x);
|
|
|
|
match arg {
|
|
|
|
Some(_) => x = NonSend,
|
|
|
|
None => yield,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-11-03 18:28:07 -05:00
|
|
|
fn reinit() {
|
|
|
|
let _ = || {
|
|
|
|
let mut arr = [Ptr];
|
|
|
|
drop(arr);
|
|
|
|
arr = [Ptr];
|
|
|
|
yield;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
fn loop_uninit() {
|
|
|
|
let _ = || {
|
|
|
|
let mut arr = [Ptr];
|
|
|
|
let mut count = 0;
|
|
|
|
drop(arr);
|
|
|
|
while count < 3 {
|
|
|
|
yield;
|
|
|
|
arr = [Ptr];
|
|
|
|
count += 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-11-04 18:38:47 -05:00
|
|
|
fn nested_loop() {
|
|
|
|
let _ = || {
|
|
|
|
let mut arr = [Ptr];
|
|
|
|
let mut count = 0;
|
|
|
|
drop(arr);
|
|
|
|
while count < 3 {
|
|
|
|
for _ in 0..3 {
|
|
|
|
yield;
|
|
|
|
}
|
|
|
|
arr = [Ptr];
|
|
|
|
count += 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-01-25 18:13:07 -06:00
|
|
|
fn loop_continue(b: bool) {
|
|
|
|
let _ = || {
|
|
|
|
let mut arr = [Ptr];
|
|
|
|
let mut count = 0;
|
|
|
|
drop(arr);
|
|
|
|
while count < 3 {
|
|
|
|
count += 1;
|
|
|
|
yield;
|
|
|
|
if b {
|
|
|
|
arr = [Ptr];
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-11-03 18:28:07 -05:00
|
|
|
fn main() {
|
|
|
|
one_armed_if(true);
|
|
|
|
if_let(Some(41));
|
2021-11-04 18:38:47 -05:00
|
|
|
init_in_if(true);
|
|
|
|
init_in_match_arm(Some(41));
|
2021-11-03 18:28:07 -05:00
|
|
|
reinit();
|
2021-11-04 12:56:07 -05:00
|
|
|
loop_uninit();
|
2021-11-04 18:38:47 -05:00
|
|
|
nested_loop();
|
2022-01-25 18:13:07 -06:00
|
|
|
loop_continue(true);
|
2021-11-03 18:28:07 -05:00
|
|
|
}
|