Skip to content

Mutable let-else binding produces dereferenced type when deconstructing references #112545

Closed as not planned
@udoprog

Description

@udoprog

I tried this code:

pub fn main() {
    let value: Option<u64> = Some(10);
    let other: u64 = 20;

    let Some(mut value) = &value else {
        panic!();
    };

    value = &other;
}
error[[E0308]](https://doc.rust-lang.org/stable/error_codes/E0308.html): mismatched types
 --> src/main.rs:9:13
  |
5 |     let Some(mut value) = &value else {
  |              --------- expected due to the type of this binding
...
9 |     value = &other;
  |             ^^^^^^ expected `u64`, found `&u64`

Note a non-mutable binding works as expected:

let Some(value) = &value else {
  panic!();
};

In my mind, value should be a mutable binding to &u64, but the desugaring performed seems to cause the mutable binding in particular to result in attempting to move the de-referenced value.

This is apparent when dealing with non-copy types:

pub fn main() {
    let value: Option<String> = Some(String::from("Hello"));
    let other: String = String::from("World");

    let Some(mut value) = &value else {
        panic!();
    };

    value = other;
}
error[[E0507]](https://doc.rust-lang.org/stable/error_codes/E0507.html): cannot move out of a shared reference
 --> src/main.rs:5:27
  |
5 |     let Some(mut value) = &value else {
  |              ---------    ^^^^^^
  |              |
  |              data moved here
  |              move occurs because `value` has type `String`, which does not implement the `Copy` trait

Meta

rustc --version --verbose:

rustc 1.70.0 (90c541806 2023-05-31)

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions