Compiler error doesn't occur

I'm reading rust document following this URL now.
https://doc.rust-jp.rs/book-ja/ch04-02-references-and-borrowing.html

it says this folloing code will be error because this also borrowed as immutable
let mut s = String::from("hello");
let r1 = &s; // np
let r2 = &s; // np
let r3 = &mut s; // problem

but in my environment, the compiler error didn't be thrown.
I don't know why. Could you help me why it is not error in my environment?
Thanks.

The borrow checker got smarter longtime ago, so that's no longer a compilation error. If you still want to see it in action, use r2 after r3 is declared:

2 Likes

@moy2010
Thank you for your quick reply.
That's big help for me! I got it.

That is odd:

✗ cargo --version
cargo 1.68.0-nightly (70898e522 2022-12-05)
 ✗ cat src/main.rs
pub fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    let r2 = &mut s;
    println!("{}, {}", r1, r2);
}
✗ cargo run  --release
   Compiling bit v0.1.0 (/Users/michaael/conveqs/bit)
error[E0499]: cannot borrow `s` as mutable more than once at a time
  --> src/main.rs:16:14
   |
15 |     let r1 = &mut s;
   |              ------ first mutable borrow occurs here
16 |     let r2 = &mut s;
   |              ^^^^^^ second mutable borrow occurs here
17 |
18 |     println!("{}, {}", r1, r2);
   |                        -- first borrow later used here

For more information about this error, try `rustc --explain E0499`.
error: could not compile `bit` due to previous error
1 Like

Ah, but if you remove the println!then there is no error.

1 Like

You have to print both r1and r2 to get the error. As per the example in the docs.

1 Like

it seems to be error when we use the variables.:pleading_face:
Thank you for trying on your machine!!

I guess the idea is that if you do not use a variable then the compiler does not even include it in the compiled code. If a borrow, like r1 and r2, does not exist in the executable then no borrow is actually made. And hence no error.

It's like agreeing to borrow your friends car and then never actually driving it away. You had a borrow agreement but no borrow ever happened.

3 Likes

Your example is easy to understand for me. Thank you.
I'm surprising at what the compiler is smart like that.

It wasn't always like that. People worked for a long time to make that happen. In fact process have only finished few months ago.

Actually it covers more cases. It's more like Bob's whining “you had an agreement with Alice for a month, but she returned car after three days… if you have it, why can't I borrow it?”…

Rice's theorem guarantees that you can never have 100% correct detection of rules violation thus choice is between being too strict or too lax in checking.

C/C++ tries to be too lax and put the onus on the developer, but that cause insane amount of frustration.

Because people don't know about Rice's theorem and naïvely assume that “no complains from the compiler == no bugs”.

Rust splits the decision: in unsafe Rust it acts as C/C++ (but these are for rare cases where normal, “safe” Rust just doesn't work), in “safe” Rust it's too strict, instead.

But if you relax these too strict rules over time valid programs would still work but people would complain about borrow-checker stupidity less.

And that's what Rust is doing.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.