Lives - "lifetime-dynamic" smart pointers
⚓ Rust 📅 2026-01-13 👤 surdeus 👁️ 1The goal is to create even "weaker" weak pointer, to allow it "forget" some covariant lifetimes and get them checked at runtime instead. In this way, we can store weak pointers of even disjoint lifetimes in the same container.
I personally don't feel like being a veteran in rust development, so feel free to tell me and discuss if you've found anything wrong.
Main idea
The standard library one, std::rc::Weak<T<'a>>, must have lifetime 'a attached to it since it's possible to be upgraded back to a std::rc::Rc<T<'a>>, which truly holds T<'a> and thus the lifetime must be tracked.
The main idea is: For type T<'a> which is covariant over 'a,.our version has reference-counting strong pointer lives::LifeRc<T<'a>> and weak pointer lives::LifeWeak<T<'static>> downgraded from the former one. Unlike the standard library one, we forbid upgrading LifeWeak back to the stronger LifeRc. Alternatively, from the LifeWeak side, all operation to the underlying &T<'a> must be done in the closure provided to the LifeWeak::with function.
To operate on the underlying &T<'a> from the LifeWeak side, at least one living strong pointer LifeRc<T<'a>> must be witnessed and kept alive (while operating on &T<'a>). Since LifeRc<T<'a>> cannot outlives 'a, we use it as a signal of aliveness of 'a during execution of LifeWeak::with. The checking here is indeed "dynamic".
Prior to granting the closure access to the &T<'a>, since the lifetime is masked to 'static in LifeWeak<T<'static>>, we must reconstruct it to some &'b T<'b> for 'b fully contained in 'a (that is, 'a: 'b). Since T<'a> is covariant over 'a and 'a: 'b, the operation on &'b T<'b> is sound.
What about invariant and contravariant lifetimes?
As is said, the smart pointers are for "forgetting" covariant lifetimes. However, it's not sound to construct &T<'a> to &'b T<'b> if T is invariant or contravariant over 'a. In that case, they must be explicitly kept, e.g., LifeRc<T<'covariant, 'invariant, 'contravariant>> -> LifeWeak<T<'static, 'invariant, 'contravariant>>.
3 posts - 2 participants
🏷️ Rust_feed