From d4f9db048447800c24d07e1815c3e2d2359059c5 Mon Sep 17 00:00:00 2001 From: shulaoda <165626830+shulaoda@users.noreply.github.com> Date: Sat, 20 Jun 2026 08:10:14 +0800 Subject: [PATCH] fix: Don't panic on out-of-range integer literals in const positions --- crates/hir-ty/src/consteval.rs | 16 ++++++++++++---- crates/hir-ty/src/tests/regression/new_solver.rs | 10 ++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index d6580d3752f6..a880ae5353b6 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -87,18 +87,24 @@ fn intern_const_ref<'db>( let valtree = match (ty.kind(), value) { (TyKind::Uint(uint), Literal::Uint(value, _)) => { let size = uint.bit_width().map(Size::from_bits).unwrap_or(data_layout.pointer_size()); - let scalar = ScalarInt::try_from_uint(*value, size).unwrap(); + let Some(scalar) = ScalarInt::try_from_uint(*value, size) else { + return Ok(Const::error(interner)); + }; ValTreeKind::Leaf(scalar) } (TyKind::Uint(uint), Literal::Int(value, _)) => { // `Literal::Int` is the default, so we also need to account for the type being uint. let size = uint.bit_width().map(Size::from_bits).unwrap_or(data_layout.pointer_size()); - let scalar = ScalarInt::try_from_uint(*value as u128, size).unwrap(); + let Some(scalar) = ScalarInt::try_from_uint(*value as u128, size) else { + return Ok(Const::error(interner)); + }; ValTreeKind::Leaf(scalar) } (TyKind::Int(int), Literal::Int(value, _)) => { let size = int.bit_width().map(Size::from_bits).unwrap_or(data_layout.pointer_size()); - let scalar = ScalarInt::try_from_int(*value, size).unwrap(); + let Some(scalar) = ScalarInt::try_from_int(*value, size) else { + return Ok(Const::error(interner)); + }; ValTreeKind::Leaf(scalar) } (TyKind::Bool, Literal::Bool(value)) => ValTreeKind::Leaf(ScalarInt::from(*value)), @@ -219,7 +225,9 @@ pub fn usize_const<'db>(db: &'db dyn HirDatabase, value: Option, krate: Cr return Const::error(interner); }; let usize_ty = interner.default_types().types.usize; - let scalar = ScalarInt::try_from_uint(value, data_layout.pointer_size()).unwrap(); + let Some(scalar) = ScalarInt::try_from_uint(value, data_layout.pointer_size()) else { + return Const::error(interner); + }; Const::new_valtree(interner, usize_ty, ValTreeKind::Leaf(scalar)) } diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs index 17127b2771d2..fb00a755fa05 100644 --- a/crates/hir-ty/src/tests/regression/new_solver.rs +++ b/crates/hir-ty/src/tests/regression/new_solver.rs @@ -404,6 +404,16 @@ const A: [u8; S] = [0; 8]; ); } +#[test] +fn oversized_array_len_does_not_panic() { + // The array length literal does not fit in `usize`; interning it must not panic. + check_no_mismatches( + r#" +fn f(_: [u8; 18446744073709551616]) {} + "#, + ); +} + #[test] fn another_20654_case() { check_no_mismatches(