What is the best way to solve "Cannot return value referencing function parameter" with an async function?

Viewed 750

I am fighting with a borrowing issue:

async fn bugger(_foo: &String) {}

fn main() {
    Some("".to_string()).map(|foo| bugger(&foo));
}

The error:

error[E0515]: cannot return value referencing function parameter `foo`
 --> src/main.rs:4:36
  |
4 |     Some("".to_string()).map(|foo| bugger(&foo));
  |                                    ^^^^^^^----^
  |                                    |      |
  |                                    |      `foo` is borrowed here
  |                                    returns a value referencing data owned by the current function

I guess the problem is that the future returned by bugger() stores the &String reference in its state machine.

Since the foo variable is owned in the map() closure, a workaround would be:

async fn bugger(_foo: &String) {}

async fn workaround(_foo: String) {
    bugger(&_foo).await
}

fn main() {
    Some("".to_string()).map(|foo| workaround(foo));
}

I find this inelegant because the compiler knows that foo is owned and used only in the call to bugger, so the workaround() function seems like avoidable boilerplate.

Assuming I cannot change the signature of bugger() (because it is defined in another crate), is there a better way to do this?

Note: using .as_ref().map() would also work for this contrived example, but I would like a solution which works in more complex cases as well (e.g. map() in the middle of an iterator or stream).

EDIT: here is a more realistic example to make the use case clearer.

use futures::stream::{self, StreamExt};

async fn bugger(_foo: & String) -> u8 { 0u8 }

fn main() {
    let vec = vec!["".to_string()];

    let _stream = stream::iter(vec)
        // Apply async function
        .map(|foo| bugger(&foo))
        // Process 10 items "in parallel"
        .buffer_unordered(10)
        // Possibly do more stuff with the stream here
        // [...]
        // .collect().await
        ;
}

Basically I want to apply a third-party async function (taking a reference) in a stream.

0 Answers
Related