, and I encountered multiple mutable reference with this
fn get_mut(&mut self, start: usize, value: &T) -> Option<&mut T> {
let len = self.items.len()
for i in 0..len {
// `self.items[index]` must have value, so this unwrapping never fails.
match self.items.get_mut((start + i) % len).unwrap() {
^^^^^^^
Some(v) => if v == value { return Some(v) }
^
None => {}
}
}
}
This mutably borrows self.items but the reference will be released at the end of match in any iteration.
It returns only ONE reference in the iterations, so it seems ok.
What's the point?
This is a known limitation of the borrow checker. Your code is okay, there's no reason that the borrow checker complains except that the borrow checker isn't smart enough to accept this use case. It's related to how the lifetime of the borrow of self.items that's passed to get_mut differs on subsequent branching paths. On one path, a reference depending on this borrow escapes the function via the return; on another path, it must end before the next usage of self.items in the next loop iteration.
Possible solutions[1] are listed e.g. also here, along with more context on what's the general issue in the first place; in this case, you can help out the compiler by the relatively minor restructuring of re-doing the get_mut call in the returning branch, so that on non-returning branches, no [even potentially] long-lasting borrows are created in the first place:
let j = (start + i) % len;
// `self.items[index]` must have value, so this unwrapping never fails.
match self.items.get_mut(j).unwrap() {
Some(v) => {
if v == value {
return self.items.get_mut(j).unwrap().as_mut();
}
}
None => {}
}
Good idea; I would further consider .chaining the two iterators, avoiding some code duplication
let len = self.items.len();
let (part_2, part_1) = self.items.split_at_mut(start % len);
let reordered = part_1.iter_mut().chain(part_2);
reordered.filter_map(Option::as_mut).find(|x| *x == value)