I'm trying to implement Implement Deref to ReadTransaction for the write Transaction type in possum-db: possum/src/tx.rs at 7d660fa365f8d0b4e61915eb109fc9690a2c810d · anacrolix/possum · GitHub
This gives me
error: lifetime may not live long enough
--> src/tx.rs:181:13
|
176 | impl<'h> Deref for Transaction<'h> {
| -- lifetime `'h` defined here
...
179 | fn deref(&self) -> &Self::Target {
| - let's call the lifetime of this reference `'1`
180 | unsafe {
181 | / &ReadTransaction {
182 | | tx: ReadOnlyRusqliteTransaction { conn: &self.tx },
183 | | }
| |_____________^ method was supposed to return data with lifetime `'h` but it is returning data with lifetime `'1`
error[E0515]: cannot return reference to temporary value
--> src/tx.rs:181:13
|
181 | &ReadTransaction {
| _____________^-
| |_____________|
| ||
182 | || tx: ReadOnlyRusqliteTransaction { conn: &self.tx },
183 | || }
| || ^
| ||_____________|
| |_____________returns a reference to data owned by the current function
| temporary value created here
I've tried casting as std::path::Path::new does for OsStr, but it says casting from rusqlite::Transaction
to ReadOnlyRusqliteTransaction
is invalid (but happily accepts the consequent cast from ReadOnlyRusqliteTransaction
to ReadTransaction
.
I don't quite follow how to get this to work. I understand in safe code I'm returning a reference to a temporary, but because both embedded types contain only a single reference, it should be possible to cast from &rusqlite::Transaction all the way up to a &ReadTransaction. Additionally the reference can't last longer than 'h
, the lifetime of the rusqlite::Transaction's reference to the rusqlite::Connection. I assume I need to ensure that the reference to the write Transaction (&self) in deref, also doesn't outlive the reference to the rusqlite::Connection.
You can see my work around to provide a read
method on Transaction
just below, but I want to get the Deref to work for my understanding, and for a cleaner API.