Skip to content

Detect when mut arg: &Type should have been arg: &mut Type #112357

Closed
@estebank

Description

@estebank

Code

struct Object;

fn change_object(mut object: &Object) {
    let object2 = Object;
    object = object2;
    // and as follow up object = &object2;
}

fn main() {
    let mut object = Object;
    change_object(&object);
}

Current output

error[E0308]: mismatched types
 --> src/main.rs:5:14
  |
3 | fn change_object(mut object: &Object) {
  |                              ------- expected due to this parameter type
4 |     let object2 = Object;
5 |     object = object2;
  |              ^^^^^^^
  |              |
  |              expected `&Object`, found `Object`
  |              help: consider borrowing here: `&object2`


------


error[E0597]: `object2` does not live long enough
 --> src/main.rs:5:14
  |
3 | fn change_object(mut object: &Object) {
  |                              - let's call the lifetime of this reference `'1`
4 |     let object2 = Object;
  |         ------- binding `object2` declared here
5 |     object = &object2;
  |     ---------^^^^^^^^
  |     |        |
  |     |        borrowed value does not live long enough
  |     assignment requires that `object2` is borrowed for `'1`
6 | }
  | - `object2` dropped here while still borrowed

Desired output

error[E0308]: mismatched types
 --> src/main.rs:5:14
  |
3 | fn change_object(mut object: &Object) {
  |                              ------- expected due to this parameter type
4 |     let object2 = Object;
5 |     object = object2;
  |              ^^^^^^^ expected `&Object`, found `Object`
help: you might have meant to change the `Object` that `object` points to
  |
3 ~ fn change_object(object: &mut Object) {
4 |     let object2 = Object;
5 ~     *object = object2;
  |



----


error[E0597]: `object2` does not live long enough
 --> src/main.rs:5:14
  |
3 | fn change_object(mut object: &Object) {
  |                              - let's call the lifetime of this reference `'1`
4 |     let object2 = Object;
  |         ------- binding `object2` declared here
5 |     object = &object2;
  |     ---------^^^^^^^^
  |     |        |
  |     |        borrowed value does not live long enough
  |     assignment requires that `object2` is borrowed for `'1`
6 | }
  | - `object2` dropped here while still borrowed
help: you might have meant to change the `Object` that `object` points to
  |
3 ~ fn change_object(object: &mut Object) {
4 |     let object2 = Object;
5 ~     *object = object2;
  |

Rationale and extra context

I've seen this case done by a couple of newcomers. For the first case we might want to give both suggestions, depending on how targeted we can actually make this.

Other cases

No response

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.D-papercutDiagnostics: An error or lint that needs small tweaks.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