Why can't we have multiple &mut


#42

The compiler takes this and effectively generates:

let mut s1: String = String::from("...");

let s: &String = &s1;
drop(s);

let s1_: &mut String = &mut s1;
String::push_str(s1_, "...");
drop(s1_);

println!("{}", s1);

You can’t have a &mut T and a &T at the same time, so the immutable borrow is dropped before the mutable borrow occurs. &mut T is often referred to as a unique reference, whereas &T is a shared reference. You can copy as many &T references and pass them around as you want, but you can only have one &mut T. You can coerce a &mut T into a &T, but you can’t do the reverse.

Theoretically, the immutable reference in your expample is fine in this case since s1 is never moved, but things change if you slightly modified the code.

let s: &str = &s1;
let s: &str = s1.as_str();

This would be a fat reference to the actual data within a String that a points to a raw buffer of bytes, and if you were to modify s1, the reference would be invalidated.


#43

@Joe232 your code in rust actually gets translated into another language before it is run on the computer (basically exactly how english is translated into french). This language is called assembly and looks like

move 32 bits from mem[0x23f2] into register 1
move 3u32 into register 2
multiply register 1 with register 2 and store the result in register 1
test the value in register 1
if the value was 0, jump to the instruction 5 places up

This language directly relates to the capabilities of the silicon. There will be a circuit adding integers, and one for testing and so on. On the chip, there is a pulse of electricity (2_000_000_000 times a second on a 2GHz chip), and each pulse runs an instruction.

The compiler (and LLVM) is doing a lot of work so you don’t have to think about all this, but you do have to maintain all the invariants it expects. :slight_smile:

Note in reality it’s a lot more complicated, but this is the general idea.


#44
  1. Rust is safe and multi-threaded safe, so if you will give const variable to one thread that constantly reads read-only variable, and another mut variable thread that mutating string, changing size, eventually SEGFAULT happen, or even security leak

  2. In case of single threaded, same situation can be simulated using slice function that will lead to SEGFAULT or security leaks.

So rust compiler doesn’t allow this, until you will start using unsafe instructions.