'Rust's borrow-checker, for loop and structs methods

I'm struggling to find a solution for the error in the code below:

struct Cell {
    line: u8,
    column: u8,
    square: u8,
    value: u8,
}


struct Sudoku {
    cells: Vec<Cell>,
}

impl Sudoku {
    
    fn possible_values(&self, cell: &Cell) -> Vec<u8> {
        ...
    }

    fn solve(&mut self) {
        for cell in self.cells.iter_mut() {
            if cell.value == 0 {
                let possible_values = self.possible_values(&cell);
                match possible_values.len() {
                    0 => panic!("La résolution semble impossible"),
                    1 => {
                        cell.value = possible_values[0];
                        println!("In cell {:?} I would write {}", cell, possible_values[0]);
                    }
                    _ => (),
                }
            }
        }
    }
}
    

The error is:

error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable

for mut cell in self.cells.iter_mut() (on self: mutable borrow occurs here and mutable borrow later used here

let possible_values = self.possible_values(&cell); (on self: immutable borrow occurs here )

The function possible_values borrows self (not mutable).

The for loop needs an iter_mut() because I want to change cell.value, but I also need to use the possible_values function to get the value I want to assign to cell.value. How can I manage do do that?

Here is the code.



Solution 1:[1]

I think you should remove the mut from for mut case.

An example from the docs:

// Then, we iterate over it and increment each element value:
for element in slice.iter_mut() {
    *element += 1;
}

Solution 2:[2]

You can get around the borrow checker by identifying the cell by its index instead of holding a reference.

for i in 0..81 {
    if self.cells[i].value == 0 {
        let possible_values = self.possible_values(&self.cells[i]);
        match possible_values.len() {
            0 => panic!("La résolution semble impossible"),
            1 => {
                self.cells[i].value = possible_values[0];
                println!(
                    "In cell {:?} I would write {}",
                    self.cells[i], possible_values[0]
                );
            }
            _ => (),
        }
    }
}

playground

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 lhk
Solution 2 apilat