Closed
Description
Currently, Rust forbids statics from containing types with destructors:
struct Foo;
impl Drop for Foo {
fn drop(&mut self) {}
}
static FOO: Foo = Foo;
error: statics are not allowed to have destructors
This was historically motivated by the question of when to run the destructor:
- There where worries about supporting life before/after
main()
for, eg, static variables due to them having historically caused trouble in, eg, C++ code bases. - Leaking the destructor was also for the most time not known to be a feasible option due to leaking possibly being bad.
The conservative choice was to forbid such types outright until a decision could be reached.
However, a lot has happened since then:
- Rusts runtime basically disappeared, with no noteworthy amount of code running before/after
main()
anymore. - With RFC: Alter mem::forget to be safe #1066 accepted the language now defines leaking as being safe and allows it in certain circumstances.
Informally, language semantic and idiomatic code now shifted into this position:
- No user code will run before/after
main()
, and all initialization/deinitialization needs to happen in it. - Leaking destructors is ok if the object lives infinitely long (RC circle,
Box<T> -> &'static T
)
In keeping with that trend, the language semantic should be changed as follows:
- It is allowed to store a type with a destructor in a static variable.
- Values in static variables will never have their destructors run automatically.
The benefit would be more freedom around static variables.
As a concrete use case, this change would allow lazy_static to work without requiring a heap allocation. (It currently uses a raw pointer to a heap allocation in a mutable static to get around the destructor issue)