Reborrowing (`&mut *x`) is not suggested as a potential solution for `&mut T` being moved
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
fn do_something<T>(_a: &mut T, _b: &mut T) {}
fn foo<T: Default>(r: &mut T) {
let mut a = T::default();
let b = r;
do_something(&mut a, b);
*r = a;
}
Current output
error[E0382]: use of moved value: `r`
--> src/lib.rs:7:5
|
3 | fn foo<T: Default>(r: &mut T) {
| - move occurs because `r` has type `&mut T`, which does not implement the `Copy` trait
4 | let mut a = T::default();
5 | let b = r;
| - value moved here
6 | do_something(&mut a, b);
7 | *r = a;
| ^^ value used here after move
For more information about this error, try `rustc --explain E0382`.
error: could not compile `moved` (lib) due to 1 previous error
Desired output
help: try reborrowing: `let b = &mut *r;`
++++++
Rationale and extra context
A rather trivial fix, but not very easy to recall it even exists, because in most places compiler does this for you automatically (iinm). For example, I think Rust always inserts &mut * when a &mut T is passed as an argument to a call.
Other cases
Similar to #81059 & #82453, but those also involve pattern matching.
Similar to #129694, but example there is more complex, with some type inference involved.
Similar to #81772, but that issue seems to be about expecting the compiler to automatically insert &mut * and not about the diagnostic quality. The diagnostics there actually does suggest to add a reborrow (as of nightly 2025-01-24).
Same thing with #85161: it is not about diagnostics but about compiler not reborrowing automatically. The diagnostic there does suggest reborrowing too.
More or less a duplicate of #74706? Feel free to close either one if you think these are indeed duplicates.
Rust Version
$ rustc --version --verbose
rustc 1.86.0-nightly (1e9b0177d 2025-01-24)
binary: rustc
commit-hash: 1e9b0177da38e3f421a3b9b1942f1777d166e06a
commit-date: 2025-01-24
host: x86_64-unknown-linux-gnu
release: 1.86.0-nightly
LLVM version: 19.1.7
Anything else?
If not for the Boats's post on pinned places, I don't think I would even realize I can do &mut * to fix the error I got, despite several years of actively using Rust under my belt.
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 src/lib.rs and run rustc --explain E0382 to understand the current diagnostic. Trace the diagnostic behavior for the moved &mut T and make the completed output suggest let b = &mut *r; as shown in the desired output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100