Futures::select macro and compiler lifetime complaints

⚓ rust    📅 2025-05-08    👤 surdeus    👁️ 6      

surdeus

Warning

This post was published 54 days ago. The information described in this article may have changed.

Hello,

I have a struct Foo:

struct Foo {}

impl Foo {
    async fn do_foo(&self) -> String {
        "did foo".to_string()
    }
}

and a function that creates and returns a Foo, but before returning it, calls the async function do_foo.

Everything works as expected when awaiting the future returned by do_foo:

async fn compiler_success() -> Foo {
    let foo = Foo {};

    let foo_f = Box::pin(foo.do_foo().fuse());

    let foo_val = foo_f.await;
    println!("{foo_val}");

    foo
}

However, if I use futures::select macro instead of awaiting:

async fn compiler_failure() -> Foo {
    let foo = Foo {};

    let mut foo_f = Box::pin(foo.do_foo().fuse());

    select! {
        foo_val = foo_f => println!("{foo_val}"),
        complete => println!("Complete"),
        default => println!("Default"),
    };

    foo
}

the compiler complains about lifetimes:

error[E0505]: cannot move out of foo because it is borrowed

From what I understand the compiler cannot be sure that indeed foo is returned only when the future has completed.

I want to use the select! macro because what I actually try to achieve is slightly more complex: awaiting more than one futures in a loop until getting a value from do_foo future.

Please note that Foo cannot implement Clone.

Is there a way to achieve what I want? I don't have problem using some other way instead of select!.

Thanks!

5 posts - 3 participants

Read full topic

🏷️ rust_feed