@@ -1360,8 +1360,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1360
1360
let min = before. len ( ) as u64 + after. len ( ) as u64 ;
1361
1361
let ( opt_slice_ty, expected) =
1362
1362
self . check_array_pat_len ( span, element_ty, expected, slice, len, min) ;
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.
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( ) ) ;
1365
1366
( element_ty, opt_slice_ty, expected)
1366
1367
}
1367
1368
ty:: Slice ( element_ty) => ( element_ty, Some ( expected) , expected) ,
@@ -1371,17 +1372,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1371
1372
self . error_expected_array_or_slice ( span, expected) ;
1372
1373
}
1373
1374
let err = self . tcx . types . err ;
1374
- ( err, None , err)
1375
+ ( err, Some ( err ) , err)
1375
1376
}
1376
1377
} ;
1377
1378
1378
1379
// Type check all the patterns before `slice`.
1379
1380
for elt in before {
1380
1381
self . check_pat ( & elt, element_ty, def_bm, ti) ;
1381
1382
}
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 ) {
1384
- self . check_pat ( & slice, slice_ty , def_bm, ti) ;
1383
+ // Type check the `slice`, if present, against its expected type.
1384
+ if let Some ( slice) = slice {
1385
+ self . check_pat ( & slice, opt_slice_ty . unwrap ( ) , def_bm, ti) ;
1385
1386
}
1386
1387
// Type check the elements after `slice`, if present.
1387
1388
for elt in after {
@@ -1393,7 +1394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1393
1394
/// Type check the length of an array pattern.
1394
1395
///
1395
1396
/// Returns both the type of the variable length pattern (or `None`), and the potentially
1396
- /// inferred array type.
1397
+ /// inferred array type. We should only return `None` for the slice type if `slice.is_none()`.
1397
1398
fn check_array_pat_len (
1398
1399
& self ,
1399
1400
span : Span ,
@@ -1409,9 +1410,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1409
1410
// ...and since there is no variable-length pattern,
1410
1411
// we require an exact match between the number of elements
1411
1412
// in the array pattern and as provided by the matched type.
1412
- if min_len ! = len {
1413
- self . error_scrutinee_inconsistent_length ( span , min_len , len ) ;
1413
+ if min_len = = len {
1414
+ return ( None , arr_ty ) ;
1414
1415
}
1416
+
1417
+ self . error_scrutinee_inconsistent_length ( span, min_len, len) ;
1415
1418
} else if let Some ( pat_len) = len. checked_sub ( min_len) {
1416
1419
// The variable-length pattern was there,
1417
1420
// so it has an array type with the remaining elements left as its size...
@@ -1433,7 +1436,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1433
1436
// `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
1434
1437
self . error_scrutinee_unfixed_length ( span) ;
1435
1438
}
1436
- ( None , arr_ty)
1439
+
1440
+ // If we get here, we must have emitted an error.
1441
+ ( Some ( self . tcx . types . err ) , arr_ty)
1437
1442
}
1438
1443
1439
1444
fn error_scrutinee_inconsistent_length ( & self , span : Span , min_len : u64 , size : u64 ) {
0 commit comments