| //! Regression test for #142056. The drop check used to be more permissive for `let` statements with |
| //! `else` blocks, due to scheduling drops for bindings' storage before pattern-matching. |
| |
| struct Struct<T>(T); |
| impl<T> Drop for Struct<T> { |
| fn drop(&mut self) {} |
| } |
| |
| fn main() { |
| { |
| // This is an error: `short1` is dead before `long1` is dropped. |
| let (mut long1, short1) = (Struct(&0), 1); |
| long1.0 = &short1; |
| //~^ ERROR `short1` does not live long enough |
| } |
| { |
| // This was OK: `short2`'s storage was live until after `long2`'s drop ran. |
| #[expect(irrefutable_let_patterns)] |
| let (mut long2, short2) = (Struct(&0), 1) else { unreachable!() }; |
| long2.0 = &short2; |
| //~^ ERROR `short2` does not live long enough |
| } |
| { |
| // Sanity check: `short3`'s drop is significant; it's dropped before `long3`: |
| let tmp = Box::new(0); |
| #[expect(irrefutable_let_patterns)] |
| let (mut long3, short3) = (Struct(&tmp), Box::new(1)) else { unreachable!() }; |
| long3.0 = &short3; |
| //~^ ERROR `short3` does not live long enough |
| } |
| } |