What are drop scopes for captured variable in closure?

Given a function, or closure, there are drop scopes for:

  • In the case of a block expression, the scope for the block and the expression are the same scope.
fn main(){
    let i = String::from("i");
    let f = move ||{
     println!("{i}");
   };
}

It is unclear what the drop scope of the captured variable i is.

Because you moved the String, it's effectively a field in the closure, and it drops when the closure drops.

It occurs to me there is something worth elaborating on here.

Well, first, the things you quoted are primarily talking about arguments of the closure and variables introduced in the closure, not captures. Captures are by reference (drops are no-ops) or by value. And if it's a capture by value, it drops when the closure drops, just like a field of a nominal struct.

But note that where the closure drops depends on the "type" of closure it is, in terms of practical code. If you don't move it somewhere else, a Fn or FnMut closure will drop at the end of its drop scope no matter how many times you call it -- example. But a FnOnce closure will drop after the execution that happens when you call it, because calling it consumes the closure (takes the closure itself by value) -- example. And additionally, a FnOnce closure may move it's "fields" (captures) out of itself before the execution of the closure finishes -- example.

Yes. But I meant what time the captured variable would be dropped. For example

fn main(){
    let i = String::from("i");
    let f = move ||{
     let r = String::from("r");
     println!("{i}");
   };
}

Compared to the local variable r.

Same as a field in the method of a struct with a self receiver -- depends on if you move the field out of self or not. If you don't, after all locals and (other) args.

I had to test myself on that statement :slight_smile:. I'm not sure if/where argument drop order is documented.

2 Likes

r is never constructed nor dropped, so you can't compare that to when i is dropped, which is at the end of main.