Skip to content

Instantly share code, notes, and snippets.

@rcythr
Created March 29, 2024 01:45
Show Gist options
  • Select an option

  • Save rcythr/de40ec0bc99d994ccd21b8b1e8fca4d7 to your computer and use it in GitHub Desktop.

Select an option

Save rcythr/de40ec0bc99d994ccd21b8b1e8fca4d7 to your computer and use it in GitHub Desktop.
use std::future::Future;
use tokio;
async fn foo<'a, 'b>(a: &'a i32, b: &'b i32, c: &'b i32) -> i32 {
a + b + c
}
async fn generic_fn<F, Fut>(f: F, a: &i32) -> i32
where
F: Fn(&i32, &i32, &i32) -> Fut,
Fut: Future<Output = i32>,
{
let b = 2;
let c = 3;
f(a, &b, &c).await
}
#[tokio::main]
async fn main() {
let a = 1;
let result = generic_fn(foo, &a).await;
println!("{}", result);
}
@rcythr
Copy link
Author

rcythr commented Mar 29, 2024

error[E0308]: mismatched types
  --> src/main.rs:21:18
   |
21 |     let result = generic_fn(foo, &a).await;
   |                  ^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected trait `for<'a, 'b, 'c> Fn(&'a i32, &'b i32, &'c i32)`
              found trait `for<'a, 'b> Fn(&'a i32, &'b i32, &'b i32)`
note: the lifetime requirement is introduced here
  --> src/main.rs:10:8
   |
10 |     F: Fn(&i32, &i32, &i32) -> Fut,
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
  --> src/main.rs:21:18
   |
21 |     let result = generic_fn(foo, &a).await;
   |                  ^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected opaque type `impl for<'a, 'b> Future<Output = i32>`
              found opaque type `impl Future<Output = i32>`
   = help: consider `await`ing on both `Future`s
   = note: distinct uses of `impl Trait` result in different opaque types
note: the lifetime requirement is introduced here
  --> src/main.rs:10:32
   |
10 |     F: Fn(&i32, &i32, &i32) -> Fut,
   |                                ^^^

error[E0308]: mismatched types
  --> src/main.rs:21:18
   |
21 |     let result = generic_fn(foo, &a).await;
   |                  ^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected trait `for<'a, 'b, 'c> FnOnce(&'a i32, &'b i32, &'c i32)`
              found trait `for<'a, 'b> FnOnce(&'a i32, &'b i32, &'b i32)`
note: the lifetime requirement is introduced here
  --> src/main.rs:10:32
   |
10 |     F: Fn(&i32, &i32, &i32) -> Fut,
   |                                ^^^

For more information about this error, try `rustc --explain E0308`.

@rcythr
Copy link
Author

rcythr commented Mar 29, 2024

I ended up resolving this by avoiding using the references inside the generic function and instead pass them by value. It leads to a copy, but it works fine for my use case. I could have also probably used an Arc, but I'm fine with copying.

Here's a working example:
https://gist.github.com/rcythr/16a70560c4292eae4a45979d8163515a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment