I have this code snippet which has both mutable and immutable references existing at the same time but still it compiles why ?
let mut str_1 = String::from("Rust");
let ref_1 = &str_1; // Immutable reference to `str_1`
let ref_2 = &mut str_1; // Mutable reference to `str_1`
println!("{}", ref_2);
This doesn't compile
let mut str_1 = String::from("Rust");
let ref_1 = &str_1; // Immutable reference to `str_1`
let ref_2 = &mut str_1; // Mutable reference to `str_1`
println!("{},{}", ref_2,ref_1);
Is it like unless i don't use the ref_1
in println
it will compile?
Because since the non-lexical lifetimes work borrows end as soon as they're not used anymore[0] (rather than at the end of scope as drops do).
In your first snippet, ref_1
is a dead variable, so the borrow ends as soon as it's created, it's likely the compiler doesn't even create a pointer. Hence on the next line you can borrow str_1
mutably, because the first borrow has already ended (or never existed in the first place).
In the second snippet however, because ref_1
is used by the println!
it has to live until after that macro's execution, thus it overlaps with ref_2
, and because the two borrows are not compatible you get a compilation error.
[0]: kinda, things get more complicated around sub-statement temporaries