-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Borrow checker overly conservative when assigning to a parent reference #27614
Comments
For the sake of completeness, I should mention that adding a trivial let statement is sufficient for the loop to compile, but that should not be needed in a ideal world. |
This is well-known. If |
This can be worked around by doing something like |
Yes, However, I somehow doubt rust-lang/rfcs#811 will be of any help here. Even if borrows were dataflow-sensitive, the example above would still not pass. Indeed, the issue is not with the None branch (the RFC would be helpful there), it is with the Some branch. The example really involves two Below is a less simplified example: insertion in a sorted list. Hopefully, one day, the five extra lines (and their associated runtime cost) will no longer be needed to make the borrow checker happy.
|
Consider the following simplified testcase. This is some Rust translation of the C idiom
while ((p = p->next))
.The code compiles fine. Unfortunately, it relies on a recursive call. Since Rust does not perform any tail call optimization, let us transform the code by hand. So, instead of calling the function recursively, we just update its argument inside a loop:
The code no longer compiles, since Rust detects 3 errors with it. Actually, only one matters (as can be seen by removing the loop), "cannot assign to p because it is borrowed". Given the borrowing rules as I understand them, the compiler is right to complain. Indeed, we have live references to values accessible by paths going through p, so accessing p is forbidden.
The rules seem overly conservative though, since no alias is being created when assigning a parent reference. Indeed, the only path to access the content pointed by p goes through p (since p is &mut); modifying p cannot break that invariant by adding a new path. At worst, modifying p could remove the only known path to the content previously pointed to. (Note that p is just a reference, so the assignment is atomic and without any side-effect.)
The text was updated successfully, but these errors were encountered: