Satisfying the Rust borrow checker with structs
<p>I'm trying to learn Rust, and as you can imagine, the borrow checker is my biggest adversary. So here's my setup, it's a kind of crate for the game battleship. The game is based on the <code>Battlefield</code> struct, which consists of <code>Cell</code>s. A <code>Cell</code> can reference a <code>Ship</code> and a <code>Ship</code> has a vector of all <code>Cell</code>s it's referenced by, so it's a bi-directional read-only relationship.</p>

<pre><code>pub struct Battlefield&lt;'a&gt; {
    cells: Vec&lt;Vec&lt;Cell&lt;'a&gt;&gt;&gt;,
}

#[derive(Debug, PartialEq)]
pub struct Cell&lt;'a&gt; {
    ship: Option&lt;&amp;'a Ship&lt;'a&gt;&gt;
}

#[derive(Debug, PartialEq)]
pub struct Ship&lt;'a&gt; {
    length: usize,
    cells: Vec&lt;&amp;'a Cell&lt;'a&gt;&gt;,
}
</code></pre>

<p>My problem is <code>Battlefield</code>'s <code>place_ship</code> function:</p>

<pre><code>impl&lt;'a&gt; Battlefield&lt;'a&gt; {
    pub fn place_ship(&amp;mut self,
                      ship: &amp;'a mut Ship,
                      x: usize,
                      y: usize,
                      orientation: Orientation)
                      -&gt; PlaceResult {
        // check ship placement in bounds
        // check affected cells are free
        // set cells' ship ref to ship
        // add cell refs to ship's cells field
    }
}
</code></pre>

<p>It makes sense to me and I don't think there's an ownership problem here, but I'm wrong it seems:</p>

<pre><code>#[cfg(test)]
mod tests {
    use super::{Battlefield, X, Y};
    use super::Orientation::*;
    use super::super::ship::Ship;

    #[test]
    fn assert_ship_placement_only_in_bounds() {
        let mut ship = Ship::new(3);
        let mut bf = Battlefield::new();

        assert_eq!(Ok(()), bf.place_ship(&amp;mut ship, 0, 0, Horizontal));
        assert_eq!(Ok(()), bf.place_ship(&amp;mut ship, 5, 5, Vertical));
    }
}
</code></pre>

<pre class="lang-none prettyprint-override"><code>src/battlefield.rs:166:47: 166:51 error: cannot borrow `ship` as mutable more than once at a time [E0499]
src/battlefield.rs:166         assert_eq!(Ok(()), bf.place_ship(&amp;mut ship, 5, 5, Vertical));
                                                                 ^~~~
src/battlefield.rs:165:47: 165:51 note: first mutable borrow occurs here
src/battlefield.rs:165         assert_eq!(Ok(()), bf.place_ship(&amp;mut ship, 0, 0, Horizontal));
                                                                 ^~~~
</code></pre>

<p>I know this is just a short excerpt, but the whole code is too much to post here. The <a href="https://github.com/Leopard2A5/lib-battleship/tree/experiment" rel="nofollow" title="here">project can be found here</a> (standard build with 'cargo build').</p>