Given a trait Trait and a T: Trait, any &'a T can be split into a Lich<dyn Trait + 'static> and a Soul<'a> pair such that the dyn Trait can cross 'static boundaries while tracking the lifetime 'a.
In Brief
The general usage pattern of this library is:
- Choose a
Lich<T>/Soul<'a>variant for your use-case (see below for the tradeoffs). - Implement
Shroudfor the trait for which you want to extend the lifetime (a simple call toshroud!(Trait)is often all it takes). - Use the corresponding
ritual::<T: Trait, dyn Trait>(value: &'a T)to produce aLich<dyn Trait + 'static>bound to aSoul<'a>. - Use the
Lich<dyn Trait>as a'staticreference to your otherwise non-static&'a T. - Use the corresponding
redeem(Lich<T>, Soul<'a>)to guarantee that all references to&'a Tare dropped before the end of lifetime'a.
When Soul<'a> is dropped or when calling Soul::sever, it is guaranteed that the captured reference is also dropped, thus
inaccessible from a remaining Lich<T>.
Different variants exist with different tradeoffs:
phylactery::raw:- Is as lightweight as a new type around a pointer (no allocation).
- Does require the
Lich<T>to beredeemed (otherwise,Lich<T>andSoul<'a>will panic on drop). - Does require some
unsafecalls. Lich<T>can not be cloned.- Can be sent to other threads.
- Can be used in
#[no_std]contexts.
phylactery::cell:- Adds an indirection and minimal overhead using
Rc<RefCell>. - Allows for the use of the
Lich<T>/Soul<'a>::severmethods. - If a borrow still exists when the
Soul<'a>is dropped, the thread will panic. - Does not require the
Lich<T>es to beredeemed (although it is considered good practice to do so). - Does not require
unsafecalls. Lich<T>can be cloned.- Can not be sent to other threads.
- Adds an indirection and minimal overhead using
phylactery::lock:- Adds an indirection and some overhead using
Arc<RwLock>. - Allows for the use of the
Lich<T>/Soul<'a>::severmethods. - If a borrow still exists when the
Soul<'a>is dropped, the thread will block until the borrow expires (which can lead to dead locks). - Does not require the
Lich<T>to beredeemed (although it is considered good practice to do so). - Does not require
unsafecalls. Lich<T>can be cloned.- Can be sent to other threads.
- Adds an indirection and some overhead using
Since this library makes use of some unsafe code, all tests are run with miri to try to catch any unsoundness.
Cheat Sheet
/// Have a thread local scoped logger available from anywhere that can borrow
/// values that live on the stack.
/// Trivially reimplement `thread::scope` in a more powerful way.
See the examples and tests folder for more detailed examples.
Contribute
- If you find a bug or have a feature request, please open an issues.
phylacteryis actively maintained and pull requests are welcome.- If
phylacterywas useful to you, please consider leaving a star!