rust-lang / rust-lang/rust

Reborrowing (`&mut *x`) is not suggested as a potential solution for `&mut T` being moved

Open
#136,057 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics T-compiler
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.