From 8974c7e8c714fb15d711af7af38bebc763c840f9 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Sat, 24 Aug 2024 15:15:07 +0530 Subject: [PATCH] Fix ice caused by wrong type of array size --- compiler/rustc_hir_typeck/src/expr.rs | 20 ++++++++++++++++++- tests/crashes/126359.rs | 9 --------- .../ui/consts/ice-const-size-relate-126359.rs | 14 +++++++++++++ .../ice-const-size-relate-126359.stderr | 14 +++++++++++++ 4 files changed, 47 insertions(+), 10 deletions(-) delete mode 100644 tests/crashes/126359.rs create mode 100644 tests/ui/consts/ice-const-size-relate-126359.rs create mode 100644 tests/ui/consts/ice-const-size-relate-126359.stderr diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index fec6efdc0f71b..9c9e09ac209be 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1402,13 +1402,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let element_ty = if !args.is_empty() { + let mut size_ct = None; let coerce_to = expected .to_option(self) .and_then(|uty| match *uty.kind() { - ty::Array(ty, _) | ty::Slice(ty) => Some(ty), + ty::Array(ty, sz_ct) => { + size_ct = Some(sz_ct); + Some(ty) + } + ty::Slice(ty) => Some(ty), _ => None, }) .unwrap_or_else(|| self.next_ty_var(expr.span)); + + // Check if the expected type of array size is something + // other than `usize` which is clearly wrong. Fixes ICE #126359 + if let Some(size_ct) = size_ct + && let ty::ConstKind::Value(size_ty, _) = size_ct.kind() + && !matches!(size_ty.kind(), ty::Uint(ty::UintTy::Usize)) + { + let guar = self.dcx().span_delayed_bug(expr.span, "array size type is not `usize`"); + self.set_tainted_by_errors(guar); + + return Ty::new_error(self.tcx, guar); + } + let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args); assert_eq!(self.diverges.get(), Diverges::Maybe); for e in args { diff --git a/tests/crashes/126359.rs b/tests/crashes/126359.rs deleted file mode 100644 index 4b28c466b55c3..0000000000000 --- a/tests/crashes/126359.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: rust-lang/rust#126359 - -struct OppOrder { - arr: [T; N], -} - -fn main() { - let _ = OppOrder::<3, u32> { arr: [0, 0, 0] }; -} diff --git a/tests/ui/consts/ice-const-size-relate-126359.rs b/tests/ui/consts/ice-const-size-relate-126359.rs new file mode 100644 index 0000000000000..0306f1c9cd9e2 --- /dev/null +++ b/tests/ui/consts/ice-const-size-relate-126359.rs @@ -0,0 +1,14 @@ +// Regression test for ICE #126359 + +// Tests that there is no ICE when the generic const +// specifying the size of an array is of a non-usize type + +struct OppOrder { + arr: [T; N], + //~^ ERROR the constant `N` is not of type `usize` +} + +fn main() { + let _ = OppOrder::<3, u32> { arr: [0, 0, 0] }; + //~^ ERROR the constant `3` is not of type `usize` +} diff --git a/tests/ui/consts/ice-const-size-relate-126359.stderr b/tests/ui/consts/ice-const-size-relate-126359.stderr new file mode 100644 index 0000000000000..da3178c9a80ad --- /dev/null +++ b/tests/ui/consts/ice-const-size-relate-126359.stderr @@ -0,0 +1,14 @@ +error: the constant `N` is not of type `usize` + --> $DIR/ice-const-size-relate-126359.rs:7:10 + | +LL | arr: [T; N], + | ^^^^^^ expected `usize`, found `u8` + +error: the constant `3` is not of type `usize` + --> $DIR/ice-const-size-relate-126359.rs:12:39 + | +LL | let _ = OppOrder::<3, u32> { arr: [0, 0, 0] }; + | ^^^^^^^^^ expected `usize`, found `u8` + +error: aborting due to 2 previous errors +