Why can I drop an object with a 'static lifetime?

Viewed 54

I have the following code where I am storing an App inside a Mutex and an Arc but I also want to be able to swap this App out at any point during runtime. And the following code seems to work just fine.

However, even though the App is marked 'static inside the static declaration and inside the set_app function, I am able to swap the underlying App out without issue. Plus the original App inside the Mutex gets dropped, even though it was marked 'static.

Apologies as I'm new to Rust but clearly I'm missing something. In my mind if an object is able to go out of scope and be dropped it isn't 'static. Why does this work?

Source:

use std::sync::{Mutex, Arc};
use lazy_static::lazy_static;

lazy_static! {
    pub static ref APP: Arc<Mutex<App<'static>>> = Arc::new(Mutex::new(App { name: "App" }));
}

pub struct App<'a> {
    name: &'a str,
}

impl<'a> Drop for App<'a> {
    fn drop(&mut self) {
        println!("DROPPING {}", self.name)
    }
}

fn main() {
    println!("CURRENT {}", APP.lock().unwrap().name);

    // Drops "App1"
    *APP.lock().unwrap() = App { name: "App2" };
    
    println!("CURRENT {}", APP.lock().unwrap().name);
    
    // Drops "App2"
    set_app(App { name: "App3" });
    
    println!("CURRENT {}", APP.lock().unwrap().name);
}

fn set_app(app: App<'static>) {
    *APP.lock().unwrap() = app;
}

Output:

CURRENT App
DROPPING App
CURRENT App2
DROPPING App2
CURRENT App3
1 Answers

The 'static lifetime does not mean "this value will live for the entire duration of the program". It means "this value can live for the entire duration of the program". That is, it does not contain any references that will drop earlier. However, it is perfectly fine to drop a 'static object.

See also: Common Rust Lifetime Misconceptions: if T: 'static then T must be valid for the entire program.

For example, String is 'static because it does not point to any external resource - thus, if you don't drop it, it'll live happily until the end of the program. However, we drop and free Strings all the time - it is just that if I have a String, and I don't drop it, it won't be dropped behind my back, unlike say a reference.

Related