Why are immutable borrows allowed while there is a mutable borrow?


#1

I’m doing a bunch of experimentation to thoroughly understand the borrow checker and move semantics… In doing so, I came across what appears to me to be a strange situation in this code.

In the code, borrower1() mutably borrows our_player and directly after, borrower2() immutably borrows our_player. Isn’t this illegal? It’s my understand that the mutable borrow does not end until the } at the end of main(). Am I incorrect here? Also, I could have sworn that when there is a mutable borrow, there may be no other borrows, read or write, on the same data.


#2

No, because at the end of borrower1() and borrower2() the references they own are dropped, and the don’t return anything that contains that reference. When they are called, they are given ownership of a temporary value (really a reference) (&mut player) and (&player) and those are dropped at the end of the function.


#3

Functions that take references only borrow a variable for the duration of the call,unless they return the reference and you put the returned reference in a variable.

In this example,you can’t move player into mover:

struct Player {
    name: String,
}

fn borrower3(b_player: &Player)->&Player {
    b_player
}

fn mover<T>(_:T){}


let player=Player{
    name:"matt".into(),
};

let player_ref=borrower3(&player); 
// The next line won't compile because player_ref is borrowing player.
// This will compile with non-lexical lifetimes because player_ref is not used afterwards.
// let recaptured = mover(player);