1

I just started learning rust. I was following the rust docs. I wrote a program and I am not sure why it works.

According to borrow rules, either I can have one mutable reference in a scope or any number of mutable reference but never both.

So, I cannot have a mutable reference and another immutable reference in the same scope.

But, my program works.

Here is my code -

fn main() {
    let s = String::from("Hi");

    let mut s = random(s);
    change_string(&mut s);

    print(&s);

    let d = &mut s;
    change_string(d);

    let f = &s;

    print(f);
    //  print(d);
    //  change_string(d);
}

fn random(mut s: String) -> String {
    s.push_str("rando");
    print(&s);
    s
}

fn change_string(s: &mut String) {
    s.push_str("Hello");
}

fn print(s: &String) {
    println!("{s}");
}
user2722968
  • 13,636
  • 2
  • 46
  • 67

1 Answers1

1

You're exactly right that you can't have a mutable and immutable borrow simultaneously. In fact, if you uncomment the two commented lines of code, you'll see that Rust will point this out.

However, Rust is terribly clever.

let d = &mut s;
change_string(d);

let f = &s;

print(f);

On the let f = &s line, Rust should fail this code immediately. That's an immutable borrow and we've got a mutable borrow in scope. However, Rust will try to help you. The compiler is smart enough to realize: Okay, we can't have f and also keep d at the same time. Since d is never used again, we can just pretend it went out of scope and everything will be fine.

So Rust will effectively insert a drop(d) just before the declaration of f, since it sees that the variable is never used again. It can't do that if the variable actually is used again, so you get an error in that case. The compiler is just trying to be incredibly helpful.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116