Open
Description
Compiling base line version: https://github.com/weiznich/diesel_async/blob/buggy_lifetimes/src/run_query_dsl/mod.rs#L783-L817
I encountered several inconsistent errors while working on the linked code:
Variant 1: (Remove the async move
block and box the future directly)
impl<'b, Changes, Output, Tab, V> UpdateAndFetchResults<Changes, Output>
for crate::AsyncPgConnection
where
Output: Send + 'static,
Changes:
Copy + AsChangeset<Target = Tab> + Send + diesel::associations::Identifiable<Table = Tab>,
Tab: diesel::Table + diesel::query_dsl::methods::FindDsl<Changes::Id> + 'b,
diesel::dsl::Find<Tab, Changes::Id>: IntoUpdateTarget<Table = Tab, WhereClause = V>,
diesel::query_builder::UpdateStatement<Tab, V, Changes::Changeset>:
diesel::query_builder::AsQuery,
diesel::dsl::Update<Changes, Changes>: methods::LoadQuery<'b, Self, Output>,
V: Send + 'b,
Changes::Changeset: Send + 'b,
Tab::FromClause: Send,
{
fn update_and_fetch<'life0, 'async_trait>(
&'life0 mut self,
changeset: Changes,
) -> BoxFuture<'async_trait, QueryResult<Output>>
where
Changes: 'async_trait,
Changes::Changeset: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
{
diesel::update(changeset)
.set(changeset)
.get_result(self)
.boxed()
}
}
Results in the following compilation error:
error: lifetime may not live long enough
--> src/run_query_dsl/mod.rs:809:9
|
784 | impl<'b, Changes, Output, Tab, V> UpdateAndFetchResults<Changes, Output>
| -- lifetime `'b` defined here
...
799 | fn update_and_fetch<'life0, 'async_trait>(
| ------------ lifetime `'async_trait` defined here
...
809 | / diesel::update(changeset)
810 | | .set(changeset)
811 | | .get_result(self)
812 | | .boxed()
| |____________________^ method was supposed to return data with lifetime `'async_trait` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'async_trait`
Variant 2: Use impl Future
for the return type
impl<'b, Changes, Output, Tab, V> UpdateAndFetchResults<Changes, Output>
for crate::AsyncPgConnection
where
Output: Send + 'static,
Changes:
Copy + AsChangeset<Target = Tab> + Send + diesel::associations::Identifiable<Table = Tab>,
Tab: diesel::Table + diesel::query_dsl::methods::FindDsl<Changes::Id> + 'b,
diesel::dsl::Find<Tab, Changes::Id>: IntoUpdateTarget<Table = Tab, WhereClause = V>,
diesel::query_builder::UpdateStatement<Tab, V, Changes::Changeset>:
diesel::query_builder::AsQuery,
diesel::dsl::Update<Changes, Changes>: methods::LoadQuery<'b, Self, Output>,
V: Send + 'b,
Changes::Changeset: Send + 'b,
Tab::FromClause: Send,
{
fn update_and_fetch<'life0, 'async_trait>(
&'life0 mut self,
changeset: Changes,
) -> impl Future<Output = QueryResult<Output>> + Send + 'async_trait
where
Changes: 'async_trait,
Changes::Changeset: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
{
async move {
diesel::update(changeset)
.set(changeset)
.get_result(self)
.await
}
.boxed()
}
}
Error:
error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
--> src/run_query_dsl/mod.rs:784:6
|
784 | impl<'b, Changes, Output, Tab, V> UpdateAndFetchResults<Changes, Output>
| ^^ unconstrained lifetime parameter
I would expect all three code variations to be the "same" in terms of involved lifetimes, but two of them do not compile with rather surprising errors.
Meta
rustc --version --verbose
:
rustc 1.86.0-nightly (99db2737c 2025-01-16)
binary: rustc
commit-hash: 99db2737c91d1e4b36b2ffc17dcda5878bcae625
commit-date: 2025-01-16
host: x86_64-unknown-linux-gnu
release: 1.86.0-nightly
LLVM version: 19.1.7
Backtrace
<backtrace>