Trait bound sqlx::FromRow<'r, PgRow> is not satisfied

I am trying to create a Postgres database toolkit for my project that uses sqlx internally. The issue I can not fix is that I am always missing the for<'r> T: FromRow<'r, PgRow> trait bound.

Here is a snippet of the function. It builds the sqlx:QueryAs struct, tries to execute its fetch_all method and return the result.

pub async fn fetch_all<'r, T>(&self, query: Query<'r>) -> Result<Vec<T>, QueryError>
where
    T: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow>,
{
    let query = query.0.build_query_as();
    let rows = query.fetch_all(&self.pool).await?;

    Ok(rows)
}

Query is my struct that abstracts away the slqx::QueryBuilder.

pub struct Query<'args>(sqlx::QueryBuilder<'args, sqlx::postgres::Postgres>);

I do not understand why it still requires the FromRow trait bound even if I already have it.

Here is the full error I get from cargo check:

 1  error[E0277]: the trait bound `for<'r> T: FromRow<'r, PgRow>` is not satisfied
   --> database.rs:28:26
    |
 28 |         let rows = query.fetch_all(&self.pool).await?;
    |                          ^^^^^^^^^ the trait `for<'r> FromRow<'r, PgRow>` is not implemented for `T`
    |
 note: required by a bound in `QueryAs::<'q, DB, O, A>::fetch_all`
   --> query_as.rs:84:23
    |
 84 |     O: Send + Unpin + for<'r> FromRow<'r, DB::Row>,
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryAs::<'q, DB, O, A>::fetch_all`
 help: consider further restricting this bound
    |
 25 |         T: Send + Unpin + sqlx::FromRow<'r, sqlx::postgres::PgRow> + for<'r> sqlx::FromRow<'r, sqlx::postgres::PgRow>,
    |                                                                    ++++++++++++++++++++++++++++++++++++++++++++++++++

If I add the suggested trait bound it still says that I am missing it along with a new lifetime name 'r shadows a lifetime name that is already in scope error.

 1  error[E0496]: lifetime name `'r` shadows a lifetime name that is already in scope
   --> database.rs:28:19
    |
 23 |     pub async fn fetch_all<'r, T>(&self, query: Query<'r>) -> Result<Vec<T>, QueryError>
    |                            -- first declared here
 ...
 28 |             + for<'r> sqlx::FromRow<'r, sqlx::postgres::PgRow>,
    |                   ^^ lifetime `'r` already in scope

 2  error[E0277]: the trait bound `for<'r> T: FromRow<'r, PgRow>` is not satisfied
   --> database.rs:31:26
    |
 31 |         let rows = query.fetch_all(&self.pool).await?;
    |                          ^^^^^^^^^ the trait `for<'r> FromRow<'r, PgRow>` is not implemented for `T`
    |
 note: required by a bound in `QueryAs::<'q, DB, O, A>::fetch_all`
   --> query_as.rs:84:23
    |
 84 |     O: Send + Unpin + for<'r> FromRow<'r, DB::Row>,
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `QueryAs::<'q, DB, O, A>::fetch_all`
 help: consider further restricting this bound
    |
 28 |             + for<'r> sqlx::FromRow<'r, sqlx::postgres::PgRow> + for<'r> sqlx::FromRow<'r, sqlx::postgres::PgRow>,
    |                                                                ++++++++++++++++++++++++++++++++++++++++++++++++++

Any help would be appreciated.

The immediate cause of your last error is that you're trying to use the same lifetime name for a caller provided lifetime (the 'r in Query<'r>) and for the higher-ranked bound (for<'r> ... FromRow<'r, ...>). The compiler wants you try try this:

pub async fn fetch_all<'query, T>(&self, query: Query<'query>) -> Result<Vec<T>, QueryError>
//       Distinct name ^^^^^^                         ^^^^^^
where
    T: Send + Unpin +  for<'r> sqlx::FromRow<'r, sqlx::postgres::PgRow>,
// Higher-ranked bound ^^^^^^^               ^^

(I didn't dig any deeper, so this may or may not solve your actual problem.)


The higher-ranked bound with for<'r> means "T implements FromRow<'r, ...> for any 'r, no matter how long or short (and independently of the lifetime in Query<'query>)".

Your original bound with a caller-chosen 'r means "T implements FromRow<'r, ...> for the one specific lifetime that the caller has chosen (which is necessary longer than this function body, and is the same as the lifetime in the Query<'r> they provided)".

1 Like

Than you. Your suggestion helped me solve the issue. The solution was to have a separate lifetime for the Query and FromRow trait bound. I just needed the for<'r> FromRow<'r, PgRow> trait bound and not FromRow<'query, PgRow>

    pub async fn fetch_all<'query, T>(&self, query: Query<'query>) -> Result<Vec<T>, QueryError>
    where
        T: Send + Unpin + for<'r> FromRow<'r, PgRow>,
    {

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.