@@ -1353,23 +1353,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13531353        def_bm :  BindingMode , 
13541354        ti :  TopInfo < ' tcx > , 
13551355    )  -> Ty < ' tcx >  { 
1356-         let  err = self . tcx . types . err ; 
13571356        let  expected = self . structurally_resolved_type ( span,  expected) ; 
1358-         let  ( element_ty,  slice_ty ,  inferred)  = match  expected. kind  { 
1357+         let  ( element_ty,  opt_slice_ty ,  inferred)  = match  expected. kind  { 
13591358            // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`. 
13601359            ty:: Array ( element_ty,  len)  => { 
13611360                let  min = before. len ( )  as  u64  + after. len ( )  as  u64 ; 
1362-                 let  ( slice_ty ,  expected)  =
1361+                 let  ( opt_slice_ty ,  expected)  =
13631362                    self . check_array_pat_len ( span,  element_ty,  expected,  slice,  len,  min) ; 
1364-                 ( element_ty,  slice_ty,  expected) 
1363+                 // `opt_slice_ty.is_none()` => `slice.is_none()`. 
1364+                 // Note, though, that opt_slice_ty could be `Some(error_ty)`. 
1365+                 assert ! ( opt_slice_ty. is_some( )  || slice. is_none( ) ) ; 
1366+                 ( element_ty,  opt_slice_ty,  expected) 
13651367            } 
1366-             ty:: Slice ( element_ty)  => ( element_ty,  expected,  expected) , 
1368+             ty:: Slice ( element_ty)  => ( element_ty,  Some ( expected) ,  expected) , 
13671369            // The expected type must be an array or slice, but was neither, so error. 
13681370            _ => { 
13691371                if  !expected. references_error ( )  { 
13701372                    self . error_expected_array_or_slice ( span,  expected) ; 
13711373                } 
1372-                 ( err,  err,  err) 
1374+                 let  err = self . tcx . types . err ; 
1375+                 ( err,  Some ( err) ,  err) 
13731376            } 
13741377        } ; 
13751378
@@ -1379,7 +1382,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13791382        } 
13801383        // Type check the `slice`, if present, against its expected type. 
13811384        if  let  Some ( slice)  = slice { 
1382-             self . check_pat ( & slice,  slice_ty ,  def_bm,  ti) ; 
1385+             self . check_pat ( & slice,  opt_slice_ty . unwrap ( ) ,  def_bm,  ti) ; 
13831386        } 
13841387        // Type check the elements after `slice`, if present. 
13851388        for  elt in  after { 
@@ -1390,9 +1393,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13901393
13911394    /// Type check the length of an array pattern. 
13921395     /// 
1393-      /// Returns both the type of the variable length pattern 
1394-      /// (or `tcx.err` in case there is none), 
1395-      /// and the potentially inferred array type. 
1396+      /// Returns both the type of the variable length pattern (or `None`), and the potentially 
1397+      /// inferred array type. We only return `None` for the slice type if `slice.is_none()`. 
13961398     fn  check_array_pat_len ( 
13971399        & self , 
13981400        span :  Span , 
@@ -1401,20 +1403,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14011403        slice :  Option < & ' tcx  Pat < ' tcx > > , 
14021404        len :  & ty:: Const < ' tcx > , 
14031405        min_len :  u64 , 
1404-     )  -> ( Ty < ' tcx > ,  Ty < ' tcx > )  { 
1406+     )  -> ( Option < Ty < ' tcx > > ,  Ty < ' tcx > )  { 
14051407        if  let  Some ( len)  = len. try_eval_usize ( self . tcx ,  self . param_env )  { 
14061408            // Now we know the length... 
14071409            if  slice. is_none ( )  { 
14081410                // ...and since there is no variable-length pattern, 
14091411                // we require an exact match between the number of elements 
14101412                // in the array pattern and as provided by the matched type. 
1411-                 if  min_len ! = len { 
1412-                     self . error_scrutinee_inconsistent_length ( span ,  min_len ,  len ) ; 
1413+                 if  min_len = = len { 
1414+                     return   ( None ,  arr_ty ) ; 
14131415                } 
1416+ 
1417+                 self . error_scrutinee_inconsistent_length ( span,  min_len,  len) ; 
14141418            }  else  if  let  Some ( pat_len)  = len. checked_sub ( min_len)  { 
14151419                // The variable-length pattern was there, 
14161420                // so it has an array type with the remaining elements left as its size... 
1417-                 return  ( self . tcx . mk_array ( element_ty,  pat_len) ,  arr_ty) ; 
1421+                 return  ( Some ( self . tcx . mk_array ( element_ty,  pat_len) ) ,  arr_ty) ; 
14181422            }  else  { 
14191423                // ...however, in this case, there were no remaining elements. 
14201424                // That is, the slice pattern requires more than the array type offers. 
@@ -1425,14 +1429,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14251429            // which we can use to infer the length of the array. 
14261430            let  updated_arr_ty = self . tcx . mk_array ( element_ty,  min_len) ; 
14271431            self . demand_eqtype ( span,  updated_arr_ty,  arr_ty) ; 
1428-             return  ( self . tcx . types . err ,  updated_arr_ty) ; 
1432+             return  ( None ,  updated_arr_ty) ; 
14291433        }  else  { 
14301434            // We have a variable-length pattern and don't know the array length. 
14311435            // This happens if we have e.g., 
14321436            // `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`. 
14331437            self . error_scrutinee_unfixed_length ( span) ; 
14341438        } 
1435-         ( self . tcx . types . err ,  arr_ty) 
1439+ 
1440+         // If we get here, we must have emitted an error. 
1441+         ( Some ( self . tcx . types . err ) ,  arr_ty) 
14361442    } 
14371443
14381444    fn  error_scrutinee_inconsistent_length ( & self ,  span :  Span ,  min_len :  u64 ,  size :  u64 )  { 
0 commit comments