Why does += require manual dereference when AddAssign() does not?

Aside from the method call rules concentrated above, I want to point out the following sentence is wrong

A += B is actually TypeOfA += TypeOfB. In your case, mri is of type &mut i32, 1 is of type i32.

The AddAssign is defined as:

pub trait AddAssign<Rhs = Self> {
    fn add_assign(&mut self, rhs: Rhs);
}

And the +=

  • desugars to Self += Rhs
  • with the method call <Self as AddAssign<Rhs>>::add_assign(&mut Self, Rhs).
    Or, personally speaking, equivalently in the following two short forms:
    • Self: AddAssign<Rhs>
    • impl AddAssign<Rhs> for Self

So:

  • mri += 1 desugars to &mut i32 += i32 with <&mut i32 as AddAssign<i32>>::add_assign(&mut &mut i32, i32), or
    • &mut i32: AddAssign<i32>
    • impl AddAssign<i32> for &mut i32 which doesn't exist and the compiler emits error[E0368]: binary assignment operation += cannot be applied to type &mut {integer}
  • while AddAssign::add_assign(mri, 1) is the call AddAssign::add_assign(&mut i32, i32), i.e.
    • Self = i32, Rhs = i32
    • impl AddAssign<i32> for i32 does exist

they are not equivalent, since OP didn't stand on the perspective of Rust's type system.

1 Like