-
Notifications
You must be signed in to change notification settings - Fork 13.3k
No compiler error message when more than one mutable ref to mutable var is declared. #113243
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
Comments
This is probably because of either NLL (non-lexical lifetimes) or Polonius, but basically the borrow checker will only raise an error if you actually try to violate the borrowing rules - that is, using both mutable lifetimes, rather than just one. If you use just one, then only one exists at a time, and all is right with the world (because we can just say that the other ones were dropped before you used that one). I'm leaving out all the semantics of stacked/tree borrows of course, which are just theories that want to take the current rough state of things and extrapolate it into a comprehensive and well-defined ruleset, but they are still pretty good approximations of what you can expect from Rust today if you look at the Stacked Borrows documents linked here. |
Actually, there is apparently a name for this specific concept - "two-phase borrows", where there is a gap between when you take a reference to something (the first phase) and first use the reference to that thing (the second phase). Therefore taking two mutable references to the same thing in succession won't raise any error as long as only one of them enter enters phase two. |
Well obviously I'm in my Rust early days so its going to be a while before I did that deep but I cant help but wonder if my comments were not clear. It confusing to me that the following will generate a compiler error let mut mutable_int = 100; and the following does not let mut mutable_int = 100; They seem like similar cases to me (das Rust newb). Thx for quick response on a Saturday. |
Just trying to help
For the first one, it's because you tried to use mref1 after creating mref2. mref2's creation invalidates mref1; since there can only be one mutable borrow at a time, creating a new one causes all the others to become invalid. (Mainly, anyway.) For the second one, mref2 invalidates mref1, but you use mref2 so it's fine. |
Don't be worried that Rust is hard to learn, it is. Stuff like this happens all the time, only thing you can do is keep on trying. Most likely this is not a bug in Rust, and is just something that the documentation didn't explain very well. Maybe you could join the community Discord server and try to find out what happened :) |
The basics of non-lexical lifetimes is that a borrow can be "ended early" if it needs to. In your case 1, In case 2, I have the mental model of "don't interleave XYX" when writing code like this. If case 2 is Since the first one interleaves creating and using two different mutable references, it can't work. The second case doesn't interleave anything at all, so it can work. (Note: there are exceptions, but this model works for most code you want to write) |
I hope the replies help, jraldrin. I'm going to close this now as it seems this is really more of a help question than a compiler bug. You might also be interested in the users forum, official discord server or other Rust communities which are great at answering questions from new users. |
I was trying to write some example code to show that rust won't allow more than one
mutable ref to a mutable var. I came up with an example that I thought should generate
a compiler error but did not.
The code appended does not generate a compiler error.
I do get a compiler error when I comment out
*mref2 = 4 and uncomment
*mref1 = 4
I tried this code:
I expected to see this happen: cannot borrow
mutable_int
as mutable more than once at a timeInstead, this happened: compiled without error
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: