@@ -1353,32 +1353,34 @@ 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+ // we can get opt_slice_ty == None in cases that are not an error, e.g. if the
1364+ // slice covers 0 elements or if slice is None.
1365+ ( element_ty, opt_slice_ty, expected)
13651366 }
1366- ty:: Slice ( element_ty) => ( element_ty, expected, expected) ,
1367+ ty:: Slice ( element_ty) => ( element_ty, Some ( expected) , expected) ,
13671368 // The expected type must be an array or slice, but was neither, so error.
13681369 _ => {
13691370 if !expected. references_error ( ) {
13701371 self . error_expected_array_or_slice ( span, expected) ;
13711372 }
1372- ( err, err, err)
1373+ let err = self . tcx . types . err ;
1374+ ( err, None , err)
13731375 }
13741376 } ;
13751377
13761378 // Type check all the patterns before `slice`.
13771379 for elt in before {
13781380 self . check_pat ( & elt, element_ty, def_bm, ti) ;
13791381 }
1380- // Type check the `slice`, if present, against its expected type.
1381- if let Some ( slice) = slice {
1382+ // Type check the `slice`, if present, against its expected type, if there is one .
1383+ if let ( Some ( slice) , Some ( slice_ty ) ) = ( slice, opt_slice_ty ) {
13821384 self . check_pat ( & slice, slice_ty, def_bm, ti) ;
13831385 }
13841386 // Type check the elements after `slice`, if present.
@@ -1390,9 +1392,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13901392
13911393 /// Type check the length of an array pattern.
13921394 ///
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.
1395+ /// Returns both the type of the variable length pattern (or `None`), and the potentially
1396+ /// inferred array type.
13961397 fn check_array_pat_len (
13971398 & self ,
13981399 span : Span ,
@@ -1401,7 +1402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14011402 slice : Option < & ' tcx Pat < ' tcx > > ,
14021403 len : & ty:: Const < ' tcx > ,
14031404 min_len : u64 ,
1404- ) -> ( Ty < ' tcx > , Ty < ' tcx > ) {
1405+ ) -> ( Option < Ty < ' tcx > > , Ty < ' tcx > ) {
14051406 if let Some ( len) = len. try_eval_usize ( self . tcx , self . param_env ) {
14061407 // Now we know the length...
14071408 if slice. is_none ( ) {
@@ -1414,7 +1415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14141415 } else if let Some ( pat_len) = len. checked_sub ( min_len) {
14151416 // The variable-length pattern was there,
14161417 // 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) ;
1418+ return ( Some ( self . tcx . mk_array ( element_ty, pat_len) ) , arr_ty) ;
14181419 } else {
14191420 // ...however, in this case, there were no remaining elements.
14201421 // That is, the slice pattern requires more than the array type offers.
@@ -1425,14 +1426,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14251426 // which we can use to infer the length of the array.
14261427 let updated_arr_ty = self . tcx . mk_array ( element_ty, min_len) ;
14271428 self . demand_eqtype ( span, updated_arr_ty, arr_ty) ;
1428- return ( self . tcx . types . err , updated_arr_ty) ;
1429+ return ( None , updated_arr_ty) ;
14291430 } else {
14301431 // We have a variable-length pattern and don't know the array length.
14311432 // This happens if we have e.g.,
14321433 // `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
14331434 self . error_scrutinee_unfixed_length ( span) ;
14341435 }
1435- ( self . tcx . types . err , arr_ty)
1436+ ( None , arr_ty)
14361437 }
14371438
14381439 fn error_scrutinee_inconsistent_length ( & self , span : Span , min_len : u64 , size : u64 ) {
0 commit comments