Skip to content

Compiler incorrectly suggests &mut x instead of &(mut x) in a pattern for Copy types. #122415

Closed
@theemathas

Description

@theemathas

Code

fn mutate(_y: &mut i32) {}

fn foo(&x: &i32) {
    mutate(&mut x);
}

Current output

Compiling playground v0.0.1 (/playground)
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
 --> src/lib.rs:4:12
  |
4 |     mutate(&mut x);
  |            ^^^^^^ cannot borrow as mutable
  |
help: consider changing this to be mutable
  |
3 | fn foo(&mut x: &i32) {
  |         +++

For more information about this error, try `rustc --explain E0596`.
error: could not compile `playground` (lib) due to 1 previous error

Desired output

Instead of suggesting &mut x: &i32, which doesn't compile, the compiler should suggest &(mut x): &i32, which does compile.

Rationale and extra context

This incorrect suggestion occurs when attempting to use a &x pattern to copy a Copy type (i32 in the reproduction code) from a reference, and then mutate the copy. The correct thing to do is to dereference with a & pattern, and assign it to a mut binding, which is written as &(mut x). The compiler incorrectly suggests &mut x, which means something else, and doesn't work.

The original use case that led to this issue had a one-line closure instead of the foo function, which makes doing something like let mut x = x undesirable.

Other cases

No response

Rust Version

1.78.0-nightly (2024-03-11 4a0cc881dcc4d800f106) on the playground

Anything else?

No response

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions