Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misleading error message when borrowing immutably in closure #32577

Open
aidanhs opened this Issue Mar 29, 2016 · 4 comments

Comments

Projects
None yet
7 participants
@aidanhs
Copy link
Member

aidanhs commented Mar 29, 2016

struct Y;

struct X {
    noncopy: Y,
    a: usize,
    b: usize,
}

impl X {
    fn x(&mut self) {
        let y = &self.noncopy;
        (|| {
            let a = self.a;
            self.b += 1;
        })();
    }
}

fn main() {}

http://is.gd/NKVuFN

Error message:


<anon>:12:10: 15:10 error: closure requires unique access to `self` but `self.noncopy` is already borrowed [E0500]
<anon>:12         (|| {
<anon>:13             let a = self.a;
<anon>:14             self.b += 1;
<anon>:15         })();
<anon>:13:21: 13:25 note: borrow occurs due to use of `self` in closure
<anon>:13             let a = self.a;
                              ^~~~
<anon>:11:18: 11:30 note: previous borrow of `self.noncopy` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `self.noncopy` until the borrow ends
<anon>:11         let y = &self.noncopy;
                           ^~~~~~~~~~~~
<anon>:16:6: 16:6 note: previous borrow ends here
<anon>:10     fn x(&mut self) {
          ...
<anon>:16     }
              ^

(this error message is repeated three times, even when I compile locally, but that's a distraction)

All you need to do is comment out the self.b += 1; line to make it compile - talking about self.a is misleading because it's not a mutable borrow and is therefore fine.

@cengizIO

This comment has been minimized.

Copy link
Contributor

cengizIO commented Apr 5, 2016

Hello.

Can you please provide a more lightweight example to this?

If not, then what do you think the description should look like?

Since it's somewhat confusing to a beginner like me, I'm having a hard time understanding what's exactly going on here.

@jonas-schievink

This comment has been minimized.

Copy link
Member

jonas-schievink commented Apr 5, 2016

I guess the "borrow occurs" note should be replaced by something like "unique access required because of mutable access to self.b".

@aidanhs

This comment has been minimized.

Copy link
Member Author

aidanhs commented Apr 6, 2016

@cengizIO don't think this example can be reduced. The issue is with

<anon>:13:21: 13:25 note: borrow occurs due to use of `self` in closure
<anon>:13             let a = self.a;

This part of the diagnosis is wrong - let a = self.a; is not problematic (it's an immutable borrow, which doesn't conflict with the immutable borrow outside the closure). Instead, the diagnosis should point to the subsequent line, self.b += 1;, which is a mutable borrow and prevents compilation.

It might also help to talk about unique access and mutable borrows, but I'm less concerned about that.

@Stebalien

This comment has been minimized.

Copy link
Contributor

Stebalien commented Nov 4, 2016

Even smaller example:

fn main() {
    let mut a = ();
    let borrow = &a;
    (|| {
        &a;
        &mut a;
    })();
}
error[E0502]: cannot borrow `a` as mutable because it is also borrowed as immutable
 --> tmp.rs:4:6
  |
3 |     let borrow = &a;
  |                   - immutable borrow occurs here
4 |     (|| {
  |      ^^ mutable borrow occurs here
5 |         &a;
  |          - borrow occurs due to use of `a` in closure
...
8 | }
  | - immutable borrow ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.