Skip to content

Borrow checker gives confusing error message when in loop #10876

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
ezyang opened this issue Dec 9, 2013 · 9 comments · Fixed by #58743
Closed

Borrow checker gives confusing error message when in loop #10876

ezyang opened this issue Dec 9, 2013 · 9 comments · Fixed by #58743
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ezyang
Copy link
Contributor

ezyang commented Dec 9, 2013

When the borrow check fails in a loop, the error message can be quite confusing:

enum Nat {
    S(~Nat),
    Z
}
fn test(x: &mut Nat) {
    let mut p = &mut *x;
    loop {
        match p {
            &Z => break,
            &S(~ref mut n) => p = &mut *n
        }
    }
}

The borrow checker informs me:

Test.rs|43 col 16 error| cannot borrow `*(*p)#0` as mutable more than once at a time
Test.rs|43 col 16 n| second borrow of `*(*p)#0` as mutable occurs here

This message is confusing, because the two occurrences have the same line number and column. In fact, the error message is right: the borrow check only fails because it is being performed in a loop. The error message should mention something like that to the effect.

@treeman
Copy link
Contributor

treeman commented Sep 15, 2014

Still relevant:

enum Nat {
    S(Box<Nat>),
    Z
}
fn test(x: &mut Nat) {
    let mut p = &mut *x;
    loop {
        match p {
            &Z => break,
            &S(box ref mut n) => p = &mut *n
        }
    }
}

fn main() { }

Gives:

tst.rs:11:20: 11:29 error: cannot borrow `*p#0` as mutable more than once at a time
tst.rs:11             &S(box ref mut n) => p = &mut *n
                             ^~~~~~~~~
tst.rs:11:20: 11:29 note: previous borrow of `*p#0` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*p#0` until the borrow ends
tst.rs:11             &S(box ref mut n) => p = &mut *n
                             ^~~~~~~~~
tst.rs:14:2: 14:2 note: previous borrow ends here
tst.rs:6 fn test(x: &mut Nat) {
...
tst.rs:14 }
          ^

@nham
Copy link
Contributor

nham commented May 18, 2015

Triage: The error looks better, but I'm not sure if it's good enough to close this issue. The updated code:

#![feature(box_patterns)]

enum Nat {
    S(Box<Nat>),
    Z
}
fn test(x: &mut Nat) {
    let mut p = &mut *x;
    loop {
        match p {
            &mut Nat::Z => break,
            &mut Nat::S(box ref mut n) => p = &mut *n
        }
    }
}

fn main() { }

And the new error message is:

iss10876.rs:12:29: 12:38 error: cannot borrow `*p.0` as mutable more than once at a time
iss10876.rs:12             &mut Nat::S(box ref mut n) => p = &mut *n
                                           ^~~~~~~~~
iss10876.rs:12:29: 12:38 note: previous borrow of `*p.0` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*p.0` until the borrow ends
iss10876.rs:12             &mut Nat::S(box ref mut n) => p = &mut *n
                                           ^~~~~~~~~
iss10876.rs:15:2: 15:2 note: previous borrow ends here
iss10876.rs:7 fn test(x: &mut Nat) {
...
iss10876.rs:15 }
               ^
iss10876.rs:12:43: 12:54 error: cannot assign to `p` because it is borrowed
iss10876.rs:12             &mut Nat::S(box ref mut n) => p = &mut *n
                                                         ^~~~~~~~~~~
iss10876.rs:12:29: 12:38 note: borrow of `p` occurs here
iss10876.rs:12             &mut Nat::S(box ref mut n) => p = &mut *n
                                           ^~~~~~~~~
error: aborting due to 2 previous errors

@estebank
Copy link
Contributor

This was fixed in 5b150cf.

@arielb1
Copy link
Contributor

arielb1 commented Jun 18, 2016

No it wasn't. Only the formatting changed.

@steveklabnik steveklabnik added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 9, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 20, 2017
@estebank
Copy link
Contributor

Current output:

error[E0499]: cannot borrow `p.0` as mutable more than once at a time
  --> src/main.rs:10:25
   |
10 |             &mut Nat::S(ref mut n) => p = &mut *n
   |                         ^^^^^^^^^ mutable borrow starts here in previous iteration of loop
...
13 | }
   | - mutable borrow ends here

error[E0506]: cannot assign to `p` because it is borrowed
  --> src/main.rs:10:39
   |
10 |             &mut Nat::S(ref mut n) => p = &mut *n
   |                         ---------     ^^^^^^^^^^^ assignment to borrowed `p` occurs here
   |                         |
   |                         borrow of `p` occurs here

@estebank
Copy link
Contributor

The code now compiles, even in stable. @arielb1 consequence of NLL?

@arielb1
Copy link
Contributor

arielb1 commented Jan 14, 2019

This looks like it (see also #10520, the infamous copy-vs-move problem). I couldn't find a concrete test for this at a quick look, however.

@estebank
Copy link
Contributor

@arielb1 should we add a pass test, come up with a different case or just close?

@estebank estebank added E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. and removed A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Jan 16, 2019
@arielb1
Copy link
Contributor

arielb1 commented Jan 16, 2019

I would like to make sure there is a pass test somewhere in src/test/ui. I believe there should already be one for a very similar case.

varkor added a commit to varkor/rust that referenced this issue Feb 26, 2019
Centril added a commit to Centril/rust that referenced this issue Feb 27, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
varkor added a commit to varkor/rust that referenced this issue Feb 27, 2019
pietroalbini added a commit to pietroalbini/rust that referenced this issue Mar 1, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
Centril added a commit to Centril/rust that referenced this issue Mar 9, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
Centril added a commit to Centril/rust that referenced this issue Mar 9, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
varkor added a commit to varkor/rust that referenced this issue Mar 11, 2019
bors added a commit that referenced this issue Mar 12, 2019
Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes #10876.
Closes #26448.
Closes #26577.
Closes #26619.
Closes #27054.
Closes #44127.
Closes #44255.
Closes #55731.
Closes #57781.
varkor added a commit to varkor/rust that referenced this issue Mar 12, 2019
pietroalbini added a commit to pietroalbini/rust that referenced this issue Mar 12, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
bors added a commit that referenced this issue Mar 12, 2019
Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes #10876.
Closes #26448.
Closes #26577.
Closes #26619.
Closes #27054.
Closes #44127.
Closes #44255.
Closes #55731.
Closes #57781.
flip1995 pushed a commit to flip1995/rust that referenced this issue Jun 30, 2023
…p1995

Adapt versions.html file to cleaned up gh-pages

Companion PR to rust-lang#10875

changelog: Remove legacy v0.0.* versions from Clippy repository and documentation.

Must be merged together with rust-lang#10875 (best with a closed tree)

r? `@Alexendoo` (because you were randomly selected on the other PR :P)
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. 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.

7 participants