mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 13:04:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			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
 | |
|     // 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();
 | |
| }
 | 
