Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to specify lifetimes for `One type is more general then the other` compile error?

I have the following setup where I am trying to create a Dummy future which is intended to modify the values in-place inside the future obtained from f: FnMut(&mut i32) -> Fut. I am passing the generic function fun to substitute it, but I am getting different lifetimes.

#![allow(unused_variables)]

pub struct Dummy<Fut, F> {
    f: F,
    futures: futures::stream::FuturesUnordered<Fut>
}


impl<Fut, F> Dummy<Fut, F>
where
    F: FnMut(&mut i32) -> Fut,
    Fut: futures::Future<Output = ()>,
{
    fn new(f: F) -> Self {
        Self { 
            f,
            futures: futures::stream::FuturesUnordered::new()
        }
    }
}

impl<Fut, F> futures::Future for Dummy<Fut, F>
where 
    F: FnMut(&mut i32) -> Fut,
    Fut: futures::Future<Output = ()>
{
    type Output = ();
    
    fn poll(self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
        // logic emitted
        core::task::Poll::Ready(())
    }
    
}


fn fun<'a>(f: &'a mut i32) -> impl futures::Future<Output = ()> + 'a {
    async move {
        *f += 1;
    }
}

#[tokio::main]
async fn main() {
    Dummy::new(fun).await;
}

playground link

which gives the compile-error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

error[E0308]: mismatched types
  --> src/main.rs:45:20
   |
45 |     Dummy::new(fun).await;
   |                    ^^^^^^ one type is more general than the other
   |
   = note: expected trait `for<'r> FnOnce<(&'r mut i32,)>`
              found trait `for<'a> FnOnce<(&'a mut i32,)>`
   = note: the lifetime requirement is introduced here

error[E0308]: mismatched types
  --> src/main.rs:45:20
   |
45 |     Dummy::new(fun).await;
   |                    ^^^^^^ one type is more general than the other
   |
   = note: expected trait `for<'r> FnOnce<(&'r mut i32,)>`
              found trait `for<'a> FnOnce<(&'a mut i32,)>`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to 4 previous errors

Is it possible to annotate the impl in a way that removes these mismatched types error? I could annotate everything with 'static, as I have done here: playground link. But I was trying to avoid this solution since I want to mutually borrow dependent data in the future poll method.

>Solution :

You need to put the same kind of connection between the reference lifetime and the future lifetime you currently have on fun() on the Future implementation of Dummy:

impl<'a, Fut, F> futures::Future for Dummy<Fut, F>
where
    F: FnMut(&'a mut i32) -> Fut,
    Fut: futures::Future<Output = ()> + 'a,

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading