@@ -1353,32 +1353,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1353
1353
def_bm : BindingMode ,
1354
1354
ti : TopInfo < ' tcx > ,
1355
1355
) -> Ty < ' tcx > {
1356
- let err = self . tcx . types . err ;
1357
1356
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 {
1359
1358
// An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
1360
1359
ty:: Array ( element_ty, len) => {
1361
1360
let min = before. len ( ) as u64 + after. len ( ) as u64 ;
1362
- let ( slice_ty , expected) =
1361
+ let ( opt_slice_ty , expected) =
1363
1362
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)
1365
1366
}
1366
- ty:: Slice ( element_ty) => ( element_ty, expected, expected) ,
1367
+ ty:: Slice ( element_ty) => ( element_ty, Some ( expected) , expected) ,
1367
1368
// The expected type must be an array or slice, but was neither, so error.
1368
1369
_ => {
1369
1370
if !expected. references_error ( ) {
1370
1371
self . error_expected_array_or_slice ( span, expected) ;
1371
1372
}
1372
- ( err, err, err)
1373
+ let err = self . tcx . types . err ;
1374
+ ( err, None , err)
1373
1375
}
1374
1376
} ;
1375
1377
1376
1378
// Type check all the patterns before `slice`.
1377
1379
for elt in before {
1378
1380
self . check_pat ( & elt, element_ty, def_bm, ti) ;
1379
1381
}
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 ) {
1382
1384
self . check_pat ( & slice, slice_ty, def_bm, ti) ;
1383
1385
}
1384
1386
// Type check the elements after `slice`, if present.
@@ -1390,9 +1392,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1390
1392
1391
1393
/// Type check the length of an array pattern.
1392
1394
///
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.
1396
1397
fn check_array_pat_len (
1397
1398
& self ,
1398
1399
span : Span ,
@@ -1401,7 +1402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1401
1402
slice : Option < & ' tcx Pat < ' tcx > > ,
1402
1403
len : & ty:: Const < ' tcx > ,
1403
1404
min_len : u64 ,
1404
- ) -> ( Ty < ' tcx > , Ty < ' tcx > ) {
1405
+ ) -> ( Option < Ty < ' tcx > > , Ty < ' tcx > ) {
1405
1406
if let Some ( len) = len. try_eval_usize ( self . tcx , self . param_env ) {
1406
1407
// Now we know the length...
1407
1408
if slice. is_none ( ) {
@@ -1414,7 +1415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1414
1415
} else if let Some ( pat_len) = len. checked_sub ( min_len) {
1415
1416
// The variable-length pattern was there,
1416
1417
// 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) ;
1418
1419
} else {
1419
1420
// ...however, in this case, there were no remaining elements.
1420
1421
// That is, the slice pattern requires more than the array type offers.
@@ -1425,14 +1426,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1425
1426
// which we can use to infer the length of the array.
1426
1427
let updated_arr_ty = self . tcx . mk_array ( element_ty, min_len) ;
1427
1428
self . demand_eqtype ( span, updated_arr_ty, arr_ty) ;
1428
- return ( self . tcx . types . err , updated_arr_ty) ;
1429
+ return ( None , updated_arr_ty) ;
1429
1430
} else {
1430
1431
// We have a variable-length pattern and don't know the array length.
1431
1432
// This happens if we have e.g.,
1432
1433
// `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
1433
1434
self . error_scrutinee_unfixed_length ( span) ;
1434
1435
}
1435
- ( self . tcx . types . err , arr_ty)
1436
+ ( None , arr_ty)
1436
1437
}
1437
1438
1438
1439
fn error_scrutinee_inconsistent_length ( & self , span : Span , min_len : u64 , size : u64 ) {
0 commit comments