Permissions-Scalar

mutable reference

Very similar to the const pointer to const variable in C and C++ but the positioning of the mut keyword is more intuitive:

  • Mutable reference: this means that the referenced memory can be modified.
#![allow(unused)]
fn main() {
    let mut a = 5;
    let b = &mut a;    
    *b += 1;
}
  • Mutable reference to immutable variable.
unlike C and C++ where a pointer to const pointer can be still modified if the pointer get reassigned to a non-const pointer, rust compiler will check this and not allow it, guaranteeing memory safety.
#![allow(unused)]
fn main() {
    let a = 5;
    let b = &mut a; // cannot borrow as mutable since a was declared as immutable.
    *b += 1;
}
  • b cannot be reassigned to reference another variable, because it is immutable.
#![allow(unused)]
fn main() {
    let mut a = 5;
    let mut c = 66;
    let b = &mut a; // immutable reference to mutable variable
    *b += 1;
    b = &mut c;
    *b += 1;
}
  • When b is mutable it can be reassigned.
#![allow(unused)]
fn main() {
    let mut a = 5;
    let mut c = 66;
    let mut b = &mut a; // mutable reference to mutable variable
    *b += 1;
    println!("{b}");
    b = &mut c;
    *b += 1;
    println!("{b}");
}

mutable reference effects on permissions

Lets take the following 4 usecases.

casesComment
b = &a;
b = &mut a;
mut b = &a;
mut b = &mut a;

b = &a;

  1. a is declared.
  2. b takes ownership of a but only with R permission.
  3. both a and b are accessible in R only.
  4. once b is last used in the current scope, a will recover its W permission.

b = &mut a;

  1. a is declared.
  2. b takes ownership of a but only with R permission.
  3. b are accessible inre R only but a lose the R permission.
  4. once b is last used in the current scope, a will recover its W permission.

mut b = &a;

  1. a is declared.
  2. b takes ownership of a but only with R permission.
  3. b is reassigned to mut reference to c.
  4. b’s permission still is defined from the first assignment
Here a weird behaviour, since b is mutable, it should be possible to reassign it to a reference of mutable c. but the borrow checker do not agree with it. Is a feature or a bug?
#![allow(unused)]
fn main() {
    let mut a = 5;
    let mut c = 66;
    let mut b = &a;
    // *b += 1;
    println!("{b}");
    b = &mut c;
    a += 1;
    println!("{b}");
    *b += 1; // this line will not compile
    println!("{b}");
}

mut b = &mut a;

  1. a is declared.
  2. b takes ownership of a but with W permission.
  3. b is reassigned to mut reference to c
  4. b type is decided from the first assignment
Here a weird behaviour: it is not possible to assign to b a non mutable c.
#![allow(unused)]
fn main() {
    let mut a = 5;
    let mut c = 66;
    let mut b = &mut a;
    *b += 1;
    println!("{b}");
    b = &mut c;
    a += 1;
    println!("{b}");
    *b += 1;
    println!("{b}");
}