Created
March 26, 2015 21:14
-
-
Save jviereck/227377d9b27157ad4359 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Goal of this file: | |
| // Figure out in which cases a "move" or a "borrow" operation is performed | |
| // by the rust compiler. | |
| // | |
| // Finding: | |
| // - A "simple" assignment without defining the type on the local variable | |
| // cause the field to be moved: | |
| // | |
| // let id_ref = entry.id; // entry.id is moved! | |
| // | |
| // - Defining the type on the local variable causes a borrow of the field's | |
| // borrowed value. Note that no `&mut` is required in this case for the RHS! | |
| // | |
| // let id_ref: &mut isize = entry.id; | |
| // | |
| // - Using an `&mut` operation does not take a new borrow from the borrowed | |
| // value itself but creates a new borrow to the field itself (you end up | |
| // with a double pointer when following the terminology of C/C++). The | |
| // type in the following case if then of `&mut &mut isize`. | |
| // | |
| // let id_ref = &mut entry.id; | |
| // | |
| // - The two following notations are equivalent: | |
| // | |
| // let id_ref = &mut entry.id; | |
| // let ref mut id_ref = entry.id; | |
| // | |
| struct Entry<'a> { | |
| id: &'a mut isize | |
| } | |
| fn owned_field_move() { | |
| let mut id = 1; | |
| let entry = Entry { id: &mut id }; | |
| // The following statement will MOVE the content of the entry.id field. That | |
| // means, that the `id_ref` contains the `&mut isize`. The type of `id_ref` | |
| // is `&mut isize`. | |
| let id_ref = entry.id; | |
| // ATTEMPT FAILS | |
| // The following line is rejected by the rust compiler as the line above moved | |
| // value `entry.id` out already. | |
| // | |
| // error: use of moved value: `entry.id` | |
| // | |
| // println!("entry.id={}", entry.id); | |
| } | |
| fn owned_field_typedef() { | |
| let mut id = 1; | |
| let entry = Entry { id: &mut id }; | |
| // The following statement will BORROW the content of the `entry.id` by taking | |
| // an mutable borrow on it. | |
| // -> When a type signature is specified on the local variable, then a borrow | |
| // is performed over a move. | |
| let id_ref: &mut isize = entry.id; | |
| *id_ref = 1; | |
| println!("entry.id={}", id_ref); | |
| // ATTEMPT FAILS | |
| // As above, the following lines is rejected. HOWEVER, the reason is different | |
| // here - the statement is rejected, as the `entry.id` is now mutable borrowed | |
| // to `id_ref`. | |
| // | |
| // error: cannot borrow `entry.id` as immutable because `*entry.id` is also | |
| // borrowed as mutable | |
| // | |
| // println!("entry.id={}", entry.id); | |
| } | |
| fn owned_field_mut_borrow() { | |
| let mut id = 1; | |
| let entry = Entry { id: &mut id }; | |
| // ATTEMPT FAILS | |
| // The following statement will not work. Note that the return type of the RHS | |
| // with the `&mut` operation is of type `&mut &mut isize`. So, instead of | |
| // "just taking a new borrow" on the existing field type, the operation tries | |
| // to create a double pointer/borrow to the `entry.id` field. But that is not | |
| // allowed, as `entry` is immutable, therefore all its fields are also immutable | |
| // and therefore the `id` field is immutable and the compiler therefore rejects | |
| // the mutable borrow attempt. | |
| // | |
| // cannot borrow immutable field `entry.id` as mutable | |
| // | |
| // let id_ref = &mut entry.id; | |
| // NOTE: The line | |
| // | |
| // let ref mut id_ref = entry.id; | |
| // | |
| // is equivalent to specifing the `&mut` on the RHS as in | |
| // | |
| // let id_ref = &mut entry.id; | |
| } | |
| fn main() { | |
| owned_field_move(); | |
| owned_field_typedef(); | |
| owned_field_mut_borrow(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment