Borrowing with closures

Hi all,

I think i make some wrong assumptions about closures being identical to functions. The compiler is telling me that variable p could potentially be borrowed while being dropped. I dont see it :stuck_out_tongue:

i condensed the code to the following snippet:

who can give me some context here about whats going wrong?! thank!

I'm not sure exactly why your original code fails, but it has something to do with how the compiler is inferring types/lifetimes. If you explicitly annotate the type of the closure argument, it compiles:

        let mut push_found = |path:&Path| {
            if let Some(tuple) = self.parse_file(path) {
                found.push(tuple);
            }
        };

Ah thanks. I was already thinking something like this. Would it be, since that โ€˜foundโ€™ is borrowed into the closure that p will get the same lifetime wrongfully as โ€˜foundโ€™, expecting it to live as long as it?

It has nothing to do with found and instead the problem is whether the closure should be generic over the lifetime or be valid for only a single one. In the original code it was being inferred to be the latter (a single one), but since there's no single lifetime that works (each time you call push_found(&p) the &p has a different lifetime, incompatible with the others) you get an error. With |path:&Path| the compiler instead infers the former (the closure being generic over that lifetime).

Now, one could ask "But why doesn't the compiler infers the generic one in the first case if it works?" and the answer is that it's hard. It requires insight into what your code does, which in turn to typecheck needs to know what's the signature of the closure, and it becomes a circular problem.

2 Likes