Skip to content
This repository has been archived by the owner on Apr 5, 2024. It is now read-only.

Move out of reference in move closures #31

Closed
arora-aman opened this issue Dec 3, 2020 · 4 comments · Fixed by rust-lang/rust#82007
Closed

Move out of reference in move closures #31

arora-aman opened this issue Dec 3, 2020 · 4 comments · Fixed by rust-lang/rust#82007
Assignees
Labels
bug Something isn't working

Comments

@arora-aman
Copy link
Member

arora-aman commented Dec 3, 2020

struct S {
    x: String,
    y: String
}

fn x(s: &mut S) {
    let mut c = move || {
        s.x.truncate(0);
    };
    c();
}


fn main() {
    let mut s = S { x: "".into(), y: "".into() };
    x(&mut s);
}

Without the feature gate s which is a &mut S is moved. However with the feature gate *s.x is moved which is a String which behind a &mut S and can't be moved out.

@nikomatsakis
Copy link
Contributor

@arora-aman
Copy link
Member Author

Update from 2229 sync meeting:

  • We drop any Derefs in case of move closures.

@arora-aman arora-aman added the bug Something isn't working label Dec 4, 2020
@arora-aman arora-aman self-assigned this Dec 7, 2020
@arora-aman
Copy link
Member Author

@arora-aman
Copy link
Member Author

First part implemented here: rust-lang/rust#80092

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Feb 16, 2021
Implement reborrow for closure captures

The strategy for captures is detailed here with examples: https://hackmd.io/PzxYMPY4RF-B9iH9uj9GTA

Key points:
- We only need to reborrow a capture in case of move closures.
  - If we mutate something via a `&mut` we store it as a `MutBorrow`/`UniqueMuBorrow` of the path containing the `&mut`,
  - Similarly, if it's read via `&` ref we just store it as a `ImmBorrow` of the path containing the `&` ref.
  - If a path doesn't deref a `&mut`, `&`, then that path is captured by Move.
  - If the use of a path results in a move when the closure is called, then that path is truncated before any deref and the truncated path is moved into the closure.

- In the case of non-move closure if a use of a path results in a move, then the path is truncated before any deref and the truncated path is moved into the closure.

Note that the implementation differs a bit from the document to allow for truncated path to be used in the ClosureKind analysis that happens as part of the first capture analysis pass.

Closes: rust-lang/project-rfc-2229#31

r? `@nikomatsakis`
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Feb 16, 2021
Implement reborrow for closure captures

The strategy for captures is detailed here with examples: https://hackmd.io/PzxYMPY4RF-B9iH9uj9GTA

Key points:
- We only need to reborrow a capture in case of move closures.
  - If we mutate something via a `&mut` we store it as a `MutBorrow`/`UniqueMuBorrow` of the path containing the `&mut`,
  - Similarly, if it's read via `&` ref we just store it as a `ImmBorrow` of the path containing the `&` ref.
  - If a path doesn't deref a `&mut`, `&`, then that path is captured by Move.
  - If the use of a path results in a move when the closure is called, then that path is truncated before any deref and the truncated path is moved into the closure.

- In the case of non-move closure if a use of a path results in a move, then the path is truncated before any deref and the truncated path is moved into the closure.

Note that the implementation differs a bit from the document to allow for truncated path to be used in the ClosureKind analysis that happens as part of the first capture analysis pass.

Closes: rust-lang/project-rfc-2229#31

r? ``@nikomatsakis``
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Feb 17, 2021
Implement reborrow for closure captures

The strategy for captures is detailed here with examples: https://hackmd.io/PzxYMPY4RF-B9iH9uj9GTA

Key points:
- We only need to reborrow a capture in case of move closures.
  - If we mutate something via a `&mut` we store it as a `MutBorrow`/`UniqueMuBorrow` of the path containing the `&mut`,
  - Similarly, if it's read via `&` ref we just store it as a `ImmBorrow` of the path containing the `&` ref.
  - If a path doesn't deref a `&mut`, `&`, then that path is captured by Move.
  - If the use of a path results in a move when the closure is called, then that path is truncated before any deref and the truncated path is moved into the closure.

- In the case of non-move closure if a use of a path results in a move, then the path is truncated before any deref and the truncated path is moved into the closure.

Note that the implementation differs a bit from the document to allow for truncated path to be used in the ClosureKind analysis that happens as part of the first capture analysis pass.

Closes: rust-lang/project-rfc-2229#31

r? ```@nikomatsakis```
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Feb 17, 2021
Implement reborrow for closure captures

The strategy for captures is detailed here with examples: https://hackmd.io/PzxYMPY4RF-B9iH9uj9GTA

Key points:
- We only need to reborrow a capture in case of move closures.
  - If we mutate something via a `&mut` we store it as a `MutBorrow`/`UniqueMuBorrow` of the path containing the `&mut`,
  - Similarly, if it's read via `&` ref we just store it as a `ImmBorrow` of the path containing the `&` ref.
  - If a path doesn't deref a `&mut`, `&`, then that path is captured by Move.
  - If the use of a path results in a move when the closure is called, then that path is truncated before any deref and the truncated path is moved into the closure.

- In the case of non-move closure if a use of a path results in a move, then the path is truncated before any deref and the truncated path is moved into the closure.

Note that the implementation differs a bit from the document to allow for truncated path to be used in the ClosureKind analysis that happens as part of the first capture analysis pass.

Closes: rust-lang/project-rfc-2229#31

r? ````@nikomatsakis````
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants