Moving mutably borrowed ownership

rust borrow vs move
rust immutable borrow after mutable borrow
rust borrow
cannot move out of which is behind a mutable reference
rust move
mutable reference rust
borrowed value rust
consider removing the borrow rust

My understanding is that a mutable borrower can move ownership to another mutable borrower. But this move seems to be a bit different from moving a non-pointer variable. Let's see an example. Below p1 gets moved to p2 when compute() is called the first time. But the ownership seems to come back to p1 after compute() returns.

fn compute(p2: &mut Point) {
}

fn reset(p1: &mut Point) {
    compute(p1); //OK
    compute(p1); //OK
}

This is different from how a regular variable is moved.

fn compute(p2:  Point) {
}

fn reset(p1: Point) {
    compute(p1); //OK
    compute(p1); //Compile error
}

Now, ownership does not revert back to p1 after the first compute() call returns.

Both behaviors are understandable and desirable for many reasons. But I just wanted to confirm my understanding that the two moves are slightly different in nature. Am I right thinking this way?

You're correct except that in the first instance, the reference is not being moved, it's simply being reborrowed, which is behavior particular to references. Perhaps this clears it up, as it's not an exception within move semantics, but a different behavior altogether.

In Rust, a move means that data's ownership has been handed over from Here, our mutable borrow occurs in the function change_name()  The _mut suffix (e.g. foo_mut) for the mutably borrowed variant. Exceptions In the case of iterators, the moving variant can also be understood as an into conversion, into_iter , and for x in v.into_iter() reads arguably better than for x in v.iter_move() , so the convention is into_iter .

The way I understand it is that your first snippet borrows, where as your second transfers ownership.

fn compute(p2:  Point) {
    // compute owns p2
} // owned p2 is freed

fn reset(p1: Point) {
    // reset() owns p1
    compute(p1); //Ownership of p1 is transferred to compute()
    compute(p1); //ERROR: p1 has already been freed
}

Vice...

fn compute(p2:  &Point) {
    // compute is borrowing p2
} // borrowed p2 is given back to owner

fn reset(p1: Point) {
    // reset() owns p1
    compute(&p1); //let compute() borrow p1, then get it back
    compute(&p1); //let compute() re-borrow p1, then give it back
} // owned p1 is freed

The move semantics is powerful in preventing the double free error, because each A variable x may mutably borrow a variable y only if y is mutable; otherwise,  Borrow restricts allowable operations (read, write, or move) on the borrowed variable. If the variable x owns a value, when x is borrowed only immutably (i.e., the program has only shared references to x), the program may read x, but not write or move x.

Instead, Rust uses a system of ownership to manage its values with rules error[​E0382]: borrow of moved value: `hello` --> src/main.rs:5:49 | 2 | let Here we create a mutable reference to our variable and pass that to the  How does borrowing and ownership work if you have recursive data structure? I am a total beginner in rust, and I am trying to make sense of the concept of ownership and borrowing semantics under the context recursive data structure.

With ownership move, the original variable holding the value would no error[​E0596]: cannot borrow `*borrow_owner` as mutable, as it is  The _mut suffix (e.g. foo_mut) for the mutably borrowed variant. The _move suffix (e.g. foo_move) for the owned variant. However, in the case of iterators, the moving variant can also be understood as an into conversion, into_iter, and for x in v.into_iter() reads arguably better than for x in v.iter_move(), so the convention is into_iter.

The process of transferring ownership is also called moving, because resource Mutable references are moved, immutable ones are copied. Ownership and Moves The big feature in Rust is Ownership, which means that non-primitive values are moved by default instead of being copied. As an example, if we create a String in Rust and pass it to another function, it will be moved into that function and destroyed there.

In this lesson, we're going to hit the basics of ownership in Rust. error[E0505]: cannot move out of `x` because it is borrowed --> foo.rs:19:20 You cannot take a mutable reference to an immutable variable, and therefore x  The owner is responsible for dropping that value when it goes out of scope, and is the only one who may move the ownership of the value. The owner of a value may give away references to it by letting other pieces of code borrow that value. At any given time, there may be any number of immutable references to a value:

Comments
  • "a mutable borrower can move ownership to another mutable borrower" - in my mind, you either own an object or you borrow one, there's no concept of "borrowed ownership".
  • @Shepmaster, references are regular values and they are subjects to ownership rules too. Without reborrowing &mut would behave exactly like other noncopyable types (i.e. they could only be moved).
  • They will both transfer ownership since a mutable pointer is an uncopyable type. However, "reborrow" happens for a mutable pointer after the compute() function returns, making the pointer variable usable again. That is my understanding. It will be good to see a more official explanation for this.
  • When you pass any type as a function argument, it is moved, including references. It may happen to be a copy that is moved.
  • @Shepmaster: We can use that line of thought as well. But that makes the wordings slightly complicated I guess, because in that case I'd have to add that "when it is reference which is moved, then the object being referred to by the reference does not move".