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

for borrowing lasts after the end of the for loop #38614

Closed
progval opened this issue Dec 26, 2016 · 6 comments
Closed

for borrowing lasts after the end of the for loop #38614

progval opened this issue Dec 26, 2016 · 6 comments
Labels
A-borrow-checker Area: The borrow checker

Comments

@progval
Copy link
Contributor

progval commented Dec 26, 2016

Hi,

The following code:

fn method(vector: &mut Vec<u64>) -> &u64 {
    {
        for item in vector.iter() {
            return item
        }
    }

    vector.last_mut().unwrap()
}

Raises an error about vector.iter()'s borrow conflicting with vector.last_mut():

error[E0502]: cannot borrow `*vector` as mutable because it is also borrowed as immutable
 --> <anon>:8:5
  |
3 |         for item in vector.iter() {
  |                     ------ immutable borrow occurs here
...
8 |     vector.last_mut().unwrap()
  |     ^^^^^^ mutable borrow occurs here
9 | }
  | - immutable borrow ends here

However, I would have expected the first borrow to end with the first closing bracket.

Playground URL: https://play.rust-lang.org/?gist=36c206ebc1f8c96b96978a628b5c09a9&version=stable&backtrace=0

@progval progval changed the title For borrowing lasts after the end of the for loop for borrowing lasts after the end of the for loop Dec 26, 2016
@steveklabnik steveklabnik added the A-borrow-checker Area: The borrow checker label Dec 26, 2016
@steveklabnik
Copy link
Member

I believe this is a duplicate, but I'm not sure.

@hanna-kruppe
Copy link
Contributor

This is because of lexical lifetimes and is thus covered by rust-lang/rfcs#811. item is returned, so it must be valid for longer than the loop (longer than the function, actually) and consequently the vector is also borrowed for as long. This isn't a real problem because this only applies to the return path, but because lifetimes are lexical, the compiler only has one choice for the lifetime of that borrow (namely, the lifetime encompassing the whole function).

@steveklabnik
Copy link
Member

I was not 100% sure, but this was also a suspicion I had. Thanks for the report, @progval , but yes, it's covered by that linked issue.

@nox
Copy link
Contributor

nox commented Dec 26, 2016

But the whole loop is in a block by itself, why would the borrow need to survive longer than the enclosing block? Oh I see. Very weird to call this "not a real problem" though, @rkruppe.

@steveklabnik
Copy link
Member

You're reading "not a real problem" backwards; @rkruppe is saying that your code is fine, that it doesn't have an actual problem. Borrowck can't understand that, though.

@nox
Copy link
Contributor

nox commented Dec 26, 2016

Oh I see, thanks for the explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker
Projects
None yet
Development

No branches or pull requests

4 participants