diff options
| author | Ralf Jung <post@ralfj.de> | 2024-06-08 16:13:45 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-06-10 13:43:16 +0200 |
| commit | 3c57ea0df79c8ee2ad1ff99881f80ab87b186935 (patch) | |
| tree | 8ae30dd0b4654f65ac8513fc5d141b958813fbf2 /compiler/rustc_const_eval/src | |
| parent | 13423befc40fffe23ccc6dd06868142cff9428fe (diff) | |
| download | rust-3c57ea0df79c8ee2ad1ff99881f80ab87b186935.tar.gz rust-3c57ea0df79c8ee2ad1ff99881f80ab87b186935.zip | |
ScalarInt: size mismatches are a bug, do not delay the panic
Diffstat (limited to 'compiler/rustc_const_eval/src')
7 files changed, 27 insertions, 29 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 5312f1f946f..66993476bef 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -95,10 +95,10 @@ fn const_to_valtree_inner<'tcx>( } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { let val = ecx.read_immediate(place)?; - let val = val.to_scalar(); + let val = val.to_scalar_int().unwrap(); *num_nodes += 1; - Ok(ty::ValTree::Leaf(val.assert_int())) + Ok(ty::ValTree::Leaf(val)) } ty::Pat(base, ..) => { @@ -125,7 +125,7 @@ fn const_to_valtree_inner<'tcx>( let val = val.to_scalar(); // We are in the CTFE machine, so ptr-to-int casts will fail. // This can only be `Ok` if `val` already is an integer. - let Ok(val) = val.try_to_int() else { + let Ok(val) = val.try_to_scalar_int() else { return Err(ValTreeCreationError::NonSupportedType); }; // It's just a ScalarInt! @@ -411,7 +411,7 @@ fn valtree_into_mplace<'tcx>( ty::Adt(def, _) if def.is_enum() => { // First element of valtree corresponds to variant let scalar_int = branches[0].unwrap_leaf(); - let variant_idx = VariantIdx::from_u32(scalar_int.try_to_u32().unwrap()); + let variant_idx = VariantIdx::from_u32(scalar_int.to_u32()); let variant = def.variant(variant_idx); debug!(?variant); diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 67fbf9642bf..0dbee8c1d94 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -123,14 +123,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // (`tag_bits` itself is only used for error messages below.) let tag_bits = tag_val .to_scalar() - .try_to_int() + .try_to_scalar_int() .map_err(|dbg_val| err_ub!(InvalidTag(dbg_val)))? - .assert_bits(tag_layout.size); + .to_bits(tag_layout.size); // Cast bits from tag layout to discriminant layout. // After the checks we did above, this cannot fail, as // discriminants are int-like. let discr_val = self.int_to_int_or_float(&tag_val, discr_layout).unwrap(); - let discr_bits = discr_val.to_scalar().assert_bits(discr_layout.size); + let discr_bits = discr_val.to_scalar().to_bits(discr_layout.size)?; // Convert discriminant to variant index, and catch invalid discriminants. let index = match *ty.kind() { ty::Adt(adt, _) => { @@ -152,7 +152,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // discriminant (encoded in niche/tag) and variant index are the same. let variants_start = niche_variants.start().as_u32(); let variants_end = niche_variants.end().as_u32(); - let variant = match tag_val.try_to_int() { + let variant = match tag_val.try_to_scalar_int() { Err(dbg_val) => { // So this is a pointer then, and casting to an int failed. // Can only happen during CTFE. @@ -167,7 +167,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { untagged_variant } Ok(tag_bits) => { - let tag_bits = tag_bits.assert_bits(tag_layout.size); + let tag_bits = tag_bits.to_bits(tag_layout.size); // We need to use machine arithmetic to get the relative variant idx: // variant_index_relative = tag_val - niche_start_val let tag_val = ImmTy::from_uint(tag_bits, tag_layout); @@ -175,7 +175,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let variant_index_relative_val = self.binary_op(mir::BinOp::Sub, &tag_val, &niche_start_val)?; let variant_index_relative = - variant_index_relative_val.to_scalar().assert_bits(tag_val.layout.size); + variant_index_relative_val.to_scalar().to_bits(tag_val.layout.size)?; // Check if this is in the range that indicates an actual discriminant. if variant_index_relative <= u128::from(variants_end - variants_start) { let variant_index_relative = u32::try_from(variant_index_relative) @@ -294,8 +294,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ImmTy::from_uint(variant_index_relative, tag_layout); let tag = self .binary_op(mir::BinOp::Add, &variant_index_relative_val, &niche_start_val)? - .to_scalar() - .assert_int(); + .to_scalar_int()?; Ok(Some((tag, tag_field))) } } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 18b76443cd9..dac5c10addc 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -519,7 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`. // First, check x % y != 0 (or if that computation overflows). let rem = self.binary_op(BinOp::Rem, a, b)?; - if rem.to_scalar().assert_bits(a.layout.size) != 0 { + if rem.to_scalar().to_bits(a.layout.size)? != 0 { throw_ub_custom!( fluent::const_eval_exact_div_has_remainder, a = format!("{a}"), diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 521f28b7123..7eb73e9b52f 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1344,7 +1344,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Test if this value might be null. /// If the machine does not support ptr-to-int casts, this is conservative. pub fn scalar_may_be_null(&self, scalar: Scalar<M::Provenance>) -> InterpResult<'tcx, bool> { - Ok(match scalar.try_to_int() { + Ok(match scalar.try_to_scalar_int() { Ok(int) => int.is_null(), Err(_) => { // Can only happen during CTFE. diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index bbb2c2f3938..0a7e9853763 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -89,6 +89,12 @@ impl<Prov: Provenance> Immediate<Prov> { #[inline] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) + pub fn to_scalar_int(self) -> ScalarInt { + self.to_scalar().try_to_scalar_int().unwrap() + } + + #[inline] + #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn to_scalar_pair(self) -> (Scalar<Prov>, Scalar<Prov>) { match self { Immediate::ScalarPair(val1, val2) => (val1, val2), @@ -220,19 +226,11 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { } #[inline] - pub fn try_from_uint(i: impl Into<u128>, layout: TyAndLayout<'tcx>) -> Option<Self> { - Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) - } - #[inline] pub fn from_uint(i: impl Into<u128>, layout: TyAndLayout<'tcx>) -> Self { Self::from_scalar(Scalar::from_uint(i, layout.size), layout) } #[inline] - pub fn try_from_int(i: impl Into<i128>, layout: TyAndLayout<'tcx>) -> Option<Self> { - Some(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout)) - } - #[inline] pub fn from_int(i: impl Into<i128>, layout: TyAndLayout<'tcx>) -> Self { Self::from_scalar(Scalar::from_int(i, layout.size), layout) } @@ -276,7 +274,8 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { #[inline] pub fn to_const_int(self) -> ConstInt { assert!(self.layout.ty.is_integral()); - let int = self.to_scalar().assert_int(); + let int = self.imm.to_scalar_int(); + assert_eq!(int.size(), self.layout.size); ConstInt::new(int, self.layout.ty.is_signed(), self.layout.ty.is_ptr_sized_integral()) } diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 6d005dfcd86..c821c98073d 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -95,10 +95,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let l = left.to_scalar_int()?; let r = right.to_scalar_int()?; // Prepare to convert the values to signed or unsigned form. - let l_signed = || l.assert_int(left.layout.size); - let l_unsigned = || l.assert_uint(left.layout.size); - let r_signed = || r.assert_int(right.layout.size); - let r_unsigned = || r.assert_uint(right.layout.size); + let l_signed = || l.to_int(left.layout.size); + let l_unsigned = || l.to_uint(left.layout.size); + let r_signed = || r.to_int(right.layout.size); + let r_unsigned = || r.to_uint(right.layout.size); let throw_ub_on_overflow = match bin_op { AddUnchecked => Some(sym::unchecked_add), diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 3407c7b8c79..f532f6bbe37 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -653,8 +653,8 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { let WrappingRange { start, end } = valid_range; let max_value = size.unsigned_int_max(); assert!(end <= max_value); - let bits = match scalar.try_to_int() { - Ok(int) => int.assert_bits(size), + let bits = match scalar.try_to_scalar_int() { + Ok(int) => int.to_bits(size), Err(_) => { // So this is a pointer then, and casting to an int failed. // Can only happen during CTFE. |
