Open
Description
Versions
- Rust:: 1.88.0
- Diesel:: commit
cdf7c51c35da7ebc6fb12e71857bfba8487c20cd
- Diesel_async:: commit 0e703ba
- Operating System: Ubuntu 22
Problem Description
The following code doesn't compile:
fn f(conn: &mut crate::AsyncPgConnection) {
use diesel::sql_types::Integer;
use diesel::IntoSql;
use futures_util::future::try_join;
use futures_util::FutureExt;
use crate::RunQueryDsl;
let f1 = diesel::select(1_i32.into_sql::<Integer>()).get_result::<i32>(conn);
let f2 = diesel::select(2_i32.into_sql::<Integer>()).get_result::<i32>(conn);
// This doesn't work
let _ = async { try_join(f1, f2).await }.boxed();
}
Error
error[E0308]: mismatched types
--> src/pg/mod.rs:1145:17
|
1145 | let _ = async { try_join(f1, f2).await }.boxed();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected struct `Map<StreamFuture<Pin<Box<Map<Pin<Box<dyn Stream<Item = ...> + Send>>, ...>>>>, ...>`
found struct `Map<StreamFuture<Pin<Box<Map<Pin<Box<dyn Stream<Item = ...> + Send>>, ...>>>>, ...>`
note: the lifetime requirement is introduced here
--> /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/future/future/mod.rs:516:23
|
516 | Self: Sized + Send + 'a,
| ^^^^
= note: the full name for the type has been written to '/home/runner/Desktop/diesel_async/target/debug/deps/diesel_async-0e1fc68988d593f9.long-type-4500313906557700460.txt'
= note: consider using `--verbose` to print the full type name to the console
error[E0308]: mismatched types
--> src/pg/mod.rs:1145:17
|
1145 | let _ = async { try_join(f1, f2).await }.boxed();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected struct `Map<StreamFuture<Pin<Box<Map<Pin<Box<dyn Stream<Item = ...> + Send>>, ...>>>>, ...>`
found struct `Map<StreamFuture<Pin<Box<Map<Pin<Box<dyn Stream<Item = ...> + Send>>, ...>>>>, ...>`
note: the lifetime requirement is introduced here
--> /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/future/future/mod.rs:516:23
|
516 | Self: Sized + Send + 'a,
| ^^^^
= note: the full name for the type has been written to '/home/runner/Desktop/diesel_async/target/debug/deps/diesel_async-0e1fc68988d593f9.long-type-9446752501490231457.txt'
= note: consider using `--verbose` to print the full type name to the console
error: implementation of `FnOnce` is not general enough
--> src/pg/mod.rs:1145:17
|
1145 | let _ = async { try_join(f1, f2).await }.boxed();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: `fn(Pin<Box<(dyn Stream<Item = Result<PgRow, diesel::result::Error>> + std::marker::Send + '0)>>) -> futures_util::stream::Map<Pin<Box<dyn Stream<Item = Result<PgRow, diesel::result::Error>> + std::marker::Send>>, fn(Result<PgRow, diesel::result::Error>) -> Result<i32, diesel::result::Error>>` must implement `FnOnce<(Pin<Box<(dyn Stream<Item = Result<PgRow, diesel::result::Error>> + std::marker::Send + '1)>>,)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `FnOnce<(Pin<Box<dyn Stream<Item = Result<PgRow, diesel::result::Error>> + std::marker::Send>>,)>`
error[E0308]: mismatched types
--> src/pg/mod.rs:1145:17
|
1145 | let _ = async { try_join(f1, f2).await }.boxed();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected struct `futures_util::stream::Map<Pin<Box<dyn Stream<Item = Result<PgRow, diesel::result::Error>> + std::marker::Send>>, _>`
found struct `futures_util::stream::Map<Pin<Box<dyn Stream<Item = Result<PgRow, diesel::result::Error>> + std::marker::Send>>, _>`
note: the lifetime requirement is introduced here
--> /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/future/future/mod.rs:516:23
|
516 | Self: Sized + Send + 'a,
| ^^^^
For more information about this error, try `rustc --explain E0308`.
error: could not compile `diesel-async` (lib test) due to 4 previous errors
This seems to be related to the GAT lifetimes of the returned futures.
The workaround is to erase the lifetimes of the futures:
// This works
let _ = async { try_join(f1, f2).boxed().await }.boxed();
// This also works
fn erase<'a, F: Future + Send + 'a>(fut: F) -> impl Future<Output = F::Output> + Send + 'a {
fut
}
let _ = async { erase(try_join(f1, f2)).await }.boxed();
Checklist
- I have already looked over the issue tracker for similar possible closed issues.
- This issue can be reproduced on Rust's stable channel. (Your issue will be
closed if this is not the case) - This issue can be reproduced without requiring a third party crate