Skip to content

Commit 8974c7e

Browse files
committed
Fix ice caused by wrong type of array size
1 parent a32d4a0 commit 8974c7e

File tree

4 files changed

+47
-10
lines changed

4 files changed

+47
-10
lines changed

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,13 +1402,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14021402
expr: &'tcx hir::Expr<'tcx>,
14031403
) -> Ty<'tcx> {
14041404
let element_ty = if !args.is_empty() {
1405+
let mut size_ct = None;
14051406
let coerce_to = expected
14061407
.to_option(self)
14071408
.and_then(|uty| match *uty.kind() {
1408-
ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
1409+
ty::Array(ty, sz_ct) => {
1410+
size_ct = Some(sz_ct);
1411+
Some(ty)
1412+
}
1413+
ty::Slice(ty) => Some(ty),
14091414
_ => None,
14101415
})
14111416
.unwrap_or_else(|| self.next_ty_var(expr.span));
1417+
1418+
// Check if the expected type of array size is something
1419+
// other than `usize` which is clearly wrong. Fixes ICE #126359
1420+
if let Some(size_ct) = size_ct
1421+
&& let ty::ConstKind::Value(size_ty, _) = size_ct.kind()
1422+
&& !matches!(size_ty.kind(), ty::Uint(ty::UintTy::Usize))
1423+
{
1424+
let guar = self.dcx().span_delayed_bug(expr.span, "array size type is not `usize`");
1425+
self.set_tainted_by_errors(guar);
1426+
1427+
return Ty::new_error(self.tcx, guar);
1428+
}
1429+
14121430
let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
14131431
assert_eq!(self.diverges.get(), Diverges::Maybe);
14141432
for e in args {

tests/crashes/126359.rs

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Regression test for ICE #126359
2+
3+
// Tests that there is no ICE when the generic const
4+
// specifying the size of an array is of a non-usize type
5+
6+
struct OppOrder<const N: u8 = 3, T = u32> {
7+
arr: [T; N],
8+
//~^ ERROR the constant `N` is not of type `usize`
9+
}
10+
11+
fn main() {
12+
let _ = OppOrder::<3, u32> { arr: [0, 0, 0] };
13+
//~^ ERROR the constant `3` is not of type `usize`
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: the constant `N` is not of type `usize`
2+
--> $DIR/ice-const-size-relate-126359.rs:7:10
3+
|
4+
LL | arr: [T; N],
5+
| ^^^^^^ expected `usize`, found `u8`
6+
7+
error: the constant `3` is not of type `usize`
8+
--> $DIR/ice-const-size-relate-126359.rs:12:39
9+
|
10+
LL | let _ = OppOrder::<3, u32> { arr: [0, 0, 0] };
11+
| ^^^^^^^^^ expected `usize`, found `u8`
12+
13+
error: aborting due to 2 previous errors
14+

0 commit comments

Comments
 (0)