From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/expr/compound-assignment/eval-order.rs | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/test/ui/expr/compound-assignment/eval-order.rs (limited to 'src/test/ui/expr/compound-assignment/eval-order.rs') diff --git a/src/test/ui/expr/compound-assignment/eval-order.rs b/src/test/ui/expr/compound-assignment/eval-order.rs new file mode 100644 index 000000000..658adae19 --- /dev/null +++ b/src/test/ui/expr/compound-assignment/eval-order.rs @@ -0,0 +1,76 @@ +// Test evaluation order of operands of the compound assignment operators + +// run-pass + +use std::ops::AddAssign; + +enum Side { + Lhs, + Rhs, +} + +// In the following tests, we place our value into a wrapper type so that we +// can do an element access as the outer place expression. If we just had the +// block expression, it'd be a value expression and not compile. +struct Wrapper(T); + +// Evaluation order for `a op= b` where typeof(a) and typeof(b) are primitives +// is first `b` then `a`. +fn primitive_compound() { + let mut side_order = vec![]; + let mut int = Wrapper(0); + + { + side_order.push(Side::Lhs); + int + }.0 += { + side_order.push(Side::Rhs); + 0 + }; + + assert!(matches!(side_order[..], [Side::Rhs, Side::Lhs])); +} + +// Evaluation order for `a op=b` otherwise is first `a` then `b`. +fn generic_compound + Default>() { + let mut side_order = vec![]; + let mut add_assignable: Wrapper = Wrapper(Default::default()); + + { + side_order.push(Side::Lhs); + add_assignable + }.0 += { + side_order.push(Side::Rhs); + Default::default() + }; + + assert!(matches!(side_order[..], [Side::Lhs, Side::Rhs])); +} + +fn custom_compound() { + struct Custom; + + impl AddAssign<()> for Custom { + fn add_assign(&mut self, _: ()) { + // this block purposely left blank + } + } + + let mut side_order = vec![]; + let mut custom = Wrapper(Custom); + + { + side_order.push(Side::Lhs); + custom + }.0 += { + side_order.push(Side::Rhs); + }; + + assert!(matches!(side_order[..], [Side::Lhs, Side::Rhs])); +} + +fn main() { + primitive_compound(); + generic_compound::(); + custom_compound(); +} -- cgit v1.2.3