-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Cannot borrow *self
as mutable more than once at a time
#84361
Comments
This is supposed to happen. The lifetime of For more in detail information check out the rust book chapter 4: https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html. Also just to be aware your code will cause an infinite loop as you are matching the value of |
It doesn't explain, why different match arms produce such result. It's seems to be this issue fixed by NLL. |
Polonius borrow checker seems to compile code just fine, but I'm still not 100% sure if this code is correct. |
@In-line submitted this bug based on my question on StackOverflow -- thanks to him. Below is a slightly less artificial example, which maybe makes the problem clearer: pub struct Test(String);
impl Test {
pub fn next(&mut self) -> Option<&str> {
self.0.pop();
if self.0.is_empty() {
None
} else {
Some(&self.0)
}
}
pub fn next_multiple(&mut self, n: usize) -> Option<&str> {
match self.next() {
None => None,
Some(txt) if txt.len() % n == 0 => Some(txt),
Some(_) => self.next()
}
}
} The method |
I'm a little fuzzy on lifetimes, so take this with a grain of salt, but it looks like the issue is that the lifetime of the first It seems to me like it definitely needs the lifetime to persist at least to the Like I said, I'm fuzzy on lifetimes, so I might be missing something, but this seems like expected and proper behavior to me. |
The problem here is that the reference created by the first
there isn't any reason why the
However, such a sinking transformation is only valid in absence of side-effectful drops (which Rust does have). In that situation user could observe that the Additionally, while we do have situations where the behaviour of borrowck changes based on certain drop-specific relationships, we still maintain the property that in most (all?) cases adding a |
@nagisa Can we theoretically change drop order for next Rust edition? |
@nagisa thanks for this explanations. I tried to explicitly change the drop order using pub fn next_multiple(&mut self, n: usize) -> Option<&str> {
let opt = self.next();
match opt {
None => return None,
Some(txt) if txt.len() % n == 0 => return Some(txt),
Some(_) => (),
}
std::mem::drop(opt);
self.next()
} |
I have a similar issue like this. I have client_id and server_id. The logic is to get a pub fn get_live_order_mut(&mut self, client_id: &str, server_id: &str) -> Option<&mut Order> {
let this = self as *mut Self;
unsafe {
if let Some(x) = (*this).live_orders.get_by_cid_mut(client_id) {
Some(x)
} else {
(*this).live_orders.get_by_sid_mut(server_id)
}
}
} |
I tried this code:
I expected to it to compile without erorrs.
Instead, this happened:
Playground link
Playground (version with if)
The text was updated successfully, but these errors were encountered: