Skip to content

Commit 71b9700

Browse files
committed
Add examples of eval order for compound assignment
1 parent 1353192 commit 71b9700

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/expressions/operator-expr.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,40 @@ r[expr.compound-assign.primitive-order]
906906
If both types are primitives and the expression is non-generic (i.e., directly uses concrete types), then the modifying operand will be evaluated first followed by the assigned operand.
907907
It will then set the value of the assigned operand's place to the value of performing the operation of the operator with the values of the assigned operand and modifying operand.
908908

909+
```rust
910+
# use core::{num::Wrapping, ops::AddAssign};
911+
#
912+
fn f1(x: (u8,)) {
913+
let mut order: Vec<u64> = vec![];
914+
// The RHS is evaluated first as both operands are of primitive
915+
// type.
916+
{ order.push(2); x }.0 += { order.push(1); x }.0;
917+
assert_eq!((1..=2).into_iter().collect::<Vec<_>>(), order);
918+
}
919+
920+
fn f2(x: (Wrapping<u8>,)) {
921+
let mut order: Vec<u64> = vec![];
922+
// The LHS is evaluated first as `Wrapping<_>` is not a primitive
923+
// type.
924+
{ order.push(1); x }.0 += { order.push(2); (0u8,) }.0;
925+
assert_eq!((1..=2).into_iter().collect::<Vec<_>>(), order);
926+
}
927+
928+
fn f3<T: AddAssign<u8> + Copy>(x: (T,)) {
929+
let mut order: Vec<u64> = vec![];
930+
// The LHS is evaluated first as one of the operands is a generic
931+
// parameter.
932+
{ order.push(1); x }.0 += { order.push(2); (0u8,) }.0;
933+
assert_eq!((1..=2).into_iter().collect::<Vec<_>>(), order);
934+
}
935+
936+
fn main() {
937+
f1((0u8,));
938+
f2((Wrapping(0u8),));
939+
f3::<u8>((0u8,));
940+
}
941+
```
942+
909943
> [!NOTE]
910944
> This is different than other expressions in that the right operand is evaluated before the left one.
911945

0 commit comments

Comments
 (0)