I'm trying to learn and understand ownership in rust. And i stuck on this piece of code. I know three rules of ownership one of which is "only one mutual ref at a time". But why is this code works fine if change &mut foo.vec to &mut foo1.vec, the result and type of let vec = &mut foo.vec; are the same but one compiles when the other is not. Thanks in advance.
#[derive(Debug)]
struct Foo {
vec: Vec<String>,
};
let mut foo = Foo { vec: vec!["Hello".to_string()] };
let foo1 = &mut foo;
let vec = &mut foo.vec; // this doesn't work
// but with foo1.vec - works fine
vec.push("World".to_string());
foo1.vec.push("Lorem".to_string());
println!("{:?}", foo1);
If you mutate vec, then you're changing foo out from under foo1, who is holding a mutable (exclusive!) reference.
With the other way:
let foo1 = &mut foo;
let vec = &mut foo1.vec;
The vec reference is derived from foo1, in some sense it's a "finer-grained" reference. Importantly, this only works because you don't interleave uses of vec and foo1. You can only use the foo1 after the mutable borrow of vec is over (vec.push("World".to_string());).
Sorry I jumped ahead. Is this to do with Non-Lexical-Lifetime added in 2018 edition ? Originally I too had the same understanding, as in, the lifetime is tied to the scope.
This is indeed due to non-lexical lifetimes. Before that feature, the borrow of vec would last until the end of the scope (even though it's not used!), and you'd get an error when you tried to use the foo1 reference on the second-to-last line.