Here's my minimum reproducible example:
use axum::{extract::State, Json, Router};
use diesel::pg::Pg;
use diesel_async::{
pooled_connection::bb8::Pool,
AsyncConnection, AsyncPgConnection, RunQueryDsl,
};
fn main() {
// body omitted for brevity
}
pub type AsyncPool = Pool<AsyncPgConnection>;
fn router() -> Router<AsyncPool> {
use axum::routing::*;
Router::new().route("/create", post(create))
}
async fn create(State(db): State<AsyncPool>) -> Result<Json<()>, ()> {
let mut conn = db.get().await.unwrap();
let user = create_user(&mut conn).await?;
Ok(Json(user))
}
// actual return types omitted for brevity
async fn create_user(conn: &mut impl AsyncConnection<Backend = Pg>) -> Result<(), ()> {
// error doesn't happen without this line, which is even more confusing
diesel::dsl::sql_query("real query omitted for brevity")
.execute(conn)
.await
.unwrap();
Ok(())
}
Trying to compile this on Rust 1.70 gives the following error:
error: implementation of `Deref` is not general enough
--> src/main.rs:27:36
|
27 | Router::new().route("/create", post(create))
| ^^^^^^^^^^^^ implementation of `Deref` is not general enough
|
= note: `Deref` would have to be implemented for the type `bb8::api::PooledConnection<'0, AsyncDieselConnectionManager<AsyncPgConnection>>`, for any lifetime `'0`...
= note: ...but `Deref` is actually implemented for the type `bb8::api::PooledConnection<'1, AsyncDieselConnectionManager<AsyncPgConnection>>`, for some specific lifetime `'1`
I already don't understand why this error is happening, because the implementations of Deref
and DerefMut
for bb8::PooledConnection
look general enough to me:
impl<'a, M> Deref for PooledConnection<'a, M>
where
M: ManageConnection,
{
type Target = M::Connection;
fn deref(&self) -> &Self::Target {
&self.conn.as_ref().unwrap().conn
}
}
impl<'a, M> DerefMut for PooledConnection<'a, M>
where
M: ManageConnection,
{
fn deref_mut(&mut self) -> &mut M::Connection {
&mut self.conn.as_mut().unwrap().conn
}
}
But what's even more confusing is that the error goes away if I don't call diesel_async::run_query_dsl::RunQueryDsl::execute()
on the connection object inside of create_user
, OR if I call .deref_mut()
manually:
// calling deref_mut manually makes the error go away. why?
let user = create_user(conn.deref_mut()).await?;
Why is this compile error happening, and why does it go away under these circumstances? How is it possible that calling execute()
is able to implicitly place additional lifetime constraints on the parameter conn
?