]> git.lizzy.rs Git - rust.git/blob - src/test/ui/mir/mir_assign_eval_order.rs
Merge commit 'e18101137866b79045fee0ef996e696e68c920b4' into clippyup
[rust.git] / src / test / ui / mir / mir_assign_eval_order.rs
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
15     // assignment. Note that writing an explicit reborrow would not show this
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 }