@@ -202,18 +202,18 @@ types. Remember that signed integers are always represented using two's
202202complement. The operands of all of these operators are evaluated in [ value
203203expression context] [ value expression ] so are moved or copied.
204204
205- | Symbol | Integer | ` bool ` | Floating Point | Overloading Trait |
206- | --------| -------------------------| -------------| ----------------| --------------------|
207- | ` + ` | Addition | | Addition | ` std::ops::Add ` |
208- | ` - ` | Subtraction | | Subtraction | ` std::ops::Sub ` |
209- | ` * ` | Multiplication | | Multiplication | ` std::ops::Mul ` |
210- | ` / ` | Division* | | Division | ` std::ops::Div ` |
211- | ` % ` | Remainder | | Remainder | ` std::ops::Rem ` |
212- | ` & ` | Bitwise AND | Logical AND | | ` std::ops::BitAnd ` |
213- | <code >| ; </code > | Bitwise OR | Logical OR | | ` std::ops::BitOr ` |
214- | ` ^ ` | Bitwise XOR | Logical XOR | | ` std::ops::BitXor ` |
215- | ` << ` | Left Shift | | | ` std::ops::Shl ` |
216- | ` >> ` | Right Shift** | | | ` std::ops::Shr ` |
205+ | Symbol | Integer | ` bool ` | Floating Point | Overloading Trait | Overloading Compound Assignment Trait |
206+ | --------| -------------------------| -------------| ----------------| --------------------| ------------------------------------- |
207+ | ` + ` | Addition | | Addition | ` std::ops::Add ` | ` std::ops::AddAssign ` |
208+ | ` - ` | Subtraction | | Subtraction | ` std::ops::Sub ` | ` std::ops::SubAssign ` |
209+ | ` * ` | Multiplication | | Multiplication | ` std::ops::Mul ` | ` std::ops::MulAssign ` |
210+ | ` / ` | Division* | | Division | ` std::ops::Div ` | ` std::ops::DivAssign ` |
211+ | ` % ` | Remainder | | Remainder | ` std::ops::Rem ` | ` std::ops::RemAssign ` |
212+ | ` & ` | Bitwise AND | Logical AND | | ` std::ops::BitAnd ` | ` std::ops::BitAndAssign ` |
213+ | <code >| ; </code > | Bitwise OR | Logical OR | | ` std::ops::BitOr ` | ` std::ops::BitOrAssign ` |
214+ | ` ^ ` | Bitwise XOR | Logical XOR | | ` std::ops::BitXor ` | ` std::ops::BitXorAssign ` |
215+ | ` << ` | Left Shift | | | ` std::ops::Shl ` | ` std::ops::ShlAssign ` |
216+ | ` >> ` | Right Shift** | | | ` std::ops::Shr ` | ` std::ops::ShrAssign ` |
217217
218218\* Integer division rounds towards zero.
219219
@@ -441,24 +441,74 @@ x = y;
441441>   ;  ; | [ _ Expression_ ] ` <<= ` [ _ Expression_ ] \
442442>   ;  ; | [ _ Expression_ ] ` >>= ` [ _ Expression_ ]
443443
444- The ` + ` , ` - ` , ` * ` , ` / ` , ` % ` , ` & ` , ` | ` , ` ^ ` , ` << ` , and ` >> ` operators may be
445- composed with the ` = ` operator. The expression ` place_exp OP= value ` is
446- equivalent to ` place_expr = place_expr OP val ` . For example, ` x = x + 1 ` may be
447- written as ` x += 1 ` . Any such expression always has the [ ` unit ` type] .
448- These operators can all be overloaded using the trait with the same name as for
449- the normal operation followed by 'Assign', for example, ` std::ops::AddAssign `
450- is used to overload ` += ` . As with ` = ` , ` place_expr ` must be a [ place
451- expression] .
444+ * Compound assignment expressions* combine arithmetic and logical binary
445+ operators with assignment expressions.
446+
447+ For example:
448+
449+ ``` rust
450+ let mut x = 5 ;
451+ x += 1 ;
452+ assert! (x == 6 );
453+ ```
454+
455+ The syntax of compound assignment is a [ mutable] [ place expression] , the
456+ * assigned operand* , then one of the operators followed by an ` = ` as a single
457+ token (no whitespace), and then a [ value expression] , the * modifying operand* .
458+
459+ Unlike other place operands, the assigned place operand must be a place
460+ expression. Attempting to use a value expression is a compiler error rather
461+ than promoting it to a temporary.
462+
463+ Evaluation of compound assignment expressions depends on the types of the
464+ operators.
465+
466+ If both types are primitives, then the modifying operand will be evaluated
467+ first followed by the assigned operand. It will then set the value of the
468+ assigned operand's place to the value of performing the operation of the
469+ operator with the values of the assigned operand and modifying operand.
470+
471+ > ** Note** : This is different than other expressions in that the right operand
472+ > is evaluated before the left one.
473+
474+ Otherwise, this expression is syntactic sugar for calling the function of the
475+ overloading compound assigment trait of the operator (see the table earlier in
476+ this chapter). A mutable borrow of the assigned operand is automatically taken.
477+
478+ For example, the following expression statements in ` example ` are equivalent:
452479
453480``` rust
454- let mut x = 10 ;
455- x += 4 ;
456- assert_eq! (x , 14 );
481+ # struct Addable ;
482+ # use std :: ops :: AddAssign ;
483+
484+ impl AddAssign <Addable > for Addable {
485+ /* */
486+ # fn add_assign (& mut self , other : Addable ) {}
487+ }
488+
489+ fn example () {
490+ # let (mut a1 , a2 ) = (Addable , Addable );
491+ a1 += a2 ;
492+
493+ # let (mut a1 , a2 ) = (Addable , Addable );
494+ AddAssign :: add_assign (& mut a1 , a2 );
495+ }
457496```
458497
498+ <div class =" warning " >
499+
500+ Warning: The evaluation order of operands swaps depending on the types of the
501+ operands. Try not to write code that depends on the evaluation order of operands
502+ in compound assignment expressions. See [ this test] for an example of using this
503+ dependency.
504+
505+ </div >
506+
507+ [ mutable ] : ../expressions.md#mutability
459508[ place expression ] : ../expressions.md#place-expressions-and-value-expressions
460509[ value expression ] : ../expressions.md#place-expressions-and-value-expressions
461510[ temporary value ] : ../expressions.md#temporaries
511+ [ this test ] : https://github.com/rust-lang/rust/blob/master/src/test/ui/expr/compound-assignment/eval-order.rs
462512[ float-float ] : https://github.com/rust-lang/rust/issues/15536
463513[ `unit` type ] : ../types/tuple.md
464514[ Function pointer ] : ../types/function-pointer.md
0 commit comments