rustc should allow moving a value and its borrowed data into a `move` closure.
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Given the following code (playground):
struct Borrows<'a>(&'a String);
impl<'a> Borrows<'a> {
fn do_something(&self) {
println!("data contents: {}", self.0);
}
}
fn main() {
let data = String::from("hi-ho kermit thee frog heer");
let borrower = Borrows(&data);
let _ = move || {
println!("data size: {}", data.len());
borrower.do_something();
};
}
The following error is produced on stable (1.79.0) and nightly (1.81.0-nightly):
error[E0505]: cannot move out of `data` because it is borrowed
--> src/main.rs:13:13
|
10 | let data = String::from("hi-ho kermit thee frog heer");
| ---- binding `data` declared here
11 | let borrower = Borrows(&data);
| ----- borrow of `data` occurs here
12 |
13 | let _ = move || {
| ^^^^^^^ move out of `data` occurs here
14 | println!("data size: {}", data.len());
| ---- move occurs due to use in closure
15 | borrower.do_something();
| -------- borrow later captured here by closure
|
help: consider cloning the value if the performance cost is acceptable
|
11 - let borrower = Borrows(&data);
11 + let borrower = Borrows(data.clone());
|
This would normally make sense, except for the fact that both borrower and data are moved into the closure, and the println! statement inside the closure does not consume data.
So in theory, rustc could allow this code. It seems like it would be similar to other ways in which rustc pushes around lexical scopes in order to allow more code to be valid.
Alternatives
Alternatively, rustc could suggest that the move is not necessary:
help: consider capturing by reference instead of by value
|
13 - let _ = move || {
13 + let _ = || {
|
Or it could suggest rebinding as a reference to be moved into the closure:
help: consider capturing `data` by reference instead of by value
|
+ let data = &data;
13 | let _ = move || {
|
@rustbot label +T-compiler
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the example in the linked Rust Playground and inspect rustc's E0505 diagnostic for the closure capture. Determine whether the compiler should permit the move or recommend one of the alternatives, then add coverage for the chosen behavior and verify the diagnostic or compilation result.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100