Two mutable references

Why is this happening?

cargo 1.51.0 (43b129a20 2021-03-16)

fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    let r2 = &mut s; // defined and not used

    change(&mut s);

//    println!("{}, {}", r1, r2);
    println!("{}", s);
}

fn change(some_string: &mut String) {
    some_string.push_str(", world!");
}

The above code will compile, but there are warnings。

$ cargo build
warning: unused variable: `r1`
  --> src/main.rs:17:9
   |
17 |     let r1 = &mut s;
   |         ^^ help: if this is intentional, prefix it with an underscore: `_r1`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `r2`
  --> src/main.rs:18:9
   |
18 |     let r2 = &mut s;
   |         ^^ help: if this is intentional, prefix it with an underscore: `_r2`

warning: 2 warnings emitted

    Finished dev [unoptimized + debuginfo] target(s) in 0.00s

The warnings are about variables that you defined but never used. You just used s directly instead.

If you uncomment the first println!, there's a borrow checker error. Rust's borrow checking rules don't allow you to interleave non-exclusive borrows like r1 and r2 with mutations. So:

   let r1 = &mut s;
   let r2 = &mut s; // You can now no longer use r1
   change(&mut s);  // You can now no longer use r2, either

    // So this is an error:
    // println!("{}, {}", r1, r2);

I think even r2 is not used, compiler should output error message.

It used to, but now the compiler supports non-lexical lifetimes (NLL).

When the compiler looks for multiple mutable references, it looks at its last use, not when it goes out of scope to determine if they overlap.

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.