Use #![deny(elided_lifetimes_in_paths)]
and consider every lifetime you have to add.
// `self` is the only thing to borrow from, so not much to think about.
impl Database {
pub fn begin_write(&self) -> WriteTransaction<'_> {
// Only the first parameter is actually a borrow of `self`,
// `'txn` can be unconstrained since you just assign `None`
impl DbWrapper {
fn begin_write<'txn>(&self) -> MetaUseTransaction<'_, 'txn> {
And before fixing...
impl CacheTable<'_,'_> {
fn open(&mut self, use_transaction: &UseTransaction) {
That's a lot of lifetimes, let's just give them all names first so we get better errors.
impl<'db, 'txn> CacheTable<'db, 'txn> {
fn open<'s, 'b, 'u>(
&'s mut self,
use_transaction: &'b UseTransaction<'u>
) {
Ah yes, this makes sense, we need a &'txn UseTransaction<'db>
since we're trying to assign the argument to a field with those lifetimes.
// Fixed
impl<'db, 'txn> CacheTable<'db, 'txn> {
fn open(&mut self, use_transaction: &'txn UseTransaction<'db>) {
We're right back where this thread started: There's no safe way to create a self-referential struct such as this without exclusively borrowing yourself for the rest of your validity:
impl<'db, 'txn> MetaUseTransaction<'db, 'txn> {
// That's a `&'txn mut MetaUseTransaction<'db, 'txn>`
fn compute_some_thing(&'txn mut self) -> Result<(), ()> {
...and that won't work because you have a non-trivial destructor. (Even when you don't it's pretty much always too inflexible to be what you really want.)
The answer to "can I safely construct self-referential structs when there are non-trivial destructors involved" is no.