Open
Description
There seems to be a discrepancy between the description in the RBE section on capturing (9.2.1) and current stable implementation of rust regarding what happens to a copy variable when it needs to be captured by value in a closure. The RBE says that
mem::drop
requiresT
so this must take by value. A copy type would copy into the closure leaving the original untouched.
However, it appears that the compiler does not do this precisely. Consider the following example:
#![allow(unused)]
#[derive(Clone, Copy)]
struct IsCopy {}
fn main() {
let y = {
let x = IsCopy {};
// x is not copied into the closure here, only taken by reference
|| drop(x)
};
}
fn foo() -> impl FnOnce() {
let x = IsCopy {};
// Also here x is only taken by reference and not copied into the closure
|| drop(x)
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0597]: `x` does not live long enough
--> src/main.rs:11:17
|
7 | let y = {
| - borrow later stored here
...
11 | || drop(x)
| -- ^ borrowed value does not live long enough
| |
| value captured here
12 | };
| - `x` dropped here while still borrowed
error[E0597]: `x` does not live long enough
--> src/main.rs:19:13
|
15 | fn foo() -> impl FnOnce() {
| ------------- opaque type requires that `x` is borrowed for `'static`
...
19 | || drop(x)
| -- ^ borrowed value does not live long enough
| |
| value captured here
20 | }
| - `x` dropped here while still borrowed
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.
From the example it seems (I'm not actually 100% sure what is going on behind the scenes) that the closure only takes a reference, and will perform the copy later when it needs to. In any case, this is different to what is implied by the RBE.