The 'static lifetime plays a very special role in today’s Rust. Some API’s depends (Any for example) on it to work, and it is considered where leaked memory will be sit in, as we don’t currently support leak free memory managements.
This proposal introduce a keyword initially named leakproof (suggest a better name!) that
- It appears in front of blocks or function bodies like a
unsafe keyword. Not sure about the sementics if we have it in traits yet.
- Inside the
leakproof block/function it decorates, any values being created before or in the top scope have lifetime being promoted to 'static, but still get dropped after the block/function body, as usual
- Any reference to
'static inside a leakproff scope (directally or indirectally) refer to the innermost leakproof scope.
-
std::mem::forget will only delay the drop clue to the exist of the leakproof block.
-
Box::leak is also only delay the drop clue unless Box::from_raw being used on its result.
- Any threads creaded inside a
leakproof block will be killed on exit, to resolve leaks caused by deadlock.
Motivations
Dynamic code loading
Technically, 'static only makes sense if all code are loaded statically. If we are going to load/unload dynamic code, the 'static lifetime in the loaded code is only relative to the load/unload operation. This is not a problem today because we only support dynamic load through FFI and foreign functions does not support lifetimes. But my dream is rdylib: loading Rust only code dynamically!
Needless to say, 'static is in fact relative to the process!
Lifetime extension of FFI
Introducing lifetime in FFI will make it possible to interact with foreign languages that is also supports lifetimes. This is not too common at the moment, but would be a future proof.
Lifetime in RPC APIs
When designing RPC APIs, the object’s lifetime can naturally outlives 'static (relative to the process): a server may use 'session lifetimes that outlives the client’s 'static, as it can remain valid after the client restarts.
Memory leaking control
For the same reason, in reality memory leaking programs were controlled by manually killing the processes. If we do have relative 'static lifetimes, we can do it programatically.
Making APIs more usable
Allowing APIs like Any available to types other than being strictly 'static.
Simplify code that using a fixed set of long living lifetimes
rustc itself uses a few lifetimes that lives for long enough to take benefit to making it relatively 'static.
Implemention thoughts
I guess the best implementation strategy is to introduce a new region for each leakproof blocks, and the lifetime erasure procedure simply ignore them and let monomorphization generate different versions for them.
Drawbacks
- One more keyword
- Code size explode - if we use the implementation strategy I described above
Alternatives
- Do nothing if we don’t want to support native dynamic code loading ever
- Instead of promoting everything to
'static use a lifetime 'persist and have every lifetime longer than 'persist being stay after lifetime erasure and relax the restriction of API for Any to be 'persist (more to discuss)
Unresolved issues
- The exact behavior for panic/unwinding
- Interaction between variables inside and outside a
leakproof block - shall we disable storing any values created inside to an outside reference if it is not Copy?