Skip to content

Suggestion to make a binding mutable could lead beginners astray #118596

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
Nadrieril opened this issue Dec 4, 2023 · 2 comments · Fixed by #119650
Closed

Suggestion to make a binding mutable could lead beginners astray #118596

Nadrieril opened this issue Dec 4, 2023 · 2 comments · Fixed by #119650
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Nadrieril
Copy link
Member

Code

fn main() {
    let y = Some(0);
    if let Some(x) = y {
        x = 2;
    }
}

Current output

error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:4:9
  |
3 |     if let Some(x) = y {
  |                 -
  |                 |
  |                 first assignment to `x`
  |                 help: consider making this binding mutable: `mut x`
4 |         x = 2;
  |         ^^^^^ cannot assign twice to immutable variable

Desired output

error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:4:9
  |
3 |     if let Some(x) = y {
  |                 -
  |                 |
  |                 first assignment to `x`
  |                 help: consider making this binding mutable: `mut x`
  |                 help: to modify the original value, take a borrow instead: `ref mut x`
4 |         x = 2;
  |         ^^^^^ cannot assign twice to immutable variable

Rationale and extra context

In the original code, it's unclear whether the intention is to modify the contents of y or only the copy contained in x. The suggestion assumes the second case, which gives:

fn main() {
    let y = Some(0);
    if let Some(mut x) = y {
        x = 2;
    }
}

This doesn't modify y yet compiles fine, which I expect could be surprising to a beginner. This meaning of mut is far from obvious. With the updated error message, subsequent errors guide the user to actually modifying y.

Other cases

No response

Anything else?

No response

@Nadrieril Nadrieril added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 4, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Dec 4, 2023
@eggyal
Copy link
Contributor

eggyal commented Dec 4, 2023

Given that y was not declared mut, the suggestion to use ref mut x alone won't be sufficient here. Perhaps the mutability of y's binding should be considered and/or mentioned in the diagnostic.

@Nadrieril
Copy link
Member Author

If you apply the ref mut x suggestion you get another error etc until eventually you get the suggestion to declare y mutable. That feels clear enough to me and a cool series of learnings for my hypothetical beginner.

@chenyukang chenyukang self-assigned this Dec 7, 2023
@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Dec 15, 2023
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 24, 2024
…, r=wesleywiser

Suggest ref mut for pattern matching assignment

Fixes rust-lang#118596
@bors bors closed this as completed in 31e6e8c Apr 25, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants