diff options
| author | bors <bors@rust-lang.org> | 2024-06-10 21:21:00 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-06-10 21:21:00 +0000 |
| commit | b5b13568fb5da4ac988bde370008d6134d3dfe6c (patch) | |
| tree | 6c5c97a6ce4d3c13ece43e509e62df9f3b0200dc /compiler/rustc_const_eval/src/interpret | |
| parent | d402830c8a356332de93761d6996faf5a2ca29ca (diff) | |
| parent | d762ef1d0c16ef70d6282a69b16891f8156782f1 (diff) | |
Auto merge of #126240 - matthiaskrgr:rollup-ks4o2n9, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #126063 (Remove some unused crate dependencies.) - #126115 (Fix ICE due to `unwrap` in `probe_for_name_many`) - #126159 (ScalarInt: size mismatches are a bug, do not delay the panic) - #126184 (interpret: do not ICE on padded non-pow2 SIMD vectors) - #126191 (Fix `NonZero` doctest inconsistencies) - #126211 (migrate tests/run-make/llvm-outputs to use rmake.rs) - #126212 (fix: build on haiku) - #126215 (Add explanatory note to async block type mismatch error) - #126223 (run-make: add `run_in_tmpdir` self-test) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret')
8 files changed, 32 insertions, 31 deletions
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/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 4a86ec3f57a..046ff34e3d0 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -499,13 +499,14 @@ where &self, mplace: &MPlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::Provenance>, u64)> { - // Basically we just transmute this place into an array following simd_size_and_type. - // (Transmuting is okay since this is an in-memory place. We also double-check the size - // stays the same.) + // Basically we want to transmute this place into an array following simd_size_and_type. let (len, e_ty) = mplace.layout.ty.simd_size_and_type(*self.tcx); - let array = Ty::new_array(self.tcx.tcx, e_ty, len); - let layout = self.layout_of(array)?; - let mplace = mplace.transmute(layout, self)?; + // Some SIMD types have padding, so `len` many `e_ty` does not cover the entire place. + // Therefore we cannot transmute, and instead we project at offset 0, which side-steps + // the size check. + let array_layout = self.layout_of(Ty::new_array(self.tcx.tcx, e_ty, len))?; + assert!(array_layout.size <= mplace.layout.size); + let mplace = mplace.offset(Size::ZERO, array_layout, self)?; Ok((mplace, len)) } diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 0e594914c3a..09e1a59dfa1 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -81,6 +81,8 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { assert!(layout.is_sized()); + // We sometimes do pointer arithmetic with this function, disregarding the source type. + // So we don't check the sizes here. self.offset_with_meta(offset, OffsetMode::Inbounds, MemPlaceMeta::None, layout, ecx) } 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. |
