Skip to content

Commit e1c838d

Browse files
committed
de-abuse TyKind::Error: ice on missing slice type
1 parent f9a691f commit e1c838d

File tree

1 file changed

+15
-10
lines changed
  • src/librustc_typeck/check

1 file changed

+15
-10
lines changed

src/librustc_typeck/check/pat.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -1360,8 +1360,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13601360
let min = before.len() as u64 + after.len() as u64;
13611361
let (opt_slice_ty, expected) =
13621362
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());
13651366
(element_ty, opt_slice_ty, expected)
13661367
}
13671368
ty::Slice(element_ty) => (element_ty, Some(expected), expected),
@@ -1371,17 +1372,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13711372
self.error_expected_array_or_slice(span, expected);
13721373
}
13731374
let err = self.tcx.types.err;
1374-
(err, None, err)
1375+
(err, Some(err), err)
13751376
}
13761377
};
13771378

13781379
// Type check all the patterns before `slice`.
13791380
for elt in before {
13801381
self.check_pat(&elt, element_ty, def_bm, ti);
13811382
}
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);
13851386
}
13861387
// Type check the elements after `slice`, if present.
13871388
for elt in after {
@@ -1393,7 +1394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13931394
/// Type check the length of an array pattern.
13941395
///
13951396
/// 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()`.
13971398
fn check_array_pat_len(
13981399
&self,
13991400
span: Span,
@@ -1409,9 +1410,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14091410
// ...and since there is no variable-length pattern,
14101411
// we require an exact match between the number of elements
14111412
// 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);
14141415
}
1416+
1417+
self.error_scrutinee_inconsistent_length(span, min_len, len);
14151418
} else if let Some(pat_len) = len.checked_sub(min_len) {
14161419
// The variable-length pattern was there,
14171420
// so it has an array type with the remaining elements left as its size...
@@ -1433,7 +1436,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14331436
// `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
14341437
self.error_scrutinee_unfixed_length(span);
14351438
}
1436-
(None, arr_ty)
1439+
1440+
// If we get here, we must have emitted an error.
1441+
(Some(self.tcx.types.err), arr_ty)
14371442
}
14381443

14391444
fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {

0 commit comments

Comments
 (0)