The issue is that your iterator returns a mutable reference to the slice it contains without borrowing the iterator. Thus you now have two overlapping mutable references, neither of which is a borrow of the other. This is not allowed in Rust. To fix this, replace the slice with a shorter slice to avoid the overlap like this:
struct IterMut<'a> {
collection: &'a mut [i32],
}
impl<'a> Iterator for IterMut<'a> {
type Item = &'a mut i32;
fn next(&mut self) -> Option<Self::Item> {
// take replaces self.collection with an empty slice
let slice = std::mem::take(&mut self.collection);
match slice.split_first_mut() {
Some((head, tail)) => {
self.collection = tail;
Some(head)
}
None => None
}
}
}
Alternatively you can reuse the IterMut already found in the standard library like this.
The reason that the returned reference is not considered a borrow of the iterator is that the signature of next looks like this with elided lifetimes inserted:
fn next<'s>(&'s mut self) -> Option<&'a mut i32>
Notice how the reference doesn't use the lifetime parameter of the self argument. The fact that the lifetimes do not match means that the return value is not a borrow of the iterator. (Instead, it's considered a borrow of the R you created the iterator from.)
This allows you to call next multiple times without throwing the previous item away.
// this is ok
let mut iter = rrr.iter_mut();
let a = iter.next().unwrap();
let b = iter.next().unwrap();
println!("{}", *a);
println!("{}", *b);