Skip to content

Better messages for next inside for loops #102972

Closed

Description

Given the following code:
playground

fn main() {
    let mut chars = "HHeelllloo,,  wwoorrlldd!!".chars();
    for c in chars.by_ref() {
        print!("{}", c);
        chars.next(); // Skip next
    }
}

The current output is:

error[[E0499]](https://doc.rust-lang.org/stable/error-index.html#E0499): cannot borrow `chars` as mutable more than once at a time
 --> src/main.rs:5:9
  |
3 |     for c in chars.by_ref() {
  |              --------------
  |              |
  |              first mutable borrow occurs here
  |              first borrow later used here
4 |         print!("{}", c);
5 |         chars.next(); // Skip next
  |         ^^^^^^^^^^^^ second mutable borrow occurs here

Ideally the output should look like:

error[[E0499]](https://doc.rust-lang.org/stable/error-index.html#E0499): cannot borrow `chars` as mutable more than once at a time
 --> src/main.rs:5:9
  |
3 |     for c in chars.by_ref() {
  |              --------------
  |              |
  |              first mutable borrow occurs here
  |              first borrow later used here
4 |         print!("{}", c);
5 |         chars.next(); // Skip next
  |         ^^^^^^^^^^^^ second mutable borrow occurs here
 note: a for loop advances the iterator for you. The result is stored in `c`.
 help: if you want to call `next` within the loop, consider `while let`.

or similar. The note and/or help are both subject to changes, this is just a basic idea.
We could also conceivably rewrite the error message to expand on what the note says, like so:

error[[E0499]](https://doc.rust-lang.org/stable/error-index.html#E0499): cannot call `next` inside a for loop, as this results in two mutable borrows of `chars`.
 --> src/main.rs:5:9
  |
3 |     for c in chars.by_ref() {
  |              --------------
  |              |
  |              first mutable borrow occurs here
  |              first borrow later used here
4 |         print!("{}", c);
5 |         chars.next(); // Skip next
  |         ^^^^^^^^^^^^ second mutable borrow occurs here
 note: a for loop advances the iterator for you. The result is stored in `c`.
 help: if you want to call `next` within the loop, consider `while let`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsD-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