| 
 | 1 | +// This test is ensuring that type ascriptions on let bindings  | 
 | 2 | +// constrain both:  | 
 | 3 | +//  | 
 | 4 | +// 1. the input expression on the right-hand side (after any potential  | 
 | 5 | +//    coercion, and allowing for covariance), *and*  | 
 | 6 | +//  | 
 | 7 | +// 2. the bindings (if any) nested within the pattern on the left-hand  | 
 | 8 | +//    side (and here, the type-constraint is *invariant*).  | 
 | 9 | + | 
 | 10 | +#![feature(nll)]  | 
 | 11 | + | 
 | 12 | +#![allow(dead_code, unused_mut)]  | 
 | 13 | +type PairUncoupled<'a, 'b, T> = (&'a T, &'b T);  | 
 | 14 | +type PairCoupledRegions<'a, T> = (&'a T, &'a T);  | 
 | 15 | +type PairCoupledTypes<T> = (T, T);  | 
 | 16 | + | 
 | 17 | +fn uncoupled_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {  | 
 | 18 | +    let ((mut y, mut _z),): (PairUncoupled<u32>,) = ((s, &_x),); // ok  | 
 | 19 | +    // Above compiling does *not* imply below would compile.  | 
 | 20 | +    // ::std::mem::swap(&mut y, &mut _z);  | 
 | 21 | +    y  | 
 | 22 | +}  | 
 | 23 | + | 
 | 24 | +fn swap_regions((mut y, mut _z): PairCoupledRegions<u32>) {  | 
 | 25 | +    ::std::mem::swap(&mut y, &mut _z);  | 
 | 26 | +}  | 
 | 27 | + | 
 | 28 | +fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {  | 
 | 29 | +    let ((y, _z),): (PairCoupledRegions<u32>,) = ((s, &_x),);  | 
 | 30 | +    // If above line compiled, so should line below ...  | 
 | 31 | + | 
 | 32 | +    // swap_regions((y, _z));  | 
 | 33 | + | 
 | 34 | +    // ... but the ascribed type also invalidates this use of `y`  | 
 | 35 | +    y //~ ERROR lifetime may not live long enough  | 
 | 36 | +}  | 
 | 37 | + | 
 | 38 | +fn swap_types((mut y, mut _z): PairCoupledTypes<&u32>) {  | 
 | 39 | +    ::std::mem::swap(&mut y, &mut _z);  | 
 | 40 | +}  | 
 | 41 | + | 
 | 42 | +fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {  | 
 | 43 | +    let ((y, _z),): (PairCoupledTypes<&u32>,) = ((s, &_x),);  | 
 | 44 | +    // If above line compiled, so should line below ...  | 
 | 45 | + | 
 | 46 | +    // swap_types((y, _z));  | 
 | 47 | + | 
 | 48 | +    // ... but the ascribed type also invalidates this use of `y`  | 
 | 49 | +    y //~ ERROR lifetime may not live long enough  | 
 | 50 | +}  | 
 | 51 | + | 
 | 52 | +fn swap_wilds((mut y, mut _z): PairCoupledTypes<&u32>) {  | 
 | 53 | +    ::std::mem::swap(&mut y, &mut _z);  | 
 | 54 | +}  | 
 | 55 | + | 
 | 56 | +fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {  | 
 | 57 | +    let ((y, _z),): (PairCoupledTypes<_>,) = ((s, &_x),);  | 
 | 58 | +    // If above line compiled, so should line below  | 
 | 59 | +    // swap_wilds((y, _z));  | 
 | 60 | + | 
 | 61 | +    // ... but the ascribed type also invalidates this use of `y`  | 
 | 62 | +    y //~ ERROR lifetime may not live long enough  | 
 | 63 | +}  | 
 | 64 | + | 
 | 65 | +fn main() {  | 
 | 66 | +    uncoupled_lhs(&3, &4);  | 
 | 67 | +    coupled_regions_lhs(&3, &4);  | 
 | 68 | +    coupled_types_lhs(&3, &4);  | 
 | 69 | +    coupled_wilds_lhs(&3, &4);  | 
 | 70 | +}  | 
0 commit comments