aef0f4024a
And suggest adding the `#[coroutine]` to the closure
47 lines
1.0 KiB
Rust
47 lines
1.0 KiB
Rust
//@ run-pass
|
|
// Regression test for incorrect DropAndReplace behavior introduced in #60840
|
|
// and fixed in #61373. When combined with the optimization implemented in
|
|
// #60187, this produced incorrect code for coroutines when a saved local was
|
|
// re-assigned.
|
|
|
|
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
|
|
|
use std::ops::{Coroutine, CoroutineState};
|
|
use std::pin::Pin;
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
struct Foo(i32);
|
|
|
|
impl Drop for Foo {
|
|
fn drop(&mut self) {}
|
|
}
|
|
|
|
fn main() {
|
|
let mut a = #[coroutine]
|
|
|| {
|
|
let mut x = Foo(4);
|
|
yield;
|
|
assert_eq!(x.0, 4);
|
|
|
|
// At one point this tricked our dataflow analysis into thinking `x` was
|
|
// StorageDead after the assignment.
|
|
x = Foo(5);
|
|
assert_eq!(x.0, 5);
|
|
|
|
{
|
|
let y = Foo(6);
|
|
yield;
|
|
assert_eq!(y.0, 6);
|
|
}
|
|
|
|
assert_eq!(x.0, 5);
|
|
};
|
|
|
|
loop {
|
|
match Pin::new(&mut a).resume(()) {
|
|
CoroutineState::Complete(()) => break,
|
|
_ => (),
|
|
}
|
|
}
|
|
}
|