I am just puzzeled as a beginner, how to solve this? I need both neighbor cells mutable returned from neighbors , to make computations on them. I could return immutable but then I cannot turn them into &mut Cell s because that does not exist (undefined behavior). Whats the common idiom here?
You have multiple solutions with different levels of complexity and safety.
You could rely on internal mutability, which moves some of the lifetime checking to runtime, with the associated performance cost and some ergonomic costs, but this is usually a reasonable thing to do, particularly to unblock at first.
Another solution could be to rework your API to pass in closures for the mutation of the neighbors to get around the borrowing problems, but I wouldn't do this.
Finally, you can rely on unsafe, but you have to ensure that you're not running afoul of the Rust aliasing guarantees, similarly to how &mut [T]::split_at_mut(), but if you don't need this, given that you don't have experience dealing with unsafe, I'd stay away from it. Having said that, because split_at_mut already exists, you can use it.
(Getters and setters are less common in Rust due to borrowing issues like this; when they do still exist, you usually at least don't use them in the struct's own module. By the way, that particular getter could also be replaced with an implementation of IndexMut. Perhaps the methods named get (or get_mut) should check the bounds and return an Option.)
If you had two fields instead of one array with two members, Rust would understand (within a single function) that accessing each one individually can't create an overlap. But it doesn't understand that for different array indices, so you need the borrow splitting that @ekuber talked about. In this particular case, you can also use match on the array in neighbor. Or for the more general version, match on a slice.