| // ignore-tidy-dbg | |
| use core::fmt::Debug; | |
| /// Test for <https://github.com/rust-lang/rust/issues/153850>: | |
| /// `dbg!` shouldn't drop arguments' temporaries. | |
| #[test] | |
| fn no_dropping_temps() { | |
| fn temp() {} | |
| *dbg!(&temp()); | |
| *dbg!(&temp(), 1).0; | |
| *dbg!(0, &temp()).1; | |
| *dbg!(0, &temp(), 2).1; | |
| } | |
| /// Test for <https://github.com/rust-lang/rust/issues/154988>: | |
| /// `dbg!` shouldn't create a temporary that lives past its invocation. | |
| #[test] | |
| fn no_leaking_internal_temps_from_dbg() { | |
| #[derive(Debug)] | |
| struct Foo; | |
| #[derive(Debug)] | |
| struct Bar<'a>(#[allow(unused)] &'a Foo); | |
| impl Drop for Bar<'_> { | |
| fn drop(&mut self) {} | |
| } | |
| let foo = Foo; | |
| let bar = Bar(&foo); | |
| // If `dbg!` creates a `(Bar<'_>,)` temporary that lasts past its expansion, this will fail | |
| // to compile, because it will be dropped after `foo`, which it borrows from. The tuple | |
| // mimics the drop order of block tail expressions before Rust 2024: first the result of `dbg!` | |
| // is dropped, then `foo`, then any temporaries left over from `dbg!` are dropped, if present. | |
| (drop(dbg!(bar)), drop(foo)); | |
| } |