//@ 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, _ => (), } } }