I am trying to implement an Iterator that will go through a matrix line by line.
struct Matrix {
col_count: usize,
backing: Vec<bool>
}
fn get_row_mut<'a>(&'a mut self, row: usize) -> &'a mut [bool] {
&mut self.backing[row * self.col_count .. (row + 1) * self.col_count]
}
struct MatrixIterator<'a> {
matrix: &'a mut Matrix,
curr_row: usize
}
impl<'a> IntoIterator for &'a mut Matrix {
type Item = &'a mut [bool];
type IntoIter = MatrixIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
MatrixIterator {matrix: self, curr_row: 0}
}
}
impl<'b, 'a: 'b> Iterator for MatrixIterator<'a> {
type Item = &'a mut [bool];
fn next(&mut self) -> Option<Self::Item> {
let row : &'b mut [bool] = self.matrix.get_row_mut(self.curr_row);
if self.curr_row < self.matrix.row_count {
Some(row)
} else {
None
}
}
}
with the errors:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/matrix.rs:93:48
|
93 | let row : &'b mut [bool] = self.matrix.get_row_mut(self.curr_row);
| ^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 92:5...
--> src/matrix.rs:92:5
|
92 | fn next(&mut self) -> Option<Self::Item> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/matrix.rs:93:36
|
93 | let row : &'b mut [bool] = self.matrix.get_row_mut(self.curr_row);
| ^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'b` as defined on the impl at 90:6...
--> src/matrix.rs:90:6
|
90 | impl<'b, 'a: 'b> Iterator for MatrixIterator<'a> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/matrix.rs:93:36
|
93 | let row : &'b mut [bool] = self.matrix.get_row_mut(self.curr_row);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Firstly, is the compiler trying to guess the lifetime of the value returned by get_row_mut? If so, Which is the reference the compiler is concerned about regarding the first conflicting requirement? Also, wouldn't 'a as a lifetime be the perfect candidate?
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/matrix.rs:95:13
|
95 | Some(row)
| ^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'b` as defined on the impl at 90:6...
--> src/matrix.rs:90:6
|
90 | impl<'b, 'a: 'b> Iterator for MatrixIterator<'a> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/matrix.rs:95:18
|
95 | Some(row)
| ^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 90:10...
--> src/matrix.rs:90:10
|
90 | impl<'b, 'a: 'b> Iterator for MatrixIterator<'a> {
| ^^
note: ...so that the types are compatible
--> src/matrix.rs:92:46
|
92 | fn next(&mut self) -> Option<Self::Item> {
| ______________________________________________^
93 | | let row : &'b mut [bool] = self.matrix.get_row_mut(self.curr_row);
94 | | if self.curr_row < self.matrix.row_count {
95 | | Some(row)
... |
98 | | }
99 | | }
| |_____^
= note: expected `std::iter::Iterator`
found `std::iter::Iterator`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
As for this error, my though process is: Some(row)
's lifetime shouldn't be longer than b' - that means it can be b'. So now we have the requirement that b' should be valid for lifetime a'. Well, if a' == b', then that would also be true. Basically Some(row)
's lifetime should be == a' == b' and both requirements seem to be satisfied, but there should be a flaw in that logic that I can't see