I'm implementing a 2D grid type with smart pointers, both non-mutable and mutable, and I want to be able to iterate over the smart pointers to each cell of the grid, both non-mutably and mutably. Implementing an iterator over non-mutable smart pointers went fine, but when I tried to do the equivalent for mutable smart pointers, I got a lifetime error. The only way I can see to solve this error would be to add the 'a
lifetime to the receiver in next()
, but that's incompatible with the trait definition.
Very minimal MVCE:
// Bounds-checking omitted for brevity
struct MyVec<T>(Vec<T>);
impl<T> MyVec<T> {
fn get_cell_mut(&mut self, i: usize) -> CellMut<'_, T> {
CellMut::new(self, i)
}
fn iter_cell_muts(&mut self) -> IterCellMuts<'_, T> {
IterCellMuts::new(self)
}
}
struct CellMut<'a, T> {
vec: &'a mut MyVec<T>,
i: usize,
}
impl<'a, T> CellMut<'a, T> {
fn new(vec: &'a mut MyVec<T>, i: usize) -> Self {
CellMut { vec, i }
}
fn get(&mut self) -> &mut T {
&mut self.vec.0[self.i]
}
}
struct IterCellMuts<'a, T> {
vec: &'a mut MyVec<T>,
i: usize,
}
impl<'a, T> IterCellMuts<'a, T> {
fn new(vec: &'a mut MyVec<T>) -> Self {
IterCellMuts {vec, i: 0}
}
}
impl<'a, T> Iterator for IterCellMuts<'a, T> {
type Item = CellMut<'a, T>;
fn next(&mut self) -> Option<CellMut<'a, T>> {
if self.i < self.vec.0.len() {
let r = Some(self.vec.get_cell_mut(self.i));
self.i += 1;
r
} else {
None
}
}
}
Errors:
Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
--> src/lib.rs:48:13
|
41 | impl<'a, T> Iterator for IterCellMuts<'a, T> {
| -- lifetime `'a` defined here
...
44 | fn next(&mut self) -> Option<CellMut<'a, T>> {
| - let's call the lifetime of this reference `'1`
...
48 | r
| ^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
error: could not compile `playground` due to previous error