Reputation: 878
Why does the following fail to compile (2018 edition)
fn main() {
let mut s = String::from("hello");
let r1 = &mut s;
{
let _r2 = &s;
}
println!("{}", r1);
}
Why the compiler fails to notice that _r2 is unused and successfully compile the above? It complains that we have both mutable and immutable refs and mutable is used in println.
Upvotes: 2
Views: 125
Reputation: 170713
the confusing part is that literature (books etc...) talk about "using block to restrict borrowing scope. "Beginning Rust" p348 for example. So I found it confusing that we advocate for such practices but it (sometimes) does not work.
But it does work here; the scope of _r2
is restricted by the block it's
declared in. The problem is just that r1
is visible in this scope as well.
That is, the error message is not saying "you can't println
because there are both mutable and immutable borrows at that point", but "you can't declare _r2
because there is already a mutable borrow at that point". println
only appears as a reason why r1
is still alive at the point of _r2
's declaration.
You can see it from the error message:
error[E0502]: cannot borrow `s` as immutable because it is also borrowed as mutable
--> src/main.rs:5:19
|
3 | let r1 = &mut s;
| ------ mutable borrow occurs here
4 | {
5 | let _r2 = &s;
| ^^ immutable borrow occurs here
6 | }
7 | println!("{}", r1);
| -- mutable borrow later used here
^^
points at the actual error location; --
are other related locations.
Upvotes: 3
Reputation: 7
You can only do like this,
fn main(){
let mut s = String::from("hello");
let r1 = &mut s;
{
let r2 = &r1;
}
println!("{}", r1);
}
Upvotes: -1