Skip to content

diagnostics: suggest iter_mut() where trying to modify .iter()'ed vector elements inplace #62387

Closed
@matthiaskrgr

Description

@matthiaskrgr

code:

#[derive(Debug)]
struct A {
    a: i32,
}

impl A {
    fn double(&mut self) {
        self.a += self.a
    }
}

fn main() {
    let mut v = [A { a: 4 }];
    v.iter().for_each(|a| a.double());
    println!("{:?}", v);
}

The code gives the following not-very-helpful warning:

error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
  --> src/main.rs:14:27
   |
14 |     v.iter().for_each(|a| a.double());
   |                        -  ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
   |                        |
   |                        help: consider changing this to be a mutable reference: `&mut A`

warning: variable does not need to be mutable
  --> src/main.rs:13:9
   |
13 |     let mut v = [A { a: 4 }];
   |         ----^
   |         |
   |         help: remove this `mut`
   |
   = note: #[warn(unused_mut)] on by default

error: aborting due to previous error

trying to use

v.iter().for_each(|&mut a| a.double());

and a none-mutable vector just causes more errors

error[E0308]: mismatched types
  --> src/main.rs:14:24
   |
14 |     v.iter().for_each(|&mut a| a.double());
   |                        ^^^^^^ types differ in mutability
   |
   = note: expected type `&A`
              found type `&mut _`
   = help: did you mean `mut a: &&A`?

The actual fix is to use iter_mut() instead of just iter():

#[derive(Debug)]
struct A {
    a: i32,
}

impl A {
    fn double(&mut self) {
        self.a += self.a
    }
}

fn main() {
    let mut v = [A { a: 4 }];
    v.iter_mut().for_each(|a| a.double());
    println!("{:?}", v);
}

It would be very helpful the compiler could suggest iter_mut()!

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.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