68 lines
2.1 KiB
Rust
68 lines
2.1 KiB
Rust
|
// 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
|
||
|
// assignement. 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();
|
||
|
}
|