Mutable reference not re-borrowed by binary operator

8548354
Opened by Steven Allen at 2023-04-05 17:36:45

When implementing a binary operator on &mut Something, the binary operator consumes the mutable reference instead of borrowing it:

use std::ops::Shl;

struct Test;

impl<'a> Shl<()> for &'a mut Test {
    type Output = ();
    fn shl(self, rhs: ()) {}
}

// Compiles
fn test_direct() {
    let mut test = Test;
    let test_ref = &mut test;
    test_ref.shl(());
    test_ref.shl(());
}

// Doesn't compile
//
// ```
// error: use of moved value: `test_ref`
// test_ref << ();
// ^~~~~~~~
// note: `test_ref` moved here because it has type `&mut Test`, which is non-copyable
// test_ref << ();
// ```
fn test_shift() {
    let mut test = Test;
    let test_ref = &mut test;
    test_ref << (); // Should be equivalent to test_ref.shl(())
    test_ref << ();
}

fn main() {}
  1. Is this not intended behaviour? Nothing in the code suggests the &mut should have anything done to it but moved, and &mut's not Copy.

    Aria Desires at 2015-05-24 22:35:25

  2. Oh sorry, I misread. Now I'm confused why the first one does compile.

    Aria Desires at 2015-05-24 22:37:21

  3. If it didn't compile, nothing in rust would work:

    fn push_two_zeros(v: &mut Vec<usize>) {
       v.push(0);
       v.push(0);
    }
    

    Steven Allen at 2015-05-24 23:05:23

  4. @Gankro reborrows are automatically inserted in most places, which is why &mut T appears to be copyable to a certain extent.

    Eduard-Mihai Burtescu at 2015-05-25 16:24:56

  5. Cc me

    Felix S Klock II at 2015-05-26 10:12:28

  6. Triage: no change

    Steve Klabnik at 2016-11-29 21:05:36

  7. Triage: still no change

    Steve Klabnik at 2019-03-16 14:43:23

  8. Still not working. Link to playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a057796d9baed16f4cf6531485134d88

    Patrick Poitras at 2022-01-19 00:59:57