File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -369,7 +369,8 @@ macro_rules! dbg {
369369/// E.g. `dbg_internal!(() () (1, 2))` expands into
370370/// ```rust, ignore
371371/// match (1, 2) {
372- /// (tmp_1, tmp_2) => {
372+ /// args => {
373+ /// let (tmp_1, tmp_2) = args;
373374/// eprint!("...", &tmp_1, &tmp_2, /* some other arguments */);
374375/// (tmp_1, tmp_2)
375376/// }
@@ -385,7 +386,9 @@ pub macro dbg_internal {
385386 // of temporaries - https://stackoverflow.com/a/48732525/1063961
386387 // Always put the arguments in a tuple to avoid an unused parens lint on the pattern.
387388 match ( $( $processed, ) +) {
388- ( $( $bound, ) +) => {
389+ // Move the entire tuple so it doesn't stick around as a temporary (#154988).
390+ args => {
391+ let ( $( $bound, ) +) = args;
389392 $crate:: eprint!(
390393 $crate :: concat!( $( $piece) , +) ,
391394 $(
Original file line number Diff line number Diff line change 11// ignore-tidy-dbg
22
3+ use core:: fmt:: Debug ;
4+
35/// Test for <https://github.com/rust-lang/rust/issues/153850>:
46/// `dbg!` shouldn't drop arguments' temporaries.
57#[ test]
@@ -11,3 +13,25 @@ fn no_dropping_temps() {
1113 * dbg ! ( 0 , & temp( ) ) . 1 ;
1214 * dbg ! ( 0 , & temp( ) , 2 ) . 1 ;
1315}
16+
17+ /// Test for <https://github.com/rust-lang/rust/issues/154988>:
18+ /// `dbg!` shouldn't create a temporary that lives past its invocation.
19+ #[ test]
20+ fn no_leaking_internal_temps_from_dbg ( ) {
21+ #[ derive( Debug ) ]
22+ struct Foo ;
23+
24+ #[ derive( Debug ) ]
25+ struct Bar < ' a > ( #[ allow( unused) ] & ' a Foo ) ;
26+ impl Drop for Bar < ' _ > {
27+ fn drop ( & mut self ) { }
28+ }
29+
30+ let foo = Foo ;
31+ let bar = Bar ( & foo) ;
32+ // If `dbg!` creates a `(Bar<'_>,)` temporary that lasts past its expansion, this will fail
33+ // to compile, because it will be dropped after `foo`, which it borrows from. The tuple
34+ // mimics the drop order of block tail expressions before Rust 2024: first the result of `dbg!`
35+ // is dropped, then `foo`, then any temporaries left over from `dbg!` are dropped, if present.
36+ ( drop ( dbg ! ( bar) ) , drop ( foo) ) ;
37+ }
You can’t perform that action at this time.
0 commit comments