@@ -1355,16 +1355,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13551355 ) -> Ty < ' tcx > {
13561356 let err = self . tcx . types . err ;
13571357 let expected = self . structurally_resolved_type ( span, expected) ;
1358- let ( inner_ty , slice_ty, expected) = match expected. kind {
1358+ let ( element_ty , slice_ty, expected) = match expected. kind {
13591359 // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
1360- ty:: Array ( inner_ty , len) => {
1360+ ty:: Array ( element_ty , len) => {
13611361 let min = before. len ( ) as u64 + after. len ( ) as u64 ;
1362- let slice_ty = self
1363- . check_array_pat_len ( span, slice, len, min)
1364- . map_or ( err, |len| self . tcx . mk_array ( inner_ty, len) ) ;
1365- ( inner_ty, slice_ty, expected)
1362+ let ( slice_ty, expected) =
1363+ self . check_array_pat_len ( span, element_ty, expected, slice, len, min) ;
1364+ ( element_ty, slice_ty, expected)
13661365 }
1367- ty:: Slice ( inner_ty ) => ( inner_ty , expected, expected) ,
1366+ ty:: Slice ( element_ty ) => ( element_ty , expected, expected) ,
13681367 // The expected type must be an array or slice, but was neither, so error.
13691368 _ => {
13701369 if !expected. references_error ( ) {
@@ -1376,30 +1375,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13761375
13771376 // Type check all the patterns before `slice`.
13781377 for elt in before {
1379- self . check_pat ( & elt, inner_ty , def_bm, ti) ;
1378+ self . check_pat ( & elt, element_ty , def_bm, ti) ;
13801379 }
13811380 // Type check the `slice`, if present, against its expected type.
13821381 if let Some ( slice) = slice {
13831382 self . check_pat ( & slice, slice_ty, def_bm, ti) ;
13841383 }
13851384 // Type check the elements after `slice`, if present.
13861385 for elt in after {
1387- self . check_pat ( & elt, inner_ty , def_bm, ti) ;
1386+ self . check_pat ( & elt, element_ty , def_bm, ti) ;
13881387 }
13891388 expected
13901389 }
13911390
13921391 /// Type check the length of an array pattern.
13931392 ///
1394- /// Return the length of the variable length pattern,
1395- /// if it exists and there are no errors.
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.
13961396 fn check_array_pat_len (
13971397 & self ,
13981398 span : Span ,
1399+ element_ty : Ty < ' tcx > ,
1400+ arr_ty : Ty < ' tcx > ,
13991401 slice : Option < & ' tcx Pat < ' tcx > > ,
14001402 len : & ty:: Const < ' tcx > ,
14011403 min_len : u64 ,
1402- ) -> Option < u64 > {
1404+ ) -> ( Ty < ' tcx > , Ty < ' tcx > ) {
14031405 if let Some ( len) = len. try_eval_usize ( self . tcx , self . param_env ) {
14041406 // Now we know the length...
14051407 if slice. is_none ( ) {
@@ -1409,21 +1411,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14091411 if min_len != len {
14101412 self . error_scrutinee_inconsistent_length ( span, min_len, len) ;
14111413 }
1412- } else if let r @ Some ( _ ) = len. checked_sub ( min_len) {
1414+ } else if let Some ( pat_len ) = len. checked_sub ( min_len) {
14131415 // The variable-length pattern was there,
14141416 // so it has an array type with the remaining elements left as its size...
1415- return r ;
1417+ return ( self . tcx . mk_array ( element_ty , pat_len ) , arr_ty ) ;
14161418 } else {
14171419 // ...however, in this case, there were no remaining elements.
14181420 // That is, the slice pattern requires more than the array type offers.
14191421 self . error_scrutinee_with_rest_inconsistent_length ( span, min_len, len) ;
14201422 }
1423+ } else if slice. is_none ( ) {
1424+ // We have a pattern with a fixed length,
1425+ // which we can use to infer the length of the array.
1426+ // of the array.
1427+ let updated_arr_ty = self . tcx . mk_array ( element_ty, min_len) ;
1428+ self . demand_eqtype ( span, updated_arr_ty, arr_ty) ;
1429+ return ( self . tcx . types . err , updated_arr_ty) ;
14211430 } else {
1422- // No idea what the length is, which happens if we have e.g.,
1423- // `let [a, b] = arr` where `arr: [T; N]` where `const N: usize`.
1431+ // We have a variable-length pattern and don't know the array length.
1432+ // This happens if we have e.g.,
1433+ // `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
14241434 self . error_scrutinee_unfixed_length ( span) ;
14251435 }
1426- None
1436+ ( self . tcx . types . err , arr_ty )
14271437 }
14281438
14291439 fn error_scrutinee_inconsistent_length ( & self , span : Span , min_len : u64 , size : u64 ) {
0 commit comments