Manually drop a closure, so it releases borrows?

I have code that looks like this:

 let contained_in_path = |n: usize| {
                for p in paths.iter() {
                    for (i, x) in p.iter().enumerate() {
                        if x.0 == nit[n] {
                            return Some((i, p.clone()));
                        }
                    }
                }
                None
            };
            while next_i < nit.len()
                && (visited.contains(&nit[next_i]) || previous_path_ending(&paths, next_i))
            {
                next_i += 1;
                if let Some((i, p)) = contained_in_path(next_i) {
                ...something mutating paths
                    }
                }
            }

Rust will of course complain, because the closure borrowed immutably, and now I'm trying to change it. Is there anyway to tell Rust that the first I call this closure is the only time I will call it? I.e. manually drop it before I try to mutate it again? A google search didn't turn up much that is helpful...

When you find the match, save the info you need in a variable and break out of the loop. Then do the mutation after the loop.

Or take &paths as an argument.

This is what I am doing currently. So I suppose the answer is no?

Eh, it might still be possible. Tell the compiler you definitely can't continue the loop after the mutation, maybe.

1 Like

Thinking a little longer, closures don't have a destructor of any significance, so drop can't help at all (it will just be an additional use of your captured borrows).

1 Like

IIRC if let always extends the lifetime of it's capture over the body, so getting out of the loop won't help.

I'd suggest passing paths as an argument in this case.

1 Like