// Test evaluation order of assignment expressions is right to left. // run-pass // We would previously not finish evaluating borrow and FRU expressions before // starting on the LHS struct S(i32); fn evaluate_reborrow_before_assign() { let mut x = &1; let y = &mut &2; let z = &3; // There's an implicit reborrow of `x` on the right-hand side of the // assignment. Note that writing an explicit reborrow would not show this // bug, as now there would be two reborrows on the right-hand side and at // least one of them would happen before the left-hand side is evaluated. *{ x = z; &mut *y } = x; assert_eq!(*x, 3); assert_eq!(**y, 1); // y should be assigned the original value of `x`. } fn evaluate_mut_reborrow_before_assign() { let mut x = &mut 1; let y = &mut &mut 2; let z = &mut 3; *{ x = z; &mut *y } = x; assert_eq!(*x, 3); assert_eq!(**y, 1); // y should be assigned the original value of `x`. } // We should evaluate `x[2]` and borrow the value out *before* evaluating the // LHS and changing its value. fn evaluate_ref_to_temp_before_assign_slice() { let mut x = &[S(0), S(1), S(2)][..]; let y = &mut &S(7); *{ x = &[S(3), S(4), S(5)]; &mut *y } = &x[2]; assert_eq!(2, y.0); assert_eq!(5, x[2].0); } // We should evaluate `x[2]` and copy the value out *before* evaluating the LHS // and changing its value. fn evaluate_fru_to_temp_before_assign_slice() { let mut x = &[S(0), S(1), S(2)][..]; let y = &mut S(7); *{ x = &[S(3), S(4), S(5)]; &mut *y } = S { ..x[2] }; assert_eq!(2, y.0); assert_eq!(5, x[2].0); } // We should evaluate `*x` and copy the value out *before* evaluating the LHS // and dropping `x`. fn evaluate_fru_to_temp_before_assign_box() { let x = Box::new(S(0)); let y = &mut S(1); *{ drop(x); &mut *y } = S { ..*x }; assert_eq!(0, y.0); } fn main() { evaluate_reborrow_before_assign(); evaluate_mut_reborrow_before_assign(); evaluate_ref_to_temp_before_assign_slice(); evaluate_fru_to_temp_before_assign_slice(); evaluate_fru_to_temp_before_assign_box(); }