]>
Commit | Line | Data |
---|---|---|
60c5eb7d XL |
1 | // Test evaluation order of assignment expressions is right to left. |
2 | ||
3 | // run-pass | |
4 | ||
5 | // We would previously not finish evaluating borrow and FRU expressions before | |
6 | // starting on the LHS | |
7 | ||
8 | struct S(i32); | |
9 | ||
10 | fn evaluate_reborrow_before_assign() { | |
11 | let mut x = &1; | |
12 | let y = &mut &2; | |
13 | let z = &3; | |
14 | // There's an implicit reborrow of `x` on the right-hand side of the | |
74b04a01 | 15 | // assignment. Note that writing an explicit reborrow would not show this |
60c5eb7d XL |
16 | // bug, as now there would be two reborrows on the right-hand side and at |
17 | // least one of them would happen before the left-hand side is evaluated. | |
18 | *{ x = z; &mut *y } = x; | |
19 | assert_eq!(*x, 3); | |
20 | assert_eq!(**y, 1); // y should be assigned the original value of `x`. | |
21 | } | |
22 | ||
23 | fn evaluate_mut_reborrow_before_assign() { | |
24 | let mut x = &mut 1; | |
25 | let y = &mut &mut 2; | |
26 | let z = &mut 3; | |
27 | *{ x = z; &mut *y } = x; | |
28 | assert_eq!(*x, 3); | |
29 | assert_eq!(**y, 1); // y should be assigned the original value of `x`. | |
30 | } | |
31 | ||
32 | // We should evaluate `x[2]` and borrow the value out *before* evaluating the | |
33 | // LHS and changing its value. | |
34 | fn evaluate_ref_to_temp_before_assign_slice() { | |
35 | let mut x = &[S(0), S(1), S(2)][..]; | |
36 | let y = &mut &S(7); | |
37 | *{ x = &[S(3), S(4), S(5)]; &mut *y } = &x[2]; | |
38 | assert_eq!(2, y.0); | |
39 | assert_eq!(5, x[2].0); | |
40 | } | |
41 | ||
42 | // We should evaluate `x[2]` and copy the value out *before* evaluating the LHS | |
43 | // and changing its value. | |
44 | fn evaluate_fru_to_temp_before_assign_slice() { | |
45 | let mut x = &[S(0), S(1), S(2)][..]; | |
46 | let y = &mut S(7); | |
47 | *{ x = &[S(3), S(4), S(5)]; &mut *y } = S { ..x[2] }; | |
48 | assert_eq!(2, y.0); | |
49 | assert_eq!(5, x[2].0); | |
50 | } | |
51 | ||
52 | // We should evaluate `*x` and copy the value out *before* evaluating the LHS | |
53 | // and dropping `x`. | |
54 | fn evaluate_fru_to_temp_before_assign_box() { | |
55 | let x = Box::new(S(0)); | |
56 | let y = &mut S(1); | |
57 | *{ drop(x); &mut *y } = S { ..*x }; | |
58 | assert_eq!(0, y.0); | |
59 | } | |
60 | ||
61 | fn main() { | |
62 | evaluate_reborrow_before_assign(); | |
63 | evaluate_mut_reborrow_before_assign(); | |
64 | evaluate_ref_to_temp_before_assign_slice(); | |
65 | evaluate_fru_to_temp_before_assign_slice(); | |
66 | evaluate_fru_to_temp_before_assign_box(); | |
67 | } |