Inconsistent reborrowing when accessing a struct field of type `&mut`.
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
When I assign a struct field of type &mut i32 to a variable, sometimes rust reborrows it for me, and sometimes it doesn't. This reborrowing should be done consistently or not at all.
In the below code, functions works1 and works2 compile fine, but fails1 through fails6 produce a compile error.
struct Thing<'a>(&'a mut i32);
impl Drop for Thing<'_> {
fn drop(&mut self) {}
}
fn works1(t: Thing) {
let mut _x = &mut 1;
_x = t.0;
}
fn works2(t: Thing) {
let mut _x: &mut i32;
_x = t.0;
}
fn fails1(t: Thing) {
let mut _x;
_x = t.0;
}
fn fails2(t: Thing) {
let mut _x = t.0;
}
fn fails3(t: Thing) {
let Thing(mut _x) = t;
}
fn fails4(t: Thing) {
let mut _x;
Thing(_x) = t;
}
fn fails5(t: Thing) {
let mut _x = &mut 1;
Thing(_x) = t;
}
fn fails6(t: Thing) {
let mut _x: &mut i32;
Thing(_x) = t;
}
Error output
error[E0509]: cannot move out of type `Thing<'_>`, which implements the `Drop` trait
--> src/lib.rs:18:10
|
18 | _x = t.0;
| ^^^
| |
| cannot move out of here
| move occurs because `t.0` has type `&mut i32`, which does not implement the `Copy` trait
error[E0509]: cannot move out of type `Thing<'_>`, which implements the `Drop` trait
--> src/lib.rs:22:18
|
22 | let mut _x = t.0;
| ^^^
| |
| cannot move out of here
| move occurs because `t.0` has type `&mut i32`, which does not implement the `Copy` trait
|
help: consider borrowing here
|
22 | let mut _x = &t.0;
| +
error[E0509]: cannot move out of type `Thing<'_>`, which implements the `Drop` trait
--> src/lib.rs:26:25
|
26 | let Thing(mut _x) = t;
| ------ ^ cannot move out of here
| |
| data moved here
| move occurs because `_x` has type `&mut i32`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
26 | let Thing(ref mut _x) = t;
| +++
error[E0509]: cannot move out of type `Thing<'_>`, which implements the `Drop` trait
--> src/lib.rs:31:17
|
31 | Thing(_x) = t;
| -- ^ cannot move out of here
| |
| data moved here
| move occurs because the place has type `&mut i32`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
31 | Thing(ref _x) = t;
| +++
error[E0509]: cannot move out of type `Thing<'_>`, which implements the `Drop` trait
--> src/lib.rs:36:17
|
36 | Thing(_x) = t;
| -- ^ cannot move out of here
| |
| data moved here
| move occurs because the place has type `&mut i32`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
36 | Thing(ref _x) = t;
| +++
error[E0509]: cannot move out of type `Thing<'_>`, which implements the `Drop` trait
--> src/lib.rs:41:17
|
41 | Thing(_x) = t;
| -- ^ cannot move out of here
| |
| data moved here
| move occurs because the place has type `&mut i32`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
41 | Thing(ref _x) = t;
| +++
For more information about this error, try `rustc --explain E0509`.
error: could not compile `playground` (lib) due to 6 previous errors
Meta
Reproducible on the playground with version 1.95.0-nightly (2026-02-12 47611e16044c68ef27ba)
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 six failing cases and the two working cases from src/lib.rs in the playground using the reported nightly version, then compare their E0509 diagnostics. Read the E0509 explanation and trace the compiler handling of field access and destructuring for a Drop type; done means the reborrowing behavior is consistent and the relevant cases compile or fail as intended.
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
- Mostly clear
- Newbie friendliness
- 35/100