Skip to content

Commit c613c1e

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

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/expressions/operator-expr.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,47 @@ 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+
trait Equate {}
913+
impl<T> Equate for (T, T) {}
914+
915+
fn f1(x: (u8,)) {
916+
let mut order = vec![];
917+
// The RHS is evaluated first as both operands are of primitive
918+
// type.
919+
{ order.push(2); x }.0 += { order.push(1); x }.0;
920+
assert!(order.is_sorted());
921+
}
922+
923+
fn f2(x: (Wrapping<u8>,)) {
924+
let mut order = vec![];
925+
// The LHS is evaluated first as `Wrapping<_>` is not a primitive
926+
// type.
927+
{ order.push(1); x }.0 += { order.push(2); (0u8,) }.0;
928+
assert!(order.is_sorted());
929+
}
930+
931+
fn f3<T: AddAssign<u8> + Copy>(x: (T,)) where (T, u8): Equate {
932+
let mut order = vec![];
933+
// The LHS is evaluated first as one of the operands is a generic
934+
// parameter, even though that generic parameter can be unified
935+
// with a primitive type due to the where clause bound.
936+
{ order.push(1); x }.0 += { order.push(2); (0u8,) }.0;
937+
assert!(order.is_sorted());
938+
}
939+
940+
fn main() {
941+
f1((0u8,));
942+
f2((Wrapping(0u8),));
943+
// We supply a primitive type as the generic argument, but this
944+
// does not affect the evaluation order in `f3` when
945+
// monomorphized.
946+
f3::<u8>((0u8,));
947+
}
948+
```
949+
909950
> [!NOTE]
910951
> This is different than other expressions in that the right operand is evaluated before the left one.
911952

0 commit comments

Comments
 (0)