Open
Description
Code
fn main() {
let mut x: Result<u8, &mut u8> = Ok(0);
let (Ok(_y) | &mut Err(_y)) = &mut x;
}
Current output
error[E0507]: cannot move out of a mutable reference
--> src/main.rs:3:35
|
3 | let (Ok(_y) | &mut Err(_y)) = &mut x;
| -- ^^^^^^
| |
| data moved here
| move occurs because `_y` has type `&mut u8`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
3 | let (Ok(ref _y) | &mut Err(_y)) = &mut x;
| +++
Rationale and extra context
A couple things are going wrong here.
- Since
MirBorrowckContext::add_move_error_suggestions
is only given theLocal
s that are moved into and not the exact pattern bindings that were the culprits, it goes with the leftmost occurrence. Normally, each instance of a variable binding in an or-pattern has the same binding mode, so this works fine. In this instance though, the left_y
is bound by-ref-mut, so the error points to it instead of the right_y
that's bound by-move. - In order to provide a valid suggestion that doesn't change the type of
_y
, both instances of_y
would have to be given an explicitref mut
binding mode, requiring more involved changes to the pattern. I'm not sure it's worth giving a structured suggestion in this case, but at least a help that's correct would be better than a suggestion that's wrong. Here's an example of what could be done to get the pattern to work without changing the scrutinee:
let &mut (Ok(ref mut _y) | Err(&mut ref mut _y)) = &mut x;
Alternatively, this could maybe be approached as a match ergonomics issue instead of a diagnostics issue: usually using a &mut
ref implicitly reborrows, but pattern bindings will move unless you write &mut ref mut x
. Of course, by-move pattern bindings are used specifically for moving, so I don't think the answer is "make patterns implicitly reborrow", but I'm not totally sure that the current state of affairs is the best it could be either. cc @Nadrieril
@rustbot label +D-imprecise-spans +D-invalid-suggestion +A-patterns
Rust Version
rustc 1.90.0-nightly (da58c0513 2025-07-03)
binary: rustc
commit-hash: da58c051315268a197ce280f6ba07bbd03c66535
commit-date: 2025-07-03
host: x86_64-unknown-linux-gnu
release: 1.90.0-nightly
LLVM version: 20.1.7