Borrowing references to struct attributes

The first and foremost thing to understand is that function signature declares an interface - it's not just a hint. This is critical to understand. The interface of all of update, update_1a, and update_1b is that they mutably borrow the entirety of Field for the duration of the routine.

When you are borrowing a structure mutably, you are then free to borrow any of the sub-elements mutably. HOWEVER, those sub-borrow imply a transitive borrow on the parent structure - after all, maintaining that borrow may be essential to enforcing certain invariants between fields of the struct.

So, take a look at update_1b. Its signature is asking for it to mutably borrow the entirety of self. However, update_1a cannot call update_1b in the way it does since a mutable borrow must be exclusive, and you're attempting to simultaneously borrow the players part of the struct and the entire struct exclusively.

Many have tried to argue against this - that a sufficiently smart compiler should be able to "see" that update_1a's usage of update_1b is legal since update_1b is only borrowing the ball field. However, it's not this simple - if ball and players need to be kept in sync in some way, especially to enforce some safety-critical property the compiler can't see, then it would be illegal for the compiler to allow this.

6 Likes