Skip to content

Compilation error when using pipelining #249

Open
@stormshield-kg

Description

@stormshield-kg

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions