Temporary variable getting freed if Drop trait implementation is enabled

#[derive(Debug)]
struct Cat {}

// impl Drop for Cat {
//     fn drop(&mut self) {
//         println!("cat dropped");
//     }
// }

fn main() {
    let z;
    z = show(&Cat {}); // line 12
    println!("{:?}", z);
}

fn show<T>(k: &T) -> &T {
    k
}

in the above code if I enable "Drop trait implementation for Cat" I'm seeing below error

   z = show(&Cat {});
   |               ^^^^^^ - temporary value is freed at the end of this statement
   |               |
   |               creates a temporary which is freed while still in use

If I comment out that block I don't see any error. why is it so?

Define the show as fn show(c: &Cat) -> &Cat {c}, then due to lack of Cat's drop impl, it is actually

fn show(c: &'static Cat) -> &'static Cat {c}

since &Cat {} gets its constant promotion or rvalue static promotion or lifetime extension.

the promoted expression can be evaluated at compile-time and the resulting value does not contain interior mutability or destructors

Due to the existence of Cat's drop impl, now it can't get promoted.


Update: by saying

I mean they are the same thing:

To account for this, the const-eval WG agreed on the following terminology:

  • Making references have 'static lifetime is called "lifetime extension".
2 Likes

To help those helping you,

  • include the entire error
  • include functions like show

I agree with @vague that it's almost surely constant promotion. Adding a String to Cat probably produces the same error.

1 Like

edited the question.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.