Hello, Rustaceans
Given this code (also as a Rust playground link):
use postgres::{Client, Transaction};
pub trait Database<'a> {
type Connection: DBConn<'a>;
fn connect(&self) -> Result<Self::Connection, postgres::Error>;
}
pub trait DBConn<'a> {
type Transaction: DBTxn<'a>;
fn start_transaction(&'a mut self) -> Result<Self::Transaction, postgres::Error>;
}
pub trait DBTxn<'a> {
fn application_logic(&mut self) -> Result<(), postgres::Error>;
}
pub struct Pg;
impl<'a> Database<'a> for Pg {
type Connection = PgConn;
fn connect(&self) -> Result<Self::Connection, postgres::Error> {
todo!()
}
}
pub struct PgConn(Client);
impl<'a> DBConn<'a> for PgConn {
type Transaction = PgTxn<'a>;
fn start_transaction(&'a mut self) -> Result<PgTxn<'a>, postgres::Error> {
let db_txn = self.0.transaction()?;
Ok(PgTxn(db_txn))
}
}
pub struct PgTxn<'a>(Transaction<'a>);
impl<'a> DBTxn<'a> for PgTxn<'_> {
fn application_logic(&mut self) -> Result<(), postgres::Error> {
todo!()
}
}
fn foo<'a, D: Database<'a>>(db: &D) -> Result<(), postgres::Error>
where
D::Connection: 'a
{
let mut conn = db.connect()?;
let mut db_txn = conn.start_transaction()?;
db_txn.application_logic().unwrap();
Ok(())
}
fn main() {
let db = Pg {};
foo(&db);
}
I'm getting this compilation error:
Compiling playground v0.0.1 (/playground)
error[E0597]: `conn` does not live long enough
--> src/main.rs:51:22
|
46 | fn foo<'a, D: Database<'a>>(db: &D) -> Result<(), postgres::Error>
| -- lifetime `'a` defined here
...
51 | let mut db_txn = conn.start_transaction()?;
| ^^^^--------------------
| |
| borrowed value does not live long enough
| argument requires that `conn` is borrowed for `'a`
...
54 | }
| - `conn` dropped here while still borrowed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
I need for db_txn
to live shorter than conn
but have troubles encoding that with lifetimes and associated types. Why is the compiler claiming that conn
doesn't live long enough here?