1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
// 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();
}
|