3

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

zshehov
  • 31
  • 1
  • Or maybe this? [Simple as possible example of returning a mutable reference from your own iterator](https://stackoverflow.com/q/27118398) – kmdreko Nov 10 '20 at 03:51

0 Answers0