Stream filter and reference lifetime

In the following snippet, is there a way to have the second example compile without the extra allocation (i.e. without str.to_owned()), or can I annotate the closure in some way?

How come filter_map can deal with the reference lifetime here and filter can't?

use futures::prelude::*;

async fn main() {
    let stream = stream::iter(vec!["foo", "bar"]);
    // Works fine:
    let stream = stream.filter_map(|str| async move {
        println!("{}", str);
    // Fails with:
    // return type of closure `impl futures::Future` contains a lifetime `'2`
    let stream = stream.filter(|str| {
        //let str = str.to_owned();
        async move {
            println!("{}", str);

Initially stream is a stream of &'static str. filter_map receives the stream items by value, so it gets a &'static str, which doesn't contain any anonymous lifetime. filter however receives a reference to the stream items, so str there is a &'anon &'static str. Moving the reference with the 'anon lifetime inside the async move is what causes the problem. Since &'static str is Copy you can solve this by using .filter(|&str| { /* ... */ } or by putting a let str = *str; instead of theat .to_owned(). Another option would be do the print outside the async move block, thus avoiding to borrow str in the return type.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.