Borrow checker/lifetime error in iterator

⚓ Rust    📅 2025-12-31    👤 surdeus    👁️ 1      

surdeus

#[derive(Debug)]
struct UvOpts {
    from: Option<String>,
    with: Box<[(String, bool)]>,
}

fn install(opts: &UvOpts) {
    let from = ["--from"]
        .into_iter()
        .chain(opts.from.iter().map(String::as_str))
        .filter(|_| opts.from.is_some());

    let mut with_enabled_commands = Vec::new();
    let mut with_disabled_commands = Vec::new();
    opts.with.iter().for_each(|(key, opt)| {
        if *opt {
            with_enabled_commands.push(key.clone());
        } else {
            with_disabled_commands.push(key.clone());
        }
    });

    let with_disabled = with_disabled_commands.join(",");
    let with_disabled_opts = ["--with", with_disabled.as_str()]
        .into_iter()
        .filter(|_| !with_disabled_commands.is_empty());

    let command = ["uv", "tool", "install"]
        .into_iter()
        .chain(from)
        .chain(with_disabled_opts);

    drop(command);
    
}

This function fails to borrow check, while saying that with_disabled does not live long enough. I'm unable to make much out of the error, and it doesn't really make sense to me. Here's a link to the playground

My question mainly is this, why does the object not live long enough? I fail to see why it's the case. What does the from field have to do with the destructor of with_disabled?

Here's the full error message:

   Compiling playground v0.0.1 (/playground)
error[E0597]: `with_disabled` does not live long enough
  --> src/main.rs:35:41
   |
34 |     let with_disabled = with_disabled_commands.join(",");
   |         ------------- binding `with_disabled` declared here
35 |     let with_disabled_opts = ["--with", with_disabled.as_str()]
   |                                         ^^^^^^^^^^^^^ borrowed value does not live long enough
...
46 | }
   | -
   | |
   | `with_disabled` dropped here while still borrowed
   | borrow might be used here, when `from` is dropped and runs the destructor for type `Filter<std::iter::Chain<std::array::IntoIter<&str, 1>, std::option::IntoIter<&str>>, {closure@src/main.rs:22:17: 22:20}>`
   |
   = note: values in a scope are dropped in the opposite order they are defined

For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` (bin "playground") due to 1 previous error

Thanks for your help.

7 posts - 3 participants

Read full topic

🏷️ Rust_feed