Question for "Rust Programming Language" book, Page 132

For the following snippet:

let mut v = vec![1, 2, 3, 4, 5];

// immutable borrow occurs here.
let first = &v[0];

// mutable borrow occurs here.
v.push(6);

According to rust reference and borrow rules, this snippet should not compile, but actually compile successfully with rustc 1.35.

Can someone explain why ?

2 Likes

Guys, Never mind.
The following will not compile:

let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0];
v.push(6);
println!("The first element is: {}", first);

But this will compile:

let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0];
v.push(6);

Seems the compiler is smart enough to detect even there is both immutable and mutable reference at the same scope, but the immutable reference has never been used in the scope.

2 Likes

That’s right. This is one of the large changes in the borrow checker, brought to stable several versions ago - search for “non-lexical lifetimes”, if you’re interested.

1 Like

Your guess is almost correct, but not quite. The key isn’t that the immutable borrow is never used, but that there are no mutable borrows between where the immutable borrow is taken out and its last use. The following will also work, even through the immutable borrow is used:

let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0];
println!("The first element is: {}", first);
v.push(6);
1 Like

Thanks.

Hi, You are totally right. I found the same thing out today.

The thing is:
“The Rules of References” are therotically correct, in addition …
The rust compiler is smart enough to detect if mutable reference and immutable references usage are
overlapping; if not, mutable reference and immutable references can be mixed in one scope.

1 Like