2

Here is the code that works.

use core::future::Future;

async fn haha(ctx: u8) -> u8 {
    return 2u8;
}

fn set_func<T>(path: &'static str, f: fn(u8) -> T) -> u8
where
    T: Future<Output = u8> + Send + 'static,
{
    return 8u8;
}

fn main() {
  set_func("haha", haha);
}

but when I change the haha function to

use core::future::Future;

async fn haha(ctx: &mut u8) -> u8 {
    return 2u8;
}

fn set_func<T>(path: &'static str, f: fn(&mut u8) -> T) -> u8
where
    T: Future<Output = u8> + Send + 'static,
{
    return 8u8;
}

fn main() {
  set_func("haha", haha);
}

Then error will shows like this:

   |
13 |     set_func("haha", haha);
   |     --------         ^^^^ one type is more general than the other
   |     |
   |     arguments to this function are incorrect
   |
   = note: expected fn pointer `for<'a> fn(&'a mut u8) -> _`
                 found fn item `for<'a> fn(&'a mut u8) -> impl Future<Output = u8> {haha}`

I am so confusing that changing a argument from u8 to &mut u8 will change the fn pointer to fn item. why this happen?
and the &mut u8 is a requirement, do you have anyway can keep the &mut u8 and make it pass the type check?

Kenneth
  • 403
  • 4
  • 12
  • I'm not totally sure why but if you specify the lifetime of the reference in `set_func()` it compiles: [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6562330b3eaab3d1712f35de2dbe237a). – rodrigo Dec 20 '22 at 14:47
  • @rodrigo It essentially infers the lifetime to be `'static`. It fails with any temporary value. What happens is that instead of the default desugaring of HRTB, it can assume `'static`. – Chayim Friedman Dec 20 '22 at 14:56
  • @ChayimFriedman: Also if you change the `haha` function to assert that it returns an static future it also works, probably more faithful to the OP intention: `fn haha(ctx: &mut u8) -> impl Future { async move { 2u8 } }`. – rodrigo Dec 20 '22 at 15:22
  • I finally using the BoxedFuture solution. which is describe in here https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=eb8150468d05cc351d468b41a16d2693 – Kenneth Dec 23 '22 at 13:37
  • However, I got a lot more lifetime problem for my crate, which something like I know it will be safe but I just failed to tell the Rust compiler as I don't know the special way to tell it. it's very frustrated – Kenneth Dec 23 '22 at 13:38

0 Answers0