mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-30 20:44:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			121 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| fn main() {
 | |
|     struct S; // Not `Copy`.
 | |
| 
 | |
|     let mut tup0 = (S, S);
 | |
|     let mut tup1 = (S, S, S);
 | |
|     let tup2 = (S, S);
 | |
|     let tup3 = (S, S, S);
 | |
|     let tup4 = (S, S);
 | |
|     let mut arr0 = [S, S, S];
 | |
|     let mut arr1 = [S, S, S, S, S];
 | |
|     let arr2 = [S, S, S];
 | |
|     let arr3 = [S, S, S, S, S];
 | |
| 
 | |
|     // The `mov` bindings require that we capture the scrutinees by-move.
 | |
|     let mut closure = || {
 | |
|         // Tuples...
 | |
|         let (ref mut borrow, mov) = tup0;
 | |
|         let (mov, _, ref mut borrow) = tup1;
 | |
|         let (ref borrow, mov) = tup2;
 | |
|         let (mov, _, ref borrow) = tup3;
 | |
|         let (ref borrow, mov) = tup4;
 | |
|         // Arrays...
 | |
|         let [mov @ .., ref borrow] = arr0;
 | |
|         let [_, ref mut borrow @ .., _, mov] = arr1;
 | |
|         let [mov @ .., ref borrow] = arr2;
 | |
|         let [_, ref borrow @ .., _, mov] = arr3;
 | |
|     };
 | |
| 
 | |
|     // Now we try to borrow and move the captures, which should result in errors...
 | |
|     // ...for tuples:
 | |
|     drop(&tup0); //~ ERROR borrow of moved value: `tup0`
 | |
|     drop(&tup1); //~ ERROR borrow of moved value: `tup1`
 | |
|     drop(&tup2); //~ ERROR borrow of moved value: `tup2`
 | |
|     drop(&tup3); //~ ERROR borrow of moved value: `tup3`
 | |
|     // Ostensibly this should compile.
 | |
|     // However, because closures don't capture individual fields, which is changed in RFC 2229,
 | |
|     // this won't compile because the entire product is moved into the closure.
 | |
|     // The same applies to the array patterns below.
 | |
|     drop(&tup4.0); //~ ERROR borrow of moved value: `tup4`
 | |
|     // ...for arrays:
 | |
|     drop(&arr0); //~ ERROR borrow of moved value: `arr0`
 | |
|     let [_, mov1, mov2, mov3, _] = &arr1; //~ ERROR borrow of moved value: `arr1`
 | |
|     drop(&arr2); //~ ERROR borrow of moved value: `arr2`
 | |
|     let [_, mov1, mov2, mov3, _] = &arr3; //~ ERROR borrow of moved value: `arr3`
 | |
| 
 | |
|     // Let's redo ^--- with a `match` + sum type:
 | |
|     macro_rules! m {
 | |
|         ($p:pat = $s:expr) => {
 | |
|             match $s {
 | |
|                 Some($p) => {}
 | |
|                 _ => {}
 | |
|             }
 | |
|         };
 | |
|     }
 | |
|     let mut tup0: Option<(S, S)> = None;
 | |
|     let mut tup1: Option<(S, S, S)> = None;
 | |
|     let tup2: Option<(S, S)> = None;
 | |
|     let tup3: Option<(S, S, S)> = None;
 | |
|     let tup4: Option<(S, S)> = None;
 | |
|     let mut arr0: Option<[S; 3]> = None;
 | |
|     let mut arr1: Option<[S; 5]> = None;
 | |
|     let arr2: Option<[S; 3]> = None;
 | |
|     let arr3: Option<[S; 5]> = None;
 | |
|     let mut closure = || {
 | |
|         m!((ref mut borrow, mov) = tup0);
 | |
|         m!((mov, _, ref mut borrow) = tup1);
 | |
|         m!((ref borrow, mov) = tup2);
 | |
|         m!((mov, _, ref borrow) = tup3);
 | |
|         m!((ref borrow, mov) = tup4);
 | |
|         m!([mov @ .., ref borrow] = arr0);
 | |
|         m!([_, ref mut borrow @ .., _, mov] = arr1);
 | |
|         m!([mov @ .., ref borrow] = arr2);
 | |
|         m!([_, ref borrow @ .., _, mov] = arr3);
 | |
|     };
 | |
|     drop(&tup0); //~ ERROR borrow of moved value: `tup0`
 | |
|     drop(&tup1); //~ ERROR borrow of moved value: `tup1`
 | |
|     drop(&tup2); //~ ERROR borrow of moved value: `tup2`
 | |
|     drop(&tup3); //~ ERROR borrow of moved value: `tup3`
 | |
|     m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4`
 | |
|     drop(&arr0); //~ ERROR borrow of moved value: `arr0`
 | |
|     m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1`
 | |
|     drop(&arr2); //~ ERROR borrow of moved value: `arr2`
 | |
|     m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3`
 | |
| 
 | |
|     // Let's redo ^--- with `if let` (which may diverge from `match` in the future):
 | |
|     macro_rules! m {
 | |
|         ($p:pat = $s:expr) => {
 | |
|             if let Some($p) = $s {}
 | |
|         };
 | |
|     }
 | |
|     let mut tup0: Option<(S, S)> = None;
 | |
|     let mut tup1: Option<(S, S, S)> = None;
 | |
|     let tup2: Option<(S, S)> = None;
 | |
|     let tup3: Option<(S, S, S)> = None;
 | |
|     let tup4: Option<(S, S)> = None;
 | |
|     let mut arr0: Option<[S; 3]> = None;
 | |
|     let mut arr1: Option<[S; 5]> = None;
 | |
|     let arr2: Option<[S; 3]> = None;
 | |
|     let arr3: Option<[S; 5]> = None;
 | |
|     let mut closure = || {
 | |
|         m!((ref mut borrow, mov) = tup0);
 | |
|         m!((mov, _, ref mut borrow) = tup1);
 | |
|         m!((ref borrow, mov) = tup2);
 | |
|         m!((mov, _, ref borrow) = tup3);
 | |
|         m!((ref borrow, mov) = tup4);
 | |
|         m!([mov @ .., ref borrow] = arr0);
 | |
|         m!([_, ref mut borrow @ .., _, mov] = arr1);
 | |
|         m!([mov @ .., ref borrow] = arr2);
 | |
|         m!([_, ref borrow @ .., _, mov] = arr3);
 | |
|     };
 | |
|     drop(&tup0); //~ ERROR borrow of moved value: `tup0`
 | |
|     drop(&tup1); //~ ERROR borrow of moved value: `tup1`
 | |
|     drop(&tup2); //~ ERROR borrow of moved value: `tup2`
 | |
|     drop(&tup3); //~ ERROR borrow of moved value: `tup3`
 | |
|     m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4`
 | |
|     drop(&arr0); //~ ERROR borrow of moved value: `arr0`
 | |
|     m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1`
 | |
|     drop(&arr2); //~ ERROR borrow of moved value: `arr2`
 | |
|     m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3`
 | |
| }
 | 
