From d3f8661c3183b4093d8420d80cebc32c21e405d2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 17 Sep 2023 13:20:21 +0000 Subject: [PATCH 1/2] Intern ConstValue. --- .../rustc_codegen_cranelift/src/constant.rs | 12 +-- .../src/intrinsics/simd.rs | 4 +- compiler/rustc_codegen_ssa/src/common.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 12 +-- .../src/const_eval/eval_queries.rs | 23 ++-- .../rustc_const_eval/src/const_eval/mod.rs | 2 +- .../src/const_eval/valtrees.rs | 6 +- .../src/interpret/intrinsics.rs | 12 +-- .../rustc_const_eval/src/interpret/operand.rs | 16 +-- .../src/transform/promote_consts.rs | 2 +- .../rustc_middle/src/mir/interpret/mod.rs | 2 +- .../rustc_middle/src/mir/interpret/value.rs | 100 +++++++++++++----- compiler/rustc_middle/src/mir/mod.rs | 28 ++--- compiler/rustc_middle/src/mir/pretty.rs | 28 ++--- compiler/rustc_middle/src/ty/codec.rs | 14 ++- compiler/rustc_middle/src/ty/context.rs | 5 +- .../rustc_middle/src/ty/structural_impls.rs | 7 ++ compiler/rustc_mir_build/src/build/cfg.rs | 2 +- .../src/build/custom/parse/instruction.rs | 4 +- .../src/build/expr/as_constant.rs | 29 ++--- .../src/build/expr/as_rvalue.rs | 2 +- .../rustc_mir_build/src/build/matches/test.rs | 2 +- compiler/rustc_mir_build/src/build/mod.rs | 4 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 13 ++- .../src/check_alignment.rs | 12 ++- .../rustc_mir_transform/src/const_prop.rs | 4 +- .../src/dataflow_const_prop.rs | 6 +- .../rustc_mir_transform/src/large_enums.rs | 2 +- .../src/lower_intrinsics.rs | 2 +- .../rustc_mir_transform/src/remove_zsts.rs | 3 +- compiler/rustc_mir_transform/src/shim.rs | 4 +- compiler/rustc_monomorphize/src/collector.rs | 12 ++- compiler/rustc_smir/src/rustc_smir/alloc.rs | 12 +-- src/librustdoc/clean/utils.rs | 54 +++++----- src/tools/clippy/clippy_utils/src/consts.rs | 13 +-- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 36 files changed, 274 insertions(+), 183 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 8c67760a0b9e3..9def350aef4e1 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -3,7 +3,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{ - read_target_uint, AllocId, ConstValue, ErrorHandled, GlobalAlloc, Scalar, + read_target_uint, AllocId, ConstValue, ConstValueKind, ErrorHandled, GlobalAlloc, Scalar, }; use cranelift_module::*; @@ -115,9 +115,9 @@ pub(crate) fn codegen_const_value<'tcx>( return CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout); } - match const_val { - ConstValue::ZeroSized => unreachable!(), // we already handled ZST above - ConstValue::Scalar(x) => match x { + match *const_val.kind() { + ConstValueKind::ZeroSized => unreachable!(), // we already handled ZST above + ConstValueKind::Scalar(x) => match x { Scalar::Int(int) => { if fx.clif_type(layout.ty).is_some() { return CValue::const_val(fx, layout, int); @@ -200,12 +200,12 @@ pub(crate) fn codegen_const_value<'tcx>( CValue::by_val(val, layout) } }, - ConstValue::Indirect { alloc_id, offset } => CValue::by_ref( + ConstValueKind::Indirect { alloc_id, offset } => CValue::by_ref( pointer_for_allocation(fx, alloc_id) .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()), layout, ), - ConstValue::Slice { data, start, end } => { + ConstValueKind::Slice { data, start, end } => { let alloc_id = fx.tcx.reserve_and_set_memory_alloc(data); let ptr = pointer_for_allocation(fx, alloc_id) .offset_i64(fx, i64::try_from(start).unwrap()) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index c64a4008996d5..ee6a0dcf1fd5b 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -171,8 +171,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let idx_const = crate::constant::mir_operand_get_const_val(fx, idx) .expect("simd_shuffle idx not const"); - let idx_bytes = match idx_const { - ConstValue::Indirect { alloc_id, offset } => { + let idx_bytes = match *idx_const.kind() { + ConstValueKind::Indirect { alloc_id, offset } => { let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); let size = Size::from_bytes( 4 * ret_lane_count, /* size_of([u32; ret_lane_count]) */ diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 5a68075991f16..60af2960c5165 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -197,7 +197,7 @@ pub fn asm_const_to_str<'tcx>( const_value: ConstValue<'tcx>, ty_and_layout: TyAndLayout<'tcx>, ) -> String { - let ConstValue::Scalar(scalar) = const_value else { + let Some(scalar) = const_value.try_to_scalar() else { span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value) }; let value = scalar.assert_bits(ty_and_layout.size); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 1926bb8df52cc..7d44956b771da 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -7,7 +7,7 @@ use crate::traits::*; use crate::MemFlags; use rustc_middle::mir; -use rustc_middle::mir::interpret::{alloc_range, ConstValue, Pointer, Scalar}; +use rustc_middle::mir::interpret::{alloc_range, ConstValue, ConstValueKind, Pointer, Scalar}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; use rustc_target::abi::{self, Abi, Align, Size}; @@ -91,16 +91,16 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { ) -> Self { let layout = bx.layout_of(ty); - let val = match val { - ConstValue::Scalar(x) => { + let val = match *val.kind() { + ConstValueKind::Scalar(x) => { let Abi::Scalar(scalar) = layout.abi else { bug!("from_const: invalid ByVal layout: {:#?}", layout); }; let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout)); OperandValue::Immediate(llval) } - ConstValue::ZeroSized => return OperandRef::zero_sized(layout), - ConstValue::Slice { data, start, end } => { + ConstValueKind::ZeroSized => return OperandRef::zero_sized(layout), + ConstValueKind::Slice { data, start, end } => { let Abi::ScalarPair(a_scalar, _) = layout.abi else { bug!("from_const: invalid ScalarPair layout: {:#?}", layout); }; @@ -119,7 +119,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let b_llval = bx.const_usize((end - start) as u64); OperandValue::Pair(a_llval, b_llval) } - ConstValue::Indirect { alloc_id, offset } => { + ConstValueKind::Indirect { alloc_id, offset } => { let alloc = bx.tcx().global_alloc(alloc_id).unwrap_memory(); return Self::from_const_alloc(bx, layout, alloc, offset); } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 454baf2a745b9..baf3e6e4d429c 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -111,23 +111,24 @@ pub(super) fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, 'tcx>, op: &OpTy<'tcx>, ) -> ConstValue<'tcx> { + let tcx = *ecx.tcx; // Handle ZST consistently and early. if op.layout.is_zst() { - return ConstValue::ZeroSized; + return ConstValue::zero_sized(tcx); } - // All scalar types should be stored as `ConstValue::Scalar`. This is needed to make - // `ConstValue::try_to_scalar` efficient; we want that to work for *all* constants of scalar + // All scalar types should be stored as `ConstValueKind::Scalar`. This is needed to make + // `ConstValueKind::try_to_scalar` efficient; we want that to work for *all* constants of scalar // type (it's used throughout the compiler and having it work just on literals is not enough) // and we want it to be fast (i.e., don't go to an `Allocation` and reconstruct the `Scalar` // from its byte-serialized form). let force_as_immediate = match op.layout.abi { Abi::Scalar(abi::Scalar::Initialized { .. }) => true, - // We don't *force* `ConstValue::Slice` for `ScalarPair`. This has the advantage that if the + // We don't *force* `ConstValueKind::Slice` for `ScalarPair`. This has the advantage that if the // input `op` is a place, then turning it into a `ConstValue` and back into a `OpTy` will // not have to generate any duplicate allocations (we preserve the original `AllocId` in - // `ConstValue::Indirect`). It means accessing the contents of a slice can be slow (since - // they can be stored as `ConstValue::Indirect`), but that's not relevant since we barely + // `ConstValueKind::Indirect`). It means accessing the contents of a slice can be slow (since + // they can be stored as `ConstValueKind::Indirect`), but that's not relevant since we barely // ever have to do this. (`try_get_slice_bytes_for_diagnostics` exists to provide this // functionality.) _ => false, @@ -145,26 +146,26 @@ pub(super) fn op_to_const<'tcx>( // We know `offset` is relative to the allocation, so we can use `into_parts`. let (alloc_id, offset) = mplace.ptr().into_parts(); let alloc_id = alloc_id.expect("cannot have `fake` place fot non-ZST type"); - ConstValue::Indirect { alloc_id, offset } + ConstValue::from_memory(tcx, alloc_id, offset) } // see comment on `let force_as_immediate` above Right(imm) => match *imm { - Immediate::Scalar(x) => ConstValue::Scalar(x), + Immediate::Scalar(x) => ConstValue::from_scalar(tcx, x), Immediate::ScalarPair(a, b) => { debug!("ScalarPair(a: {:?}, b: {:?})", a, b); // FIXME: assert that this has an appropriate type. // Currently we actually get here for non-[u8] slices during valtree construction! let msg = "`op_to_const` on an immediate scalar pair must only be used on slice references to actually allocated memory"; // We know `offset` is relative to the allocation, so we can use `into_parts`. - // We use `ConstValue::Slice` so that we don't have to generate an allocation for - // `ConstValue::Indirect` here. + // We use `ConstValueKind::Slice` so that we don't have to generate an allocation for + // `ConstValueKind::Indirect` here. let (alloc_id, offset) = a.to_pointer(ecx).expect(msg).into_parts(); let alloc_id = alloc_id.expect(msg); let data = ecx.tcx.global_alloc(alloc_id).unwrap_memory(); let start = offset.bytes_usize(); let len = b.to_target_usize(ecx).expect(msg); let len: usize = len.try_into().unwrap(); - ConstValue::Slice { data, start, end: start + len } + ConstValue::from_slice(tcx, data, start, start + len) } Immediate::Uninit => bug!("`Uninit` is not a valid value for {}", op.layout.ty), }, diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 5327fa5ce39bd..eb8e200a90fc8 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -30,7 +30,7 @@ pub(crate) fn const_caller_location( if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &loc_place).is_err() { bug!("intern_const_alloc_recursive should not error in this case") } - ConstValue::Scalar(Scalar::from_maybe_pointer(loc_place.ptr(), &tcx)) + ConstValue::from_scalar(tcx, Scalar::from_maybe_pointer(loc_place.ptr(), &tcx)) } // We forbid type-level constants that contain more than `VALTREE_MAX_NODES` nodes. diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 1675b824c525c..5b0e85c1e474e 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -219,10 +219,10 @@ pub fn valtree_to_const_value<'tcx>( match ty.kind() { ty::FnDef(..) => { assert!(valtree.unwrap_branch().is_empty()); - ConstValue::ZeroSized + ConstValue::zero_sized(tcx) } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => match valtree { - ty::ValTree::Leaf(scalar_int) => ConstValue::Scalar(Scalar::Int(scalar_int)), + ty::ValTree::Leaf(scalar_int) => ConstValue::from_scalar(tcx, Scalar::Int(scalar_int)), ty::ValTree::Branch(_) => bug!( "ValTrees for Bool, Int, Uint, Float or Char should have the form ValTree::Leaf" ), @@ -237,7 +237,7 @@ pub fn valtree_to_const_value<'tcx>( let layout = tcx.layout_of(param_env_ty).unwrap(); if layout.is_zst() { // Fast path to avoid some allocations. - return ConstValue::ZeroSized; + return ConstValue::zero_sized(tcx); } if layout.abi.is_scalar() && (matches!(ty.kind(), ty::Tuple(_)) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 3b58f66353b27..4a67c55d2f6dc 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -64,24 +64,24 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( sym::type_name => { ensure_monomorphic_enough(tcx, tp_ty)?; let alloc = alloc_type_name(tcx, tp_ty); - ConstValue::Slice { data: alloc, start: 0, end: alloc.inner().len() } + ConstValue::from_slice(tcx, alloc, 0, alloc.inner().len()) } sym::needs_drop => { ensure_monomorphic_enough(tcx, tp_ty)?; - ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)) + ConstValue::from_bool(tcx, tp_ty.needs_drop(tcx, param_env)) } sym::pref_align_of => { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(*e)))?; - ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx) + ConstValue::from_target_usize(tcx, layout.align.pref.bytes()) } sym::type_id => { ensure_monomorphic_enough(tcx, tp_ty)?; - ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128()) + ConstValue::from_u128(tcx, tcx.type_id_hash(tp_ty).as_u128()) } sym::variant_count => match tp_ty.kind() { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. - ty::Adt(adt, _) => ConstValue::from_target_usize(adt.variants().len() as u64, &tcx), + ty::Adt(adt, _) => ConstValue::from_target_usize(tcx, adt.variants().len() as u64), ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => { throw_inval!(TooGeneric) } @@ -106,7 +106,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( | ty::GeneratorWitnessMIR(_, _) | ty::Never | ty::Tuple(_) - | ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx), + | ty::Error(_) => ConstValue::from_target_usize(tcx, 0u64), }, other => bug!("`{}` is not a zero arg intrinsic", other), }) diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 3d42fda1f68a7..0b902448068ab 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -14,9 +14,9 @@ use rustc_span::Span; use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size}; use super::{ - alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, GlobalId, - InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, - Projectable, Provenance, Scalar, + alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, ConstValueKind, + Frame, GlobalId, InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, + Pointer, Projectable, Provenance, Scalar, }; /// An `Immediate` represents a single immediate self-contained Rust value. @@ -763,16 +763,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }) }; let layout = from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty))?; - let op = match val_val { - ConstValue::Indirect { alloc_id, offset } => { + let op = match *val_val.kind() { + ConstValueKind::Indirect { alloc_id, offset } => { // We rely on mutability being set correctly in that allocation to prevent writes // where none should happen. let ptr = self.global_base_pointer(Pointer::new(alloc_id, offset))?; Operand::Indirect(MemPlace::from_ptr(ptr.into())) } - ConstValue::Scalar(x) => Operand::Immediate(adjust_scalar(x)?.into()), - ConstValue::ZeroSized => Operand::Immediate(Immediate::Uninit), - ConstValue::Slice { data, start, end } => { + ConstValueKind::Scalar(x) => Operand::Immediate(adjust_scalar(x)?.into()), + ConstValueKind::ZeroSized => Operand::Immediate(Immediate::Uninit), + ConstValueKind::Slice { data, start, end } => { // We rely on mutability being set correctly in `data` to prevent writes // where none should happen. let ptr = Pointer::new( diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index d79c65f1d1fee..5dc0bc3eb671d 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -769,7 +769,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let unit = Rvalue::Use(Operand::Constant(Box::new(Constant { span: statement.source_info.span, user_ty: None, - literal: ConstantKind::zero_sized(self.tcx.types.unit), + literal: ConstantKind::zero_sized(self.tcx, self.tcx.types.unit), }))); mem::replace(rhs, unit) }, diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 44d1dcbbe1791..9de193cf021c6 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -149,7 +149,7 @@ pub use self::error::{ UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind, }; -pub use self::value::{ConstAlloc, ConstValue, Scalar}; +pub use self::value::{ConstAlloc, ConstValue, ConstValueKind, Scalar}; pub use self::allocation::{ alloc_range, AllocBytes, AllocError, AllocRange, AllocResult, Allocation, ConstAllocation, diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index c169733ad742c..f52bd47e8ceee 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -6,6 +6,7 @@ use rustc_apfloat::{ ieee::{Double, Single}, Float, }; +use rustc_data_structures::intern::Interned; use rustc_macros::HashStable; use rustc_target::abi::{HasDataLayout, Size}; @@ -28,11 +29,15 @@ pub struct ConstAlloc<'tcx> { pub ty: Ty<'tcx>, } +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +#[derive(HashStable)] +pub struct ConstValue<'tcx>(pub(crate) Interned<'tcx, ConstValueKind<'tcx>>); + /// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for /// array length computations, enum discriminants and the pattern matching logic. #[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash)] #[derive(HashStable, Lift)] -pub enum ConstValue<'tcx> { +pub enum ConstValueKind<'tcx> { /// Used for types with `layout::abi::Scalar` ABI. /// /// Not using the enum `Value` to encode that this must not be `Uninit`. @@ -65,35 +70,47 @@ pub enum ConstValue<'tcx> { } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(ConstValue<'_>, 32); +static_assert_size!(ConstValue<'_>, 8); impl<'tcx> ConstValue<'tcx> { #[inline] - pub fn try_to_scalar(&self) -> Option> { - match *self { - ConstValue::Indirect { .. } | ConstValue::Slice { .. } | ConstValue::ZeroSized => None, - ConstValue::Scalar(val) => Some(val), + pub fn new(tcx: TyCtxt<'tcx>, kind: ConstValueKind<'tcx>) -> ConstValue<'tcx> { + tcx.intern_const_value(kind) + } + + #[inline] + pub fn kind(self) -> &'tcx ConstValueKind<'tcx> { + self.0.0 + } + + #[inline] + pub fn try_to_scalar(self) -> Option> { + match self.kind() { + ConstValueKind::Indirect { .. } + | ConstValueKind::Slice { .. } + | ConstValueKind::ZeroSized => None, + ConstValueKind::Scalar(val) => Some(*val), } } - pub fn try_to_scalar_int(&self) -> Option { + pub fn try_to_scalar_int(self) -> Option { self.try_to_scalar()?.try_to_int().ok() } - pub fn try_to_bits(&self, size: Size) -> Option { + pub fn try_to_bits(self, size: Size) -> Option { self.try_to_scalar_int()?.to_bits(size).ok() } - pub fn try_to_bool(&self) -> Option { + pub fn try_to_bool(self) -> Option { self.try_to_scalar_int()?.try_into().ok() } - pub fn try_to_target_usize(&self, tcx: TyCtxt<'tcx>) -> Option { + pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { self.try_to_scalar_int()?.try_to_target_usize(tcx).ok() } pub fn try_to_bits_for_ty( - &self, + self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, @@ -102,30 +119,65 @@ impl<'tcx> ConstValue<'tcx> { self.try_to_bits(size) } - pub fn from_bool(b: bool) -> Self { - ConstValue::Scalar(Scalar::from_bool(b)) + #[inline] + pub fn zero_sized(tcx: TyCtxt<'tcx>) -> Self { + Self::new(tcx, ConstValueKind::ZeroSized) } - pub fn from_u64(i: u64) -> Self { - ConstValue::Scalar(Scalar::from_u64(i)) + #[inline] + pub fn from_scalar(tcx: TyCtxt<'tcx>, scalar: Scalar) -> Self { + Self::new(tcx, ConstValueKind::Scalar(scalar)) } - pub fn from_u128(i: u128) -> Self { - ConstValue::Scalar(Scalar::from_u128(i)) + #[inline] + pub fn from_bool(tcx: TyCtxt<'tcx>, b: bool) -> Self { + Self::from_scalar(tcx, Scalar::from_bool(b)) } - pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self { - ConstValue::Scalar(Scalar::from_target_usize(i, cx)) + #[inline] + pub fn from_u64(tcx: TyCtxt<'tcx>, i: u64) -> Self { + Self::from_scalar(tcx, Scalar::from_u64(i)) + } + + #[inline] + pub fn from_u128(tcx: TyCtxt<'tcx>, i: u128) -> Self { + Self::from_scalar(tcx, Scalar::from_u128(i)) + } + + #[inline] + pub fn from_target_usize(tcx: TyCtxt<'tcx>, i: u64) -> Self { + Self::from_scalar(tcx, Scalar::from_target_usize(i, &tcx)) + } + + #[inline] + pub fn from_pointer(tcx: TyCtxt<'tcx>, pointer: Pointer) -> Self { + Self::from_scalar(tcx, Scalar::from_pointer(pointer, &tcx)) + } + + #[inline] + pub fn from_slice( + tcx: TyCtxt<'tcx>, + data: ConstAllocation<'tcx>, + start: usize, + end: usize, + ) -> Self { + Self::new(tcx, ConstValueKind::Slice { data, start, end }) + } + + #[inline] + pub fn from_memory(tcx: TyCtxt<'tcx>, alloc_id: AllocId, offset: Size) -> Self { + debug_assert!(matches!(tcx.global_alloc(alloc_id), super::GlobalAlloc::Memory(_))); + Self::new(tcx, ConstValueKind::Indirect { alloc_id, offset }) } /// Must only be called on constants of type `&str` or `&[u8]`! - pub fn try_get_slice_bytes_for_diagnostics(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx [u8]> { - let (data, start, end) = match self { - ConstValue::Scalar(_) | ConstValue::ZeroSized => { + pub fn try_get_slice_bytes_for_diagnostics(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx [u8]> { + let (data, start, end) = match self.kind() { + ConstValueKind::Scalar(_) | ConstValueKind::ZeroSized => { bug!("`try_get_slice_bytes` on non-slice constant") } - &ConstValue::Slice { data, start, end } => (data, start, end), - &ConstValue::Indirect { alloc_id, offset } => { + &ConstValueKind::Slice { data, start, end } => (data, start, end), + &ConstValueKind::Indirect { alloc_id, offset } => { // The reference itself is stored behind an indirection. // Load the reference, and then load the actual slice contents. let a = tcx.global_alloc(alloc_id).unwrap_memory().inner(); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 8df3a79b4d414..a3e4d58aa0ffa 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -3,7 +3,7 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html use crate::mir::interpret::{ - AllocRange, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar, + AllocRange, ConstAllocation, ConstValue, ConstValueKind, ErrorHandled, GlobalAlloc, Scalar, }; use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; @@ -1967,7 +1967,7 @@ impl<'tcx> Operand<'tcx> { Operand::Constant(Box::new(Constant { span, user_ty: None, - literal: ConstantKind::Val(ConstValue::ZeroSized, ty), + literal: ConstantKind::zero_sized(tcx, ty), })) } @@ -1998,7 +1998,7 @@ impl<'tcx> Operand<'tcx> { Operand::Constant(Box::new(Constant { span, user_ty: None, - literal: ConstantKind::Val(ConstValue::Scalar(val), ty), + literal: ConstantKind::Val(ConstValue::from_scalar(tcx, val), ty), })) } @@ -2479,20 +2479,20 @@ impl<'tcx> ConstantKind<'tcx> { bug!("could not compute layout for {:?}: {:?}", param_env_ty.value, e) }) .size; - let cv = ConstValue::Scalar(Scalar::from_uint(bits, size)); + let cv = ConstValue::from_scalar(tcx, Scalar::from_uint(bits, size)); Self::Val(cv, param_env_ty.value) } #[inline] pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self { - let cv = ConstValue::from_bool(v); + let cv = ConstValue::from_bool(tcx, v); Self::Val(cv, tcx.types.bool) } #[inline] - pub fn zero_sized(ty: Ty<'tcx>) -> Self { - let cv = ConstValue::ZeroSized; + pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self { + let cv = ConstValue::zero_sized(tcx); Self::Val(cv, ty) } @@ -2502,8 +2502,8 @@ impl<'tcx> ConstantKind<'tcx> { } #[inline] - pub fn from_scalar(_tcx: TyCtxt<'tcx>, s: Scalar, ty: Ty<'tcx>) -> Self { - let val = ConstValue::Scalar(s); + pub fn from_scalar(tcx: TyCtxt<'tcx>, s: Scalar, ty: Ty<'tcx>) -> Self { + let val = ConstValue::from_scalar(tcx, s); Self::Val(val, ty) } @@ -2885,7 +2885,7 @@ fn pretty_print_const_value<'tcx>( } let u8_type = tcx.types.u8; - match (ct, ty.kind()) { + match (*ct.kind(), ty.kind()) { // Byte/string slices, printed as (byte) string literals. (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => { if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) { @@ -2899,7 +2899,7 @@ fn pretty_print_const_value<'tcx>( return Ok(()); } } - (ConstValue::Indirect { alloc_id, offset }, ty::Array(t, n)) if *t == u8_type => { + (ConstValueKind::Indirect { alloc_id, offset }, ty::Array(t, n)) if *t == u8_type => { let n = n.try_to_target_usize(tcx).unwrap(); let alloc = tcx.global_alloc(alloc_id).unwrap_memory(); // cast is ok because we already checked for pointer size (32 or 64 bit) above @@ -2978,7 +2978,7 @@ fn pretty_print_const_value<'tcx>( return Ok(()); } } - (ConstValue::Scalar(scalar), _) => { + (ConstValueKind::Scalar(scalar), _) => { let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS); cx.print_alloc_ids = true; let ty = tcx.lift(ty).unwrap(); @@ -2986,7 +2986,7 @@ fn pretty_print_const_value<'tcx>( fmt.write_str(&cx.into_buffer())?; return Ok(()); } - (ConstValue::ZeroSized, ty::FnDef(d, s)) => { + (ConstValueKind::ZeroSized, ty::FnDef(d, s)) => { let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS); cx.print_alloc_ids = true; let cx = cx.print_value_path(*d, s)?; @@ -3084,6 +3084,6 @@ mod size_asserts { static_assert_size!(StatementKind<'_>, 16); static_assert_size!(Terminator<'_>, 104); static_assert_size!(TerminatorKind<'_>, 88); - static_assert_size!(VarDebugInfo<'_>, 88); + static_assert_size!(VarDebugInfo<'_>, 80); // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index c4fae27a7a537..288a146622633 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -13,7 +13,7 @@ use rustc_hir::def_id::DefId; use rustc_index::Idx; use rustc_middle::mir::interpret::{ alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, ConstAllocation, ConstValue, - GlobalAlloc, Pointer, Provenance, + ConstValueKind, GlobalAlloc, Pointer, Provenance, }; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; @@ -456,11 +456,11 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { } // FIXME: this is a poor version of `pretty_print_const_value`. - let fmt_val = |val: &ConstValue<'tcx>| match val { - ConstValue::ZeroSized => "".to_string(), - ConstValue::Scalar(s) => format!("Scalar({s:?})"), - ConstValue::Slice { .. } => "Slice(..)".to_string(), - ConstValue::Indirect { .. } => "ByRef(..)".to_string(), + let fmt_val = |val: &ConstValue<'tcx>| match val.kind() { + ConstValueKind::ZeroSized => "".to_string(), + ConstValueKind::Scalar(s) => format!("Scalar({s:?})"), + ConstValueKind::Slice { .. } => "Slice(..)".to_string(), + ConstValueKind::Indirect { .. } => "ByRef(..)".to_string(), }; let fmt_valtree = |valtree: &ty::ValTree<'tcx>| match valtree { @@ -699,20 +699,22 @@ pub fn write_allocations<'tcx>( } fn alloc_ids_from_const_val(val: ConstValue<'_>) -> impl Iterator + '_ { - match val { - ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _)) => { + match val.kind() { + ConstValueKind::Scalar(interpret::Scalar::Ptr(ptr, _)) => { Either::Left(std::iter::once(ptr.provenance)) } - ConstValue::Scalar(interpret::Scalar::Int { .. }) => Either::Right(std::iter::empty()), - ConstValue::ZeroSized => Either::Right(std::iter::empty()), - ConstValue::Slice { .. } => { + ConstValueKind::Scalar(interpret::Scalar::Int { .. }) => { + Either::Right(std::iter::empty()) + } + ConstValueKind::ZeroSized => Either::Right(std::iter::empty()), + ConstValueKind::Slice { .. } => { // `u8`/`str` slices, shouldn't contain pointers that we want to print. Either::Right(std::iter::empty()) } - ConstValue::Indirect { alloc_id, .. } => { + ConstValueKind::Indirect { alloc_id, .. } => { // FIXME: we don't actually want to print all of these, since some are printed nicely directly as values inline in MIR. // Really we'd want `pretty_print_const_value` to decide which allocations to print, instead of having a separate visitor. - Either::Left(std::iter::once(alloc_id)) + Either::Left(std::iter::once(*alloc_id)) } } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 7c05deae90a58..d4701605a86c5 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -10,7 +10,7 @@ use crate::arena::ArenaAllocatable; use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; use crate::mir::{ self, - interpret::{AllocId, ConstAllocation}, + interpret::{AllocId, ConstAllocation, ConstValue}, }; use crate::traits; use crate::ty::GenericArgsRef; @@ -152,6 +152,12 @@ impl<'tcx, E: TyEncoder>> Encodable for ConstAllocation<'tcx } } +impl<'tcx, E: TyEncoder>> Encodable for ConstValue<'tcx> { + fn encode(&self, e: &mut E) { + self.kind().encode(e) + } +} + impl<'tcx, E: TyEncoder>> Encodable for AdtDef<'tcx> { fn encode(&self, e: &mut E) { self.0.0.encode(e) @@ -360,6 +366,12 @@ impl<'tcx, D: TyDecoder>> Decodable for ConstAllocation<'tcx } } +impl<'tcx, D: TyDecoder>> Decodable for ConstValue<'tcx> { + fn decode(decoder: &mut D) -> Self { + decoder.interner().intern_const_value(Decodable::decode(decoder)) + } +} + impl<'tcx, D: TyDecoder>> Decodable for AdtDef<'tcx> { fn decode(decoder: &mut D) -> Self { decoder.interner().mk_adt_def_from_data(Decodable::decode(decoder)) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f748404875759..702cdbfab1ce7 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -12,7 +12,7 @@ use crate::metadata::ModChild; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::resolve_bound_vars; use crate::middle::stability; -use crate::mir::interpret::{self, Allocation, ConstAllocation}; +use crate::mir::interpret::{self, Allocation, ConstAllocation, ConstValue, ConstValueKind}; use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::query::plumbing::QuerySystem; use crate::query::LocalCrate; @@ -156,6 +156,7 @@ pub struct CtxtInterners<'tcx> { external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>, predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>, fields: InternedSet<'tcx, List>, + const_value: InternedSet<'tcx, ConstValueKind<'tcx>>, } impl<'tcx> CtxtInterners<'tcx> { @@ -181,6 +182,7 @@ impl<'tcx> CtxtInterners<'tcx> { external_constraints: Default::default(), predefined_opaques_in_body: Default::default(), fields: Default::default(), + const_value: Default::default(), } } @@ -1497,6 +1499,7 @@ direct_interners! { region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>, const_: intern_const(ConstData<'tcx>): Const -> Const<'tcx>, const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, + const_value: pub(crate) intern_const_value(ConstValueKind<'tcx>): ConstValue -> ConstValue<'tcx>, layout: pub mk_layout(LayoutS): Layout -> Layout<'tcx>, adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>, external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>): diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 7c25d0209c92d..afadcfca459bb 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -624,6 +624,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { } } +impl<'a, 'tcx> Lift<'tcx> for interpret::ConstValue<'a> { + type Lifted = interpret::ConstValue<'tcx>; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + tcx.lift(*self.kind()).map(|kind| interpret::ConstValue::new(tcx, kind)) + } +} + /////////////////////////////////////////////////////////////////////////// // Traversal implementations. diff --git a/compiler/rustc_mir_build/src/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs index 4f1623b4c6a7c..1816175a44b84 100644 --- a/compiler/rustc_mir_build/src/build/cfg.rs +++ b/compiler/rustc_mir_build/src/build/cfg.rs @@ -73,7 +73,7 @@ impl<'tcx> CFG<'tcx> { Rvalue::Use(Operand::Constant(Box::new(Constant { span: source_info.span, user_ty: None, - literal: ConstantKind::zero_sized(tcx.types.unit), + literal: ConstantKind::zero_sized(tcx, tcx.types.unit), }))), ); } diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index da5f2b1bcc99c..4834c6ae85b92 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -1,4 +1,4 @@ -use rustc_middle::mir::interpret::{ConstValue, Scalar}; +use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::ty::cast::mir_cast_kind; use rustc_middle::{mir::*, thir::*, ty}; @@ -282,7 +282,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { parse_by_kind!(self, expr_id, expr, "static", ExprKind::StaticRef { alloc_id, ty, .. } => { let const_val = - ConstValue::Scalar(Scalar::from_pointer((*alloc_id).into(), &self.tcx)); + ConstValue::from_pointer(self.tcx, (*alloc_id).into()); let literal = ConstantKind::Val(const_val, *ty); Ok(Operand::Constant(Box::new(Constant { diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index aaa37446e24d3..b0e1bf4fd1528 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -64,14 +64,14 @@ pub fn as_constant_inner<'tcx>( ExprKind::NonHirLiteral { lit, ref user_ty } => { let user_ty = user_ty.as_ref().and_then(push_cuta); - let literal = ConstantKind::Val(ConstValue::Scalar(Scalar::Int(lit)), ty); + let literal = ConstantKind::from_scalar(tcx, Scalar::Int(lit), ty); Constant { span, user_ty, literal } } ExprKind::ZstLiteral { ref user_ty } => { let user_ty = user_ty.as_ref().and_then(push_cuta); - let literal = ConstantKind::Val(ConstValue::ZeroSized, ty); + let literal = ConstantKind::zero_sized(tcx, ty); Constant { span, user_ty, literal } } @@ -96,7 +96,7 @@ pub fn as_constant_inner<'tcx>( Constant { user_ty: None, span, literal } } ExprKind::StaticRef { alloc_id, ty, .. } => { - let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx)); + let const_val = ConstValue::from_pointer(tcx, alloc_id.into()); let literal = ConstantKind::Val(const_val, ty); Constant { span, user_ty: None, literal } @@ -125,7 +125,7 @@ fn lit_to_mir_constant<'tcx>( trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); let result = width.truncate(n); trace!("trunc result: {}", result); - Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) + Ok(ConstValue::from_scalar(tcx, Scalar::from_uint(result, width))) }; let value = match (lit, &ty.kind()) { @@ -133,40 +133,41 @@ fn lit_to_mir_constant<'tcx>( let s = s.as_str(); let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); let allocation = tcx.mk_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: s.len() } + ConstValue::from_slice(tcx, allocation, 0, s.len()) } (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(_)) => { let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); let allocation = tcx.mk_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: data.len() } + ConstValue::from_slice(tcx, allocation, 0, data.len()) } (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { let id = tcx.allocate_bytes(data); - ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx)) + ConstValue::from_pointer(tcx, id.into()) } (ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) => { let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); let allocation = tcx.mk_const_alloc(allocation); - ConstValue::Slice { data: allocation, start: 0, end: data.len() } + ConstValue::from_slice(tcx, allocation, 0, data.len()) } (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { - ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) + ConstValue::from_scalar(tcx, Scalar::from_uint(*n, Size::from_bytes(1))) } (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })? } - (ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float_into_constval(*n, *fty, neg) - .ok_or_else(|| { + (ast::LitKind::Float(n, _), ty::Float(fty)) => { + parse_float_into_constval(tcx, *n, *fty, neg).ok_or_else(|| { LitToConstError::Reported(tcx.sess.delay_span_bug( DUMMY_SP, format!("couldn't parse float literal: {:?}", lit_input.lit), )) - })?, - (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), - (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), + })? + } + (ast::LitKind::Bool(b), ty::Bool) => ConstValue::from_bool(tcx, *b), + (ast::LitKind::Char(c), ty::Char) => ConstValue::from_scalar(tcx, Scalar::from_char(*c)), (ast::LitKind::Err, _) => { return Err(LitToConstError::Reported( tcx.sess.delay_span_bug(DUMMY_SP, "encountered LitKind::Err during mir build"), diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 3220a184d49ba..73e42c3d71251 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -488,7 +488,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(Rvalue::Use(Operand::Constant(Box::new(Constant { span: expr_span, user_ty: None, - literal: ConstantKind::zero_sized(this.tcx.types.unit), + literal: ConstantKind::zero_sized(this.tcx, this.tcx.types.unit), })))) } diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 484e8490919d4..861e7d5193a55 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -877,5 +877,5 @@ fn trait_method<'tcx>( let method_ty = Ty::new_fn_def(tcx, item.def_id, args); - ConstantKind::zero_sized(method_ty) + ConstantKind::zero_sized(tcx, method_ty) } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 4e10916ad61ef..ee8b58c513128 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -961,11 +961,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } fn parse_float_into_constval<'tcx>( + tcx: TyCtxt<'tcx>, num: Symbol, float_ty: ty::FloatTy, neg: bool, ) -> Option> { - parse_float_into_scalar(num, float_ty, neg).map(ConstValue::Scalar) + let scalar = parse_float_into_scalar(num, float_ty, neg)?; + Some(ConstValue::from_scalar(tcx, scalar)) } pub(crate) fn parse_float_into_scalar( diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 0ea61ec8d401d..9f2a1d45de869 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -18,7 +18,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::RangeEnd; use rustc_index::Idx; use rustc_middle::mir::interpret::{ - ConstValue, ErrorHandled, GlobalId, LitToConstError, LitToConstInput, Scalar, + ErrorHandled, GlobalId, LitToConstError, LitToConstInput, Scalar, }; use rustc_middle::mir::{self, ConstantKind, UserTypeProjection}; use rustc_middle::mir::{BorrowKind, Mutability}; @@ -854,10 +854,13 @@ pub(crate) fn compare_const_vals<'tcx>( match ty.kind() { ty::Float(_) | ty::Int(_) => {} // require special handling, see below _ => match (a, b) { - ( - mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(a)), _a_ty), - mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(b)), _b_ty), - ) => return Some(a.cmp(&b)), + (mir::ConstantKind::Val(a, _a_ty), mir::ConstantKind::Val(b, _b_ty)) => { + if let Some(Scalar::Int(a)) = a.try_to_scalar() + && let Some(Scalar::Int(b)) = b.try_to_scalar() + { + return Some(a.cmp(&b)) + } + } (mir::ConstantKind::Ty(a), mir::ConstantKind::Ty(b)) => { return Some(a.kind().cmp(&b.kind())); } diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index 4892ace53e381..b151ee52c6d7d 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -4,7 +4,7 @@ use rustc_hir::lang_items::LangItem; use rustc_index::IndexVec; use rustc_middle::mir::*; use rustc_middle::mir::{ - interpret::{ConstValue, Scalar}, + interpret::Scalar, visit::{PlaceContext, Visitor}, }; use rustc_middle::ty::{Ty, TyCtxt, TypeAndMut}; @@ -184,8 +184,9 @@ fn insert_alignment_check<'tcx>( let one = Operand::Constant(Box::new(Constant { span: source_info.span, user_ty: None, - literal: ConstantKind::Val( - ConstValue::Scalar(Scalar::from_target_usize(1, &tcx)), + literal: ConstantKind::from_scalar( + tcx, + Scalar::from_target_usize(1, &tcx), tcx.types.usize, ), })); @@ -216,8 +217,9 @@ fn insert_alignment_check<'tcx>( let zero = Operand::Constant(Box::new(Constant { span: source_info.span, user_ty: None, - literal: ConstantKind::Val( - ConstValue::Scalar(Scalar::from_target_usize(0, &tcx)), + literal: ConstantKind::from_scalar( + tcx, + Scalar::from_target_usize(0, &tcx), tcx.types.usize, ), })); diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 00e3e3a8f9f88..d9cddba607031 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -143,7 +143,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> #[inline(always)] fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment { // We do not check for alignment to avoid having to carry an `Align` - // in `ConstValue::Indirect`. + // in `ConstValueKind::Indirect`. CheckAlignment::No } @@ -552,7 +552,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { .ok()?; Some(ConstantKind::Val( - ConstValue::Indirect { alloc_id, offset: Size::ZERO }, + ConstValue::from_memory(self.tcx, alloc_id, Size::ZERO), value.layout.ty, )) } diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index c7c5f17dfec50..f8c3cfd9bad51 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -6,7 +6,7 @@ use rustc_const_eval::const_eval::CheckAlignment; use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, Projectable}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; -use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ConstValue, InterpResult, Scalar}; +use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult, Scalar}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::layout::TyAndLayout; @@ -554,7 +554,7 @@ impl<'tcx, 'locals> Collector<'tcx, 'locals> { return None; }; let ty = place.ty(self.local_decls, self.patch.tcx).ty; - Some(ConstantKind::Val(ConstValue::Scalar(value.into()), ty)) + Some(ConstantKind::from_scalar(self.patch.tcx, value.into(), ty)) } } @@ -703,7 +703,7 @@ impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for Dumm #[inline(always)] fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment { // We do not check for alignment to avoid having to carry an `Align` - // in `ConstValue::ByRef`. + // in `ConstValueKind::ByRef`. CheckAlignment::No } diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 8afbe418502c5..aff10d2a86396 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -153,7 +153,7 @@ impl EnumSizeOpt { span, user_ty: None, literal: ConstantKind::Val( - interpret::ConstValue::Indirect { alloc_id, offset: Size::ZERO }, + interpret::ConstValue::from_memory(tcx, alloc_id, Size::ZERO), tmp_ty, ), }; diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 13277d62bf4c9..083a4ed6a6ab0 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -35,7 +35,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { Rvalue::Use(Operand::Constant(Box::new(Constant { span: terminator.source_info.span, user_ty: None, - literal: ConstantKind::zero_sized(tcx.types.unit), + literal: ConstantKind::zero_sized(tcx, tcx.types.unit), }))), ))), }); diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index c13bafa9fbb5b..7a8e88551067b 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -1,7 +1,6 @@ //! Removes operations on ZST places, and convert ZST operands to constants. use crate::MirPass; -use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -68,7 +67,7 @@ impl<'tcx> Replacer<'_, 'tcx> { Constant { span: rustc_span::DUMMY_SP, user_ty: None, - literal: ConstantKind::Val(ConstValue::ZeroSized, ty), + literal: ConstantKind::zero_sized(self.tcx, ty), } } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index e1000d9693239..16987395ea808 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -500,7 +500,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { let func = Operand::Constant(Box::new(Constant { span: self.span, user_ty: None, - literal: ConstantKind::zero_sized(func_ty), + literal: ConstantKind::zero_sized(tcx, func_ty), })); let ref_loc = self.make_place( @@ -767,7 +767,7 @@ fn build_call_shim<'tcx>( Operand::Constant(Box::new(Constant { span, user_ty: None, - literal: ConstantKind::zero_sized(ty), + literal: ConstantKind::zero_sized(tcx, ty), })), rcvr.into_iter().collect::>(), ) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index f5cfc4153b8d1..226f4cec2cd2c 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -170,7 +170,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::lang_items::LangItem; -use rustc_middle::mir::interpret::{AllocId, ConstValue}; +use rustc_middle::mir::interpret::{AllocId, ConstValue, ConstValueKind}; use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::mir::visit::Visitor as MirVisitor; @@ -1445,10 +1445,12 @@ fn collect_const_value<'tcx>( value: ConstValue<'tcx>, output: &mut MonoItems<'tcx>, ) { - match value { - ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => collect_alloc(tcx, ptr.provenance, output), - ConstValue::Indirect { alloc_id, .. } => collect_alloc(tcx, alloc_id, output), - ConstValue::Slice { data, start: _, end: _ } => { + match *value.kind() { + ConstValueKind::Scalar(Scalar::Ptr(ptr, _size)) => { + collect_alloc(tcx, ptr.provenance, output) + } + ConstValueKind::Indirect { alloc_id, .. } => collect_alloc(tcx, alloc_id, output), + ConstValueKind::Slice { data, start: _, end: _ } => { for &id in data.inner().provenance().ptrs().values() { collect_alloc(tcx, id, output); } diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 35e65c19be05b..07f137b43945e 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -1,4 +1,4 @@ -use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer}; +use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, ConstValueKind, Pointer}; use crate::{ rustc_smir::{Stable, Tables}, @@ -25,8 +25,8 @@ pub fn new_allocation<'tcx>( const_value: ConstValue<'tcx>, tables: &mut Tables<'tcx>, ) -> Allocation { - match const_value { - ConstValue::Scalar(scalar) => { + match *const_value.kind() { + ConstValueKind::Scalar(scalar) => { let size = scalar.size(); let align = tables .tcx @@ -39,12 +39,12 @@ pub fn new_allocation<'tcx>( .unwrap(); allocation.stable(tables) } - ConstValue::ZeroSized => { + ConstValueKind::ZeroSized => { let align = tables.tcx.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)).unwrap().align; new_empty_allocation(align.abi) } - ConstValue::Slice { data, start, end } => { + ConstValueKind::Slice { data, start, end } => { let alloc_id = tables.tcx.reserve_and_set_memory_alloc(data); let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start)); let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); @@ -72,7 +72,7 @@ pub fn new_allocation<'tcx>( .unwrap(); allocation.stable(tables) } - ConstValue::Indirect { alloc_id, offset } => { + ConstValueKind::Indirect { alloc_id, offset } => { let alloc = tables.tcx.global_alloc(alloc_id).unwrap_memory(); let ty_size = tables .tcx diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 7696ea0f44956..f68b4f6059c77 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -16,7 +16,6 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_metadata::rendered_const; use rustc_middle::mir; -use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use std::fmt::Write as _; @@ -280,10 +279,10 @@ pub(crate) fn print_evaluated_const( ) -> Option { tcx.const_eval_poly(def_id).ok().and_then(|val| { let ty = tcx.type_of(def_id).instantiate_identity(); - match (val, ty.kind()) { + match (val.try_to_scalar().is_some(), ty.kind()) { (_, &ty::Ref(..)) => None, - (ConstValue::Scalar(_), &ty::Adt(_, _)) => None, - (ConstValue::Scalar(_), _) => { + (true, &ty::Adt(_, _)) => None, + (true, _) => { let const_ = mir::ConstantKind::from_value(val, ty); Some(print_const_with_custom_print_scalar(tcx, const_, underscores_and_type)) } @@ -325,31 +324,36 @@ fn print_const_with_custom_print_scalar<'tcx>( ) -> String { // Use a slightly different format for integer types which always shows the actual value. // For all other types, fallback to the original `pretty_print_const`. - match (ct, ct.ty().kind()) { - (mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Uint(ui)) => { - if underscores_and_type { - format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str()) - } else { - int.to_string() + if let mir::ConstantKind::Val(ct, ty) = ct + && let Some(int) = ct.try_to_scalar() + { + match ty.kind() { + ty::Uint(ui) => { + return if underscores_and_type { + format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str()) + } else { + int.to_string() + } } - } - (mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Int(i)) => { - let ty = ct.ty(); - let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size; - let data = int.assert_bits(size); - let sign_extended_data = size.sign_extend(data) as i128; - if underscores_and_type { - format!( - "{}{}", - format_integer_with_underscore_sep(&sign_extended_data.to_string()), - i.name_str() - ) - } else { - sign_extended_data.to_string() + ty::Int(i) => { + let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size; + let data = int.assert_bits(size); + let sign_extended_data = size.sign_extend(data) as i128; + return if underscores_and_type { + format!( + "{}{}", + format_integer_with_underscore_sep(&sign_extended_data.to_string()), + i.name_str() + ) + } else { + sign_extended_data.to_string() + } } + _ => {} } - _ => ct.to_string(), } + + ct.to_string() } pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index fcb90c63a6fc6..36b701e0196a7 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -656,9 +656,10 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { } pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'tcx>) -> Option> { - use rustc_middle::mir::interpret::ConstValue; - match result { - mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() { + use rustc_middle::mir::interpret::ConstValueKind; + let mir::ConstantKind::Val(cv, ty) = result else { return None }; + match *cv.kind() { + ConstValueKind::Scalar(Scalar::Int(int)) => match ty.kind() { ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)), ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))), @@ -671,13 +672,13 @@ pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'t ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))), _ => None, }, - mir::ConstantKind::Val(cv, _) if matches!(result.ty().kind(), ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Str)) => { + _ if matches!(ty.kind(), ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Str)) => { let data = cv.try_get_slice_bytes_for_diagnostics(lcx.tcx)?; String::from_utf8(data.to_owned()).ok().map(Constant::Str) } - mir::ConstantKind::Val(ConstValue::Indirect { alloc_id, offset: _ }, _) => { + ConstValueKind::Indirect { alloc_id, offset: _ } => { let alloc = lcx.tcx.global_alloc(alloc_id).unwrap_memory(); - match result.ty().kind() { + match ty.kind() { ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), ty::Array(sub_type, len) => match sub_type.kind() { ty::Float(FloatTy::F32) => match len.try_to_target_usize(lcx.tcx) { diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index f0b4ede35fbc5..e3aa320f6790e 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -829,7 +829,7 @@ impl core::ops::Add for EnumValue { /// Attempts to read the given constant as though it were an enum value. #[expect(clippy::cast_possible_truncation, clippy::cast_possible_wrap)] pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option { - if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) { + if let Some(Scalar::Int(value)) = tcx.const_eval_poly(id).ok().and_then(ConstValue::try_to_scalar) { match tcx.type_of(id).instantiate_identity().kind() { ty::Int(_) => Some(EnumValue::Signed(match value.size().bytes() { 1 => i128::from(value.assert_bits(Size::from_bytes(1)) as u8 as i8), From a8c8dea73b3220a95f515eb400e4ab35d4255e21 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 17 Sep 2023 12:27:04 +0000 Subject: [PATCH 2/2] Remplace ConstValue::Slice by ConstValue::ScalarPair. --- .../rustc_codegen_cranelift/src/constant.rs | 181 +++++++++--------- compiler/rustc_codegen_ssa/src/mir/operand.rs | 21 +- .../src/const_eval/eval_queries.rs | 17 +- .../src/interpret/intrinsics.rs | 15 +- .../rustc_const_eval/src/interpret/operand.rs | 16 +- .../rustc_middle/src/mir/interpret/value.rs | 62 +++--- compiler/rustc_middle/src/mir/mod.rs | 6 + compiler/rustc_middle/src/mir/pretty.rs | 30 +-- compiler/rustc_middle/src/ty/context.rs | 8 +- .../rustc_middle/src/ty/structural_impls.rs | 2 +- .../src/build/expr/as_constant.rs | 23 +-- .../rustc_mir_transform/src/const_prop.rs | 16 +- compiler/rustc_monomorphize/src/collector.rs | 21 +- compiler/rustc_smir/src/rustc_smir/alloc.rs | 21 +- .../issue_101867.main.built.after.mir | 4 + ...e_live_dead_in_statics.XXX.built.after.mir | 4 + ..._allocation.main.ConstProp.after.32bit.mir | 32 ++-- ..._allocation.main.ConstProp.after.64bit.mir | 36 ++-- .../const_debuginfo.main.ConstDebugInfo.diff | 4 + ...hecked_add.main.ConstProp.panic-abort.diff | 4 - ...ecked_add.main.ConstProp.panic-unwind.diff | 4 - ...ification.hello.ConstProp.panic-abort.diff | 4 + ...fication.hello.ConstProp.panic-unwind.diff | 4 + .../indirect.main.ConstProp.panic-abort.diff | 4 - .../indirect.main.ConstProp.panic-unwind.diff | 4 - ...t_overflow.main.ConstProp.panic-abort.diff | 4 - ..._overflow.main.ConstProp.panic-unwind.diff | 4 - .../invalid_constant.main.ConstProp.diff | 6 +- .../invalid_constant.main.RemoveZsts.diff | 2 +- ...ssue_66971.main.ConstProp.panic-abort.diff | 8 - ...sue_66971.main.ConstProp.panic-unwind.diff | 8 - ...ssue_67019.main.ConstProp.panic-abort.diff | 12 -- ...sue_67019.main.ConstProp.panic-unwind.diff | 12 -- ...ble_variable_aggregate.main.ConstProp.diff | 8 - ...rop_assign.main.ConstProp.panic-abort.diff | 4 - ...op_assign.main.ConstProp.panic-unwind.diff | 4 - ...eturn_place.add.ConstProp.panic-abort.diff | 4 - ...turn_place.add.ConstProp.panic-unwind.diff | 4 - ...lace.add.PreCodegen.before.panic-abort.mir | 4 - ...ace.add.PreCodegen.before.panic-unwind.mir | 4 - ...ropagation.main.ConstProp.panic-abort.diff | 12 -- ...opagation.main.ConstProp.panic-unwind.diff | 12 -- ...ace_mention.main.DeadStoreElimination.diff | 8 + ...inline_diverging.g.Inline.panic-abort.diff | 4 + ...nline_diverging.g.Inline.panic-unwind.diff | 4 + ...implifyComparisonIntegral.panic-abort.diff | 6 + ...mplifyComparisonIntegral.panic-unwind.diff | 6 + ..._to_digit.PreCodegen.after.panic-abort.mir | 6 + ...to_digit.PreCodegen.after.panic-unwind.mir | 6 + .../nll/named_lifetimes_basic.use_x.nll.0.mir | 2 +- ...egion_subtyping_basic.main.nll.0.32bit.mir | 14 +- ...egion_subtyping_basic.main.nll.0.64bit.mir | 14 +- ...yCfg-elaborate-drops.after.panic-abort.mir | 4 + ...Cfg-elaborate-drops.after.panic-unwind.mir | 4 + ...main.ElaborateDrops.before.panic-abort.mir | 2 + ...ain.ElaborateDrops.before.panic-unwind.mir | 2 + ...able.main.ConstProp.32bit.panic-abort.diff | 4 - ...ble.main.ConstProp.32bit.panic-unwind.diff | 4 - ...able.main.ConstProp.64bit.panic-abort.diff | 4 - ...ble.main.ConstProp.64bit.panic-unwind.diff | 4 - ...mple_option_map.ezmap.PreCodegen.after.mir | 2 +- ...ated_loop.PreCodegen.after.panic-abort.mir | 2 +- ...ted_loop.PreCodegen.after.panic-unwind.mir | 2 +- ...ward_loop.PreCodegen.after.panic-abort.mir | 2 +- ...ard_loop.PreCodegen.after.panic-unwind.mir | 2 +- ...erse_loop.PreCodegen.after.panic-abort.mir | 2 +- ...rse_loop.PreCodegen.after.panic-unwind.mir | 2 +- ...ts.flat.ScalarReplacementOfAggregates.diff | 4 + ...after-uninhabited-enum-branching.after.mir | 12 ++ ...anching.main.UninhabitedEnumBranching.diff | 20 ++ ...after-uninhabited-enum-branching.after.mir | 16 ++ ...nching2.main.UninhabitedEnumBranching.diff | 32 ++++ tests/ui/consts/const-eval/issue-49296.stderr | 2 +- tests/ui/consts/offset_from_ub.stderr | 6 +- 74 files changed, 417 insertions(+), 442 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 9def350aef4e1..650c5f0c3a78d 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -103,6 +103,91 @@ pub(crate) fn codegen_constant_operand<'tcx>( codegen_const_value(fx, const_val, ty) } +pub(crate) fn codegen_const_scalar<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, + scalar: Scalar, + layout: TyAndLayout<'tcx>, +) -> CValue<'tcx> { + match scalar { + Scalar::Int(int) => { + if fx.clif_type(layout.ty).is_some() { + return CValue::const_val(fx, layout, int); + } else { + let raw_val = int.to_bits(int.size()).unwrap(); + let val = match int.size().bytes() { + 1 => fx.bcx.ins().iconst(types::I8, raw_val as i64), + 2 => fx.bcx.ins().iconst(types::I16, raw_val as i64), + 4 => fx.bcx.ins().iconst(types::I32, raw_val as i64), + 8 => fx.bcx.ins().iconst(types::I64, raw_val as i64), + 16 => { + let lsb = fx.bcx.ins().iconst(types::I64, raw_val as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (raw_val >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + _ => unreachable!(), + }; + + // FIXME avoid this extra copy to the stack and directly write to the final + // destination + let place = CPlace::new_stack_slot(fx, layout); + place.to_ptr().store(fx, val, MemFlags::trusted()); + place.to_cvalue(fx) + } + } + Scalar::Ptr(ptr, _size) => { + let (alloc_id, offset) = ptr.into_parts(); // we know the `offset` is relative + let base_addr = match fx.tcx.global_alloc(alloc_id) { + GlobalAlloc::Memory(alloc) => { + let data_id = data_id_for_alloc_id( + &mut fx.constants_cx, + fx.module, + alloc_id, + alloc.inner().mutability, + ); + let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", alloc_id)); + } + fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + } + GlobalAlloc::Function(instance) => { + let func_id = crate::abi::import_function(fx.tcx, fx.module, instance); + let local_func_id = fx.module.declare_func_in_func(func_id, &mut fx.bcx.func); + fx.bcx.ins().func_addr(fx.pointer_type, local_func_id) + } + GlobalAlloc::VTable(ty, trait_ref) => { + let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref)); + let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); + // FIXME: factor this common code with the `Memory` arm into a function? + let data_id = data_id_for_alloc_id( + &mut fx.constants_cx, + fx.module, + alloc_id, + alloc.inner().mutability, + ); + let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + } + GlobalAlloc::Static(def_id) => { + assert!(fx.tcx.is_static(def_id)); + let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false); + let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", def_id)); + } + fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + } + }; + let val = if offset.bytes() != 0 { + fx.bcx.ins().iadd_imm(base_addr, i64::try_from(offset.bytes()).unwrap()) + } else { + base_addr + }; + CValue::by_val(val, layout) + } + } +} + pub(crate) fn codegen_const_value<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, const_val: ConstValue<'tcx>, @@ -117,105 +202,13 @@ pub(crate) fn codegen_const_value<'tcx>( match *const_val.kind() { ConstValueKind::ZeroSized => unreachable!(), // we already handled ZST above - ConstValueKind::Scalar(x) => match x { - Scalar::Int(int) => { - if fx.clif_type(layout.ty).is_some() { - return CValue::const_val(fx, layout, int); - } else { - let raw_val = int.to_bits(int.size()).unwrap(); - let val = match int.size().bytes() { - 1 => fx.bcx.ins().iconst(types::I8, raw_val as i64), - 2 => fx.bcx.ins().iconst(types::I16, raw_val as i64), - 4 => fx.bcx.ins().iconst(types::I32, raw_val as i64), - 8 => fx.bcx.ins().iconst(types::I64, raw_val as i64), - 16 => { - let lsb = fx.bcx.ins().iconst(types::I64, raw_val as u64 as i64); - let msb = - fx.bcx.ins().iconst(types::I64, (raw_val >> 64) as u64 as i64); - fx.bcx.ins().iconcat(lsb, msb) - } - _ => unreachable!(), - }; - - // FIXME avoid this extra copy to the stack and directly write to the final - // destination - let place = CPlace::new_stack_slot(fx, layout); - place.to_ptr().store(fx, val, MemFlags::trusted()); - place.to_cvalue(fx) - } - } - Scalar::Ptr(ptr, _size) => { - let (alloc_id, offset) = ptr.into_parts(); // we know the `offset` is relative - let base_addr = match fx.tcx.global_alloc(alloc_id) { - GlobalAlloc::Memory(alloc) => { - let data_id = data_id_for_alloc_id( - &mut fx.constants_cx, - fx.module, - alloc_id, - alloc.inner().mutability, - ); - let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - if fx.clif_comments.enabled() { - fx.add_comment(local_data_id, format!("{:?}", alloc_id)); - } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) - } - GlobalAlloc::Function(instance) => { - let func_id = crate::abi::import_function(fx.tcx, fx.module, instance); - let local_func_id = - fx.module.declare_func_in_func(func_id, &mut fx.bcx.func); - fx.bcx.ins().func_addr(fx.pointer_type, local_func_id) - } - GlobalAlloc::VTable(ty, trait_ref) => { - let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref)); - let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); - // FIXME: factor this common code with the `Memory` arm into a function? - let data_id = data_id_for_alloc_id( - &mut fx.constants_cx, - fx.module, - alloc_id, - alloc.inner().mutability, - ); - let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) - } - GlobalAlloc::Static(def_id) => { - assert!(fx.tcx.is_static(def_id)); - let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false); - let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - if fx.clif_comments.enabled() { - fx.add_comment(local_data_id, format!("{:?}", def_id)); - } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) - } - }; - let val = if offset.bytes() != 0 { - fx.bcx.ins().iadd_imm(base_addr, i64::try_from(offset.bytes()).unwrap()) - } else { - base_addr - }; - CValue::by_val(val, layout) - } - }, + ConstValueKind::Scalar(x) => codegen_const_scalar(fx, x, layout), ConstValueKind::Indirect { alloc_id, offset } => CValue::by_ref( pointer_for_allocation(fx, alloc_id) .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()), layout, ), - ConstValueKind::Slice { data, start, end } => { - let alloc_id = fx.tcx.reserve_and_set_memory_alloc(data); - let ptr = pointer_for_allocation(fx, alloc_id) - .offset_i64(fx, i64::try_from(start).unwrap()) - .get_addr(fx); - let len = fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(end.checked_sub(start).unwrap()).unwrap()); - CValue::by_val_pair(ptr, len, layout) - } + ConstValueKind::ScalarPair(..) => todo!(), } } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 7d44956b771da..eacd325aff25e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -7,7 +7,7 @@ use crate::traits::*; use crate::MemFlags; use rustc_middle::mir; -use rustc_middle::mir::interpret::{alloc_range, ConstValue, ConstValueKind, Pointer, Scalar}; +use rustc_middle::mir::interpret::{alloc_range, ConstValue, ConstValueKind}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; use rustc_target::abi::{self, Abi, Align, Size}; @@ -100,23 +100,20 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { OperandValue::Immediate(llval) } ConstValueKind::ZeroSized => return OperandRef::zero_sized(layout), - ConstValueKind::Slice { data, start, end } => { - let Abi::ScalarPair(a_scalar, _) = layout.abi else { - bug!("from_const: invalid ScalarPair layout: {:#?}", layout); + ConstValueKind::ScalarPair(a, b) => { + let Abi::ScalarPair(a_scalar, b_scalar) = layout.abi else { + bug!("from_const: invalid ByVal layout: {:#?}", layout); }; - let a = Scalar::from_pointer( - Pointer::new( - bx.tcx().reserve_and_set_memory_alloc(data), - Size::from_bytes(start), - ), - &bx.tcx(), - ); let a_llval = bx.scalar_to_backend( a, a_scalar, bx.scalar_pair_element_backend_type(layout, 0, true), ); - let b_llval = bx.const_usize((end - start) as u64); + let b_llval = bx.scalar_to_backend( + b, + b_scalar, + bx.scalar_pair_element_backend_type(layout, 1, true), + ); OperandValue::Pair(a_llval, b_llval) } ConstValueKind::Indirect { alloc_id, offset } => { diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index baf3e6e4d429c..c8defb7500705 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -151,22 +151,7 @@ pub(super) fn op_to_const<'tcx>( // see comment on `let force_as_immediate` above Right(imm) => match *imm { Immediate::Scalar(x) => ConstValue::from_scalar(tcx, x), - Immediate::ScalarPair(a, b) => { - debug!("ScalarPair(a: {:?}, b: {:?})", a, b); - // FIXME: assert that this has an appropriate type. - // Currently we actually get here for non-[u8] slices during valtree construction! - let msg = "`op_to_const` on an immediate scalar pair must only be used on slice references to actually allocated memory"; - // We know `offset` is relative to the allocation, so we can use `into_parts`. - // We use `ConstValueKind::Slice` so that we don't have to generate an allocation for - // `ConstValueKind::Indirect` here. - let (alloc_id, offset) = a.to_pointer(ecx).expect(msg).into_parts(); - let alloc_id = alloc_id.expect(msg); - let data = ecx.tcx.global_alloc(alloc_id).unwrap_memory(); - let start = offset.bytes_usize(); - let len = b.to_target_usize(ecx).expect(msg); - let len: usize = len.try_into().unwrap(); - ConstValue::from_slice(tcx, data, start, start + len) - } + Immediate::ScalarPair(a, b) => ConstValue::from_pair(tcx, a, b), Immediate::Uninit => bug!("`Uninit` is not a valid value for {}", op.layout.ty), }, } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 4a67c55d2f6dc..f745afc38e832 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -5,9 +5,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::mir::{ self, - interpret::{ - Allocation, ConstAllocation, ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar, - }, + interpret::{AllocId, ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar}, BinOp, NonDivergingIntrinsic, }; use rustc_middle::ty; @@ -44,10 +42,11 @@ fn numeric_intrinsic(name: Symbol, bits: u128, kind: Primitive) -> Scalar< } /// Directly returns an `Allocation` containing an absolute path representation of the given type. -pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> { +pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (AllocId, usize) { let path = crate::util::type_name(tcx, ty); - let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes()); - tcx.mk_const_alloc(alloc) + let bytes = path.into_bytes(); + let len = bytes.len(); + (tcx.allocate_bytes(bytes), len) } /// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated @@ -63,8 +62,8 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( Ok(match name { sym::type_name => { ensure_monomorphic_enough(tcx, tp_ty)?; - let alloc = alloc_type_name(tcx, tp_ty); - ConstValue::from_slice(tcx, alloc, 0, alloc.inner().len()) + let (alloc, len) = alloc_type_name(tcx, tp_ty); + ConstValue::from_slice(tcx, Pointer::from(alloc), len) } sym::needs_drop => { ensure_monomorphic_enough(tcx, tp_ty)?; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 0b902448068ab..6688083e65ce0 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -771,20 +771,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Operand::Indirect(MemPlace::from_ptr(ptr.into())) } ConstValueKind::Scalar(x) => Operand::Immediate(adjust_scalar(x)?.into()), - ConstValueKind::ZeroSized => Operand::Immediate(Immediate::Uninit), - ConstValueKind::Slice { data, start, end } => { - // We rely on mutability being set correctly in `data` to prevent writes - // where none should happen. - let ptr = Pointer::new( - self.tcx.reserve_and_set_memory_alloc(data), - Size::from_bytes(start), // offset: `start` - ); - Operand::Immediate(Immediate::new_slice( - Scalar::from_pointer(self.global_base_pointer(ptr)?, &*self.tcx), - u64::try_from(end.checked_sub(start).unwrap()).unwrap(), // len: `end - start` - self, - )) + ConstValueKind::ScalarPair(a, b) => { + Operand::Immediate(Immediate::ScalarPair(adjust_scalar(a)?, adjust_scalar(b)?)) } + ConstValueKind::ZeroSized => Operand::Immediate(Immediate::Uninit), }; Ok(OpTy { op, layout, align: Some(layout.align.abi) }) } diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index f52bd47e8ceee..d3ced90916fbe 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -10,14 +10,10 @@ use rustc_data_structures::intern::Interned; use rustc_macros::HashStable; use rustc_target::abi::{HasDataLayout, Size}; -use crate::{ - mir::interpret::alloc_range, - ty::{ParamEnv, ScalarInt, Ty, TyCtxt}, -}; +use crate::ty::{ParamEnv, ScalarInt, Ty, TyCtxt}; use super::{ - AllocId, ConstAllocation, InterpResult, Pointer, PointerArithmetic, Provenance, - ScalarSizeMismatch, + alloc_range, AllocId, InterpResult, Pointer, PointerArithmetic, Provenance, ScalarSizeMismatch, }; /// Represents the result of const evaluation via the `eval_to_allocation` query. @@ -31,28 +27,26 @@ pub struct ConstAlloc<'tcx> { #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] #[derive(HashStable)] -pub struct ConstValue<'tcx>(pub(crate) Interned<'tcx, ConstValueKind<'tcx>>); +pub struct ConstValue<'tcx>(pub(crate) Interned<'tcx, ConstValueKind>); /// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for /// array length computations, enum discriminants and the pattern matching logic. #[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash)] -#[derive(HashStable, Lift)] -pub enum ConstValueKind<'tcx> { +#[derive(HashStable)] +pub enum ConstValueKind { /// Used for types with `layout::abi::Scalar` ABI. /// /// Not using the enum `Value` to encode that this must not be `Uninit`. Scalar(Scalar), + /// Used for types with `layout::abi::ScalarPair` ABI. + /// + /// Not using the enum `Value` to encode that this must not be `Uninit`. + ScalarPair(Scalar, Scalar), + /// Only for ZSTs. ZeroSized, - /// Used for `&[u8]` and `&str`. - /// - /// This is worth an optimized representation since Rust has literals of these types. - /// Not having to indirect those through an `AllocId` (or two, if we used `Indirect`) has shown - /// measurable performance improvements on stress tests. - Slice { data: ConstAllocation<'tcx>, start: usize, end: usize }, - /// A value not representable by the other variants; needs to be stored in-memory. /// /// Must *not* be used for scalars or ZST, but having `&str` or other slices in this variant is fine. @@ -74,12 +68,12 @@ static_assert_size!(ConstValue<'_>, 8); impl<'tcx> ConstValue<'tcx> { #[inline] - pub fn new(tcx: TyCtxt<'tcx>, kind: ConstValueKind<'tcx>) -> ConstValue<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>, kind: ConstValueKind) -> ConstValue<'tcx> { tcx.intern_const_value(kind) } #[inline] - pub fn kind(self) -> &'tcx ConstValueKind<'tcx> { + pub fn kind(self) -> &'tcx ConstValueKind { self.0.0 } @@ -87,7 +81,7 @@ impl<'tcx> ConstValue<'tcx> { pub fn try_to_scalar(self) -> Option> { match self.kind() { ConstValueKind::Indirect { .. } - | ConstValueKind::Slice { .. } + | ConstValueKind::ScalarPair(..) | ConstValueKind::ZeroSized => None, ConstValueKind::Scalar(val) => Some(*val), } @@ -155,13 +149,17 @@ impl<'tcx> ConstValue<'tcx> { } #[inline] - pub fn from_slice( - tcx: TyCtxt<'tcx>, - data: ConstAllocation<'tcx>, - start: usize, - end: usize, - ) -> Self { - Self::new(tcx, ConstValueKind::Slice { data, start, end }) + pub fn from_pair(tcx: TyCtxt<'tcx>, a: Scalar, b: Scalar) -> Self { + Self::new(tcx, ConstValueKind::ScalarPair(a, b)) + } + + #[inline] + pub fn from_slice(tcx: TyCtxt<'tcx>, pointer: Pointer, length: usize) -> Self { + Self::from_pair( + tcx, + Scalar::from_pointer(pointer, &tcx), + Scalar::from_target_usize(length as u64, &tcx), + ) } #[inline] @@ -173,10 +171,13 @@ impl<'tcx> ConstValue<'tcx> { /// Must only be called on constants of type `&str` or `&[u8]`! pub fn try_get_slice_bytes_for_diagnostics(self, tcx: TyCtxt<'tcx>) -> Option<&'tcx [u8]> { let (data, start, end) = match self.kind() { - ConstValueKind::Scalar(_) | ConstValueKind::ZeroSized => { - bug!("`try_get_slice_bytes` on non-slice constant") + &ConstValueKind::ScalarPair(Scalar::Ptr(pointer, _), Scalar::Int(length)) => { + let (alloc_id, start) = pointer.into_parts(); + let alloc = tcx.global_alloc(alloc_id).unwrap_memory(); + let start = start.bytes_usize(); + let length = length.try_to_target_usize(tcx).unwrap() as usize; + (alloc, start, start + length) } - &ConstValueKind::Slice { data, start, end } => (data, start, end), &ConstValueKind::Indirect { alloc_id, offset } => { // The reference itself is stored behind an indirection. // Load the reference, and then load the actual slice contents. @@ -212,6 +213,9 @@ impl<'tcx> ConstValue<'tcx> { let data = tcx.global_alloc(inner_alloc_id?).unwrap_memory(); (data, offset.bytes_usize(), offset.bytes_usize() + len) } + _ => { + bug!("`try_get_slice_bytes` on non-slice constant") + } }; // This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index a3e4d58aa0ffa..d85f431de2e2c 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2507,6 +2507,12 @@ impl<'tcx> ConstantKind<'tcx> { Self::Val(val, ty) } + #[inline] + pub fn from_scalar_pair(tcx: TyCtxt<'tcx>, a: Scalar, b: Scalar, ty: Ty<'tcx>) -> Self { + let val = ConstValue::from_pair(tcx, a, b); + Self::Val(val, ty) + } + /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly /// converted to a constant, everything else becomes `Unevaluated`. #[instrument(skip(tcx), level = "debug", ret)] diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 288a146622633..2c3374feb2258 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -7,7 +7,6 @@ use std::path::{Path, PathBuf}; use super::graphviz::write_mir_fn_graphviz; use super::spanview::write_mir_fn_spanview; -use either::Either; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_index::Idx; @@ -459,7 +458,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { let fmt_val = |val: &ConstValue<'tcx>| match val.kind() { ConstValueKind::ZeroSized => "".to_string(), ConstValueKind::Scalar(s) => format!("Scalar({s:?})"), - ConstValueKind::Slice { .. } => "Slice(..)".to_string(), + ConstValueKind::ScalarPair(a, b) => format!("ScalarPair({a:?}, {b:?})"), ConstValueKind::Indirect { .. } => "ByRef(..)".to_string(), }; @@ -698,23 +697,26 @@ pub fn write_allocations<'tcx>( alloc.inner().provenance().ptrs().values().map(|id| *id) } - fn alloc_ids_from_const_val(val: ConstValue<'_>) -> impl Iterator + '_ { - match val.kind() { - ConstValueKind::Scalar(interpret::Scalar::Ptr(ptr, _)) => { - Either::Left(std::iter::once(ptr.provenance)) - } - ConstValueKind::Scalar(interpret::Scalar::Int { .. }) => { - Either::Right(std::iter::empty()) + fn alloc_ids_from_scalar(val: interpret::Scalar) -> Option { + match val { + interpret::Scalar::Ptr(ptr, _) => Some(ptr.provenance), + interpret::Scalar::Int(..) => None, + } + } + + fn alloc_ids_from_const_val<'tcx>(val: ConstValue<'tcx>) -> impl Iterator { + match *val.kind() { + ConstValueKind::ZeroSized => None.into_iter().chain(None.into_iter()), + ConstValueKind::Scalar(scalar) => { + alloc_ids_from_scalar(scalar).into_iter().chain(None.into_iter()) } - ConstValueKind::ZeroSized => Either::Right(std::iter::empty()), - ConstValueKind::Slice { .. } => { - // `u8`/`str` slices, shouldn't contain pointers that we want to print. - Either::Right(std::iter::empty()) + ConstValueKind::ScalarPair(a, b) => { + alloc_ids_from_scalar(a).into_iter().chain(alloc_ids_from_scalar(b).into_iter()) } ConstValueKind::Indirect { alloc_id, .. } => { // FIXME: we don't actually want to print all of these, since some are printed nicely directly as values inline in MIR. // Really we'd want `pretty_print_const_value` to decide which allocations to print, instead of having a separate visitor. - Either::Left(std::iter::once(*alloc_id)) + Some(alloc_id).into_iter().chain(None.into_iter()) } } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 702cdbfab1ce7..b922d5edb283b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -70,7 +70,7 @@ use rustc_type_ir::WithCachedTypeInfo; use rustc_type_ir::{CollectAndApply, Interner, TypeFlags}; use std::any::Any; -use std::borrow::Borrow; +use std::borrow::{Borrow, Cow}; use std::cmp::Ordering; use std::fmt; use std::hash::{Hash, Hasher}; @@ -156,7 +156,7 @@ pub struct CtxtInterners<'tcx> { external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>, predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>, fields: InternedSet<'tcx, List>, - const_value: InternedSet<'tcx, ConstValueKind<'tcx>>, + const_value: InternedSet<'tcx, ConstValueKind>, } impl<'tcx> CtxtInterners<'tcx> { @@ -645,7 +645,7 @@ impl<'tcx> TyCtxt<'tcx> { } /// Allocates a read-only byte or string literal for `mir::interpret`. - pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId { + pub fn allocate_bytes<'a>(self, bytes: impl Into>) -> interpret::AllocId { // Create an allocation that just contains these bytes. let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes); let alloc = self.mk_const_alloc(alloc); @@ -1499,7 +1499,7 @@ direct_interners! { region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>, const_: intern_const(ConstData<'tcx>): Const -> Const<'tcx>, const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, - const_value: pub(crate) intern_const_value(ConstValueKind<'tcx>): ConstValue -> ConstValue<'tcx>, + const_value: pub(crate) intern_const_value(ConstValueKind): ConstValue -> ConstValue<'tcx>, layout: pub mk_layout(LayoutS): Layout -> Layout<'tcx>, adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>, external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>): diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index afadcfca459bb..08d7408be88d2 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -627,7 +627,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { impl<'a, 'tcx> Lift<'tcx> for interpret::ConstValue<'a> { type Lifted = interpret::ConstValue<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(*self.kind()).map(|kind| interpret::ConstValue::new(tcx, kind)) + Some(interpret::ConstValue::new(tcx, *self.kind())) } } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index b0e1bf4fd1528..f6eb1fd98ff59 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -3,9 +3,7 @@ use crate::build::{parse_float_into_constval, Builder}; use rustc_ast as ast; use rustc_middle::mir; -use rustc_middle::mir::interpret::{ - Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, -}; +use rustc_middle::mir::interpret::{ConstValue, LitToConstError, LitToConstInput, Scalar}; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::{ @@ -130,27 +128,24 @@ fn lit_to_mir_constant<'tcx>( let value = match (lit, &ty.kind()) { (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { - let s = s.as_str(); - let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); - let allocation = tcx.mk_const_alloc(allocation); - ConstValue::from_slice(tcx, allocation, 0, s.len()) + let s = s.as_str().as_bytes(); + let allocation = tcx.allocate_bytes(s); + ConstValue::from_slice(tcx, allocation.into(), s.len()) } (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(_)) => { - let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); - let allocation = tcx.mk_const_alloc(allocation); - ConstValue::from_slice(tcx, allocation, 0, data.len()) + let allocation = tcx.allocate_bytes(data as &[u8]); + ConstValue::from_slice(tcx, allocation.into(), data.len()) } (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { - let id = tcx.allocate_bytes(data); + let id = tcx.allocate_bytes(&**data); ConstValue::from_pointer(tcx, id.into()) } (ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) => { - let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); - let allocation = tcx.mk_const_alloc(allocation); - ConstValue::from_slice(tcx, allocation, 0, data.len()) + let allocation = tcx.allocate_bytes(data as &[u8]); + ConstValue::from_slice(tcx, allocation.into(), data.len()) } (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { ConstValue::from_scalar(tcx, Scalar::from_uint(*n, Size::from_bytes(1))) diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index d9cddba607031..71e32a6835ded 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -22,8 +22,8 @@ use rustc_target::spec::abi::Abi as CallAbi; use crate::dataflow_const_prop::Patch; use crate::MirPass; use rustc_const_eval::interpret::{ - self, compile_time_machine, AllocId, ConstAllocation, ConstValue, FnArg, Frame, ImmTy, - Immediate, InterpCx, InterpResult, MemoryKind, OpTy, PlaceTy, Pointer, Scalar, StackPopCleanup, + self, compile_time_machine, AllocId, ConstAllocation, FnArg, Frame, ImmTy, Immediate, InterpCx, + InterpResult, MemoryKind, OpTy, PlaceTy, Pointer, Scalar, StackPopCleanup, }; /// The maximum number of bytes that we'll allocate space for a local or the return value. @@ -544,17 +544,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Some(ConstantKind::from_scalar(self.tcx, scalar, value.layout.ty)) } Immediate::ScalarPair(l, r) if l.try_to_int().is_ok() && r.try_to_int().is_ok() => { - let alloc_id = self - .ecx - .intern_with_temp_alloc(value.layout, |ecx, dest| { - ecx.write_immediate(*imm, dest) - }) - .ok()?; - - Some(ConstantKind::Val( - ConstValue::from_memory(self.tcx, alloc_id, Size::ZERO), - value.layout.ty, - )) + Some(ConstantKind::from_scalar_pair(self.tcx, l, r, value.layout.ty)) } // Scalars or scalar pairs that contain undef values are assumed to not have // successfully evaluated and are thus not propagated. diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 226f4cec2cd2c..7ce64a18221b4 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1439,6 +1439,14 @@ fn collect_used_items<'tcx>( .visit_body(&body); } +#[instrument(skip(tcx, output), level = "debug")] +fn collect_scalar<'tcx>(tcx: TyCtxt<'tcx>, value: Scalar, output: &mut MonoItems<'tcx>) { + match value { + Scalar::Ptr(ptr, _size) => collect_alloc(tcx, ptr.provenance, output), + Scalar::Int(_) => {} + } +} + #[instrument(skip(tcx, output), level = "debug")] fn collect_const_value<'tcx>( tcx: TyCtxt<'tcx>, @@ -1446,15 +1454,12 @@ fn collect_const_value<'tcx>( output: &mut MonoItems<'tcx>, ) { match *value.kind() { - ConstValueKind::Scalar(Scalar::Ptr(ptr, _size)) => { - collect_alloc(tcx, ptr.provenance, output) + ConstValueKind::Scalar(s) => collect_scalar(tcx, s, output), + ConstValueKind::ScalarPair(a, b) => { + collect_scalar(tcx, a, output); + collect_scalar(tcx, b, output); } + ConstValueKind::ZeroSized => {} ConstValueKind::Indirect { alloc_id, .. } => collect_alloc(tcx, alloc_id, output), - ConstValueKind::Slice { data, start: _, end: _ } => { - for &id in data.inner().provenance().ptrs().values() { - collect_alloc(tcx, id, output); - } - } - _ => {} } } diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 07f137b43945e..63c2e1c1d43cc 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -1,4 +1,4 @@ -use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, ConstValueKind, Pointer}; +use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, ConstValueKind}; use crate::{ rustc_smir::{Stable, Tables}, @@ -44,30 +44,19 @@ pub fn new_allocation<'tcx>( tables.tcx.layout_of(rustc_middle::ty::ParamEnv::empty().and(ty)).unwrap().align; new_empty_allocation(align.abi) } - ConstValueKind::Slice { data, start, end } => { - let alloc_id = tables.tcx.reserve_and_set_memory_alloc(data); - let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start)); - let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); - let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize( - (end - start) as u64, - &tables.tcx, - ); + ConstValueKind::ScalarPair(a, b) => { let layout = tables.tcx.layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(ty)).unwrap(); let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi); allocation - .write_scalar( - &tables.tcx, - alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size), - scalar_ptr, - ) + .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, a.size()), a) .unwrap(); allocation .write_scalar( &tables.tcx, - alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()), - scalar_len, + alloc_range(tables.tcx.data_layout.pointer_size, b.size()), + b, ) .unwrap(); allocation.stable(tables) diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir index 915c5ef112c39..21cfa0290e0bc 100644 --- a/tests/mir-opt/building/issue_101867.main.built.after.mir +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -67,3 +67,7 @@ fn main() -> () { resume; } } + +alloc1 (size: 14, align: 1) { + 65 78 70 6c 69 63 69 74 20 70 61 6e 69 63 │ explicit panic +} diff --git a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir index 683f63065f76b..45c5f4e36038a 100644 --- a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir +++ b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir @@ -198,3 +198,7 @@ static XXX: &Foo = { return; } } + +alloc1 (size: 2, align: 1) { + 68 69 │ hi +} diff --git a/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir b/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir index 8c8e69595950d..16ca5f95cc494 100644 --- a/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir +++ b/tests/mir-opt/const_allocation.main.ConstProp.after.32bit.mir @@ -8,7 +8,7 @@ fn main() -> () { bb0: { StorageLive(_1); StorageLive(_2); - _2 = const {alloc1: &&[(Option, &[&str])]}; + _2 = const {alloc6: &&[(Option, &[&str])]}; _1 = (*_2); StorageDead(_2); StorageDead(_1); @@ -17,43 +17,43 @@ fn main() -> () { } } -alloc1 (static: FOO, size: 8, align: 4) { +alloc6 (static: FOO, size: 8, align: 4) { ╾─alloc19─╼ 03 00 00 00 │ ╾──╼.... } alloc19 (size: 48, align: 4) { - 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc6──╼ 00 00 00 00 │ ....░░░░╾──╼.... - 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc10─╼ 02 00 00 00 │ ....░░░░╾──╼.... - 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc15─╼ 03 00 00 00 │ ....*...╾──╼.... + 0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc11─╼ 00 00 00 00 │ ....░░░░╾──╼.... + 0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc14─╼ 02 00 00 00 │ ....░░░░╾──╼.... + 0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc17─╼ 03 00 00 00 │ ....*...╾──╼.... } -alloc6 (size: 0, align: 4) {} +alloc11 (size: 0, align: 4) {} -alloc10 (size: 16, align: 4) { - ╾─alloc9──╼ 03 00 00 00 ╾─alloc11─╼ 03 00 00 00 │ ╾──╼....╾──╼.... +alloc14 (size: 16, align: 4) { + ╾─alloc1──╼ 03 00 00 00 ╾─alloc2──╼ 03 00 00 00 │ ╾──╼....╾──╼.... } -alloc9 (size: 3, align: 1) { +alloc1 (size: 3, align: 1) { 66 6f 6f │ foo } -alloc11 (size: 3, align: 1) { +alloc2 (size: 3, align: 1) { 62 61 72 │ bar } -alloc15 (size: 24, align: 4) { - 0x00 │ ╾─alloc14─╼ 03 00 00 00 ╾─alloc16─╼ 03 00 00 00 │ ╾──╼....╾──╼.... - 0x10 │ ╾─alloc17─╼ 04 00 00 00 │ ╾──╼.... +alloc17 (size: 24, align: 4) { + 0x00 │ ╾─alloc3──╼ 03 00 00 00 ╾─alloc4──╼ 03 00 00 00 │ ╾──╼....╾──╼.... + 0x10 │ ╾─alloc5──╼ 04 00 00 00 │ ╾──╼.... } -alloc14 (size: 3, align: 1) { +alloc3 (size: 3, align: 1) { 6d 65 68 │ meh } -alloc16 (size: 3, align: 1) { +alloc4 (size: 3, align: 1) { 6d 6f 70 │ mop } -alloc17 (size: 4, align: 1) { +alloc5 (size: 4, align: 1) { 6d c3 b6 70 │ m..p } diff --git a/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir b/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir index e22547032967f..83e2938489035 100644 --- a/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir +++ b/tests/mir-opt/const_allocation.main.ConstProp.after.64bit.mir @@ -8,7 +8,7 @@ fn main() -> () { bb0: { StorageLive(_1); StorageLive(_2); - _2 = const {alloc1: &&[(Option, &[&str])]}; + _2 = const {alloc6: &&[(Option, &[&str])]}; _1 = (*_2); StorageDead(_2); StorageDead(_1); @@ -17,47 +17,47 @@ fn main() -> () { } } -alloc1 (static: FOO, size: 16, align: 8) { +alloc6 (static: FOO, size: 16, align: 8) { ╾───────alloc19───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ } alloc19 (size: 72, align: 8) { - 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc6────────╼ │ ....░░░░╾──────╼ + 0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc11───────╼ │ ....░░░░╾──────╼ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░ - 0x20 │ ╾───────alloc10───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc15───────╼ │ ....*...╾──────╼ + 0x20 │ ╾───────alloc14───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc17───────╼ │ ....*...╾──────╼ 0x40 │ 03 00 00 00 00 00 00 00 │ ........ } -alloc6 (size: 0, align: 8) {} +alloc11 (size: 0, align: 8) {} -alloc10 (size: 32, align: 8) { - 0x00 │ ╾───────alloc9────────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x10 │ ╾───────alloc11───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ +alloc14 (size: 32, align: 8) { + 0x00 │ ╾───────alloc1────────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x10 │ ╾───────alloc2────────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ } -alloc9 (size: 3, align: 1) { +alloc1 (size: 3, align: 1) { 66 6f 6f │ foo } -alloc11 (size: 3, align: 1) { +alloc2 (size: 3, align: 1) { 62 61 72 │ bar } -alloc15 (size: 48, align: 8) { - 0x00 │ ╾───────alloc14───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x10 │ ╾───────alloc16───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ - 0x20 │ ╾───────alloc17───────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ +alloc17 (size: 48, align: 8) { + 0x00 │ ╾───────alloc3────────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x10 │ ╾───────alloc4────────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........ + 0x20 │ ╾───────alloc5────────╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........ } -alloc14 (size: 3, align: 1) { +alloc3 (size: 3, align: 1) { 6d 65 68 │ meh } -alloc16 (size: 3, align: 1) { +alloc4 (size: 3, align: 1) { 6d 6f 70 │ mop } -alloc17 (size: 4, align: 1) { +alloc5 (size: 4, align: 1) { 6d c3 b6 70 │ m..p } diff --git a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff index ed47baa67daba..e4f490ea8180a 100644 --- a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff +++ b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff @@ -97,3 +97,7 @@ } } + alloc1 (size: 13, align: 1) { + 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 │ hello, world! + } + diff --git a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff index c2fd7f65f5eea..6daef87dd2c73 100644 --- a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff @@ -24,9 +24,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc3 (size: 8, align: 4) { -+ 02 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff index 21a31f9aba31e..125407bf285a3 100644 --- a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff @@ -24,9 +24,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc3 (size: 8, align: 4) { -+ 02 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-abort.diff index ba2e89f0a7445..032f7c1cbbc37 100644 --- a/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-abort.diff @@ -24,3 +24,7 @@ } } + alloc1 (size: 14, align: 1) { + 65 78 70 6c 69 63 69 74 20 70 61 6e 69 63 │ explicit panic + } + diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff index e0a610f60a795..9638ba20662ab 100644 --- a/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.panic-unwind.diff @@ -24,3 +24,7 @@ } } + alloc1 (size: 14, align: 1) { + 65 78 70 6c 69 63 69 74 20 70 61 6e 69 63 │ explicit panic + } + diff --git a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff index c0efc87302925..ca0ce2888cd6e 100644 --- a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff @@ -29,9 +29,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc3 (size: 2, align: 1) { -+ 03 00 │ .. } diff --git a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff index 2aee6f164aebb..d63fb9255a326 100644 --- a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff @@ -29,9 +29,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc3 (size: 2, align: 1) { -+ 03 00 │ .. } diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff index 7ba51ccdbf6d4..51e17cf690aca 100644 --- a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff @@ -35,9 +35,5 @@ _0 = const (); return; } -+ } -+ -+ alloc3 (size: 2, align: 1) { -+ 00 01 │ .. } diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff index 545b7f22f6e0c..5ef201497fbcd 100644 --- a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff @@ -35,9 +35,5 @@ _0 = const (); return; } -+ } -+ -+ alloc3 (size: 2, align: 1) { -+ 00 01 │ .. } diff --git a/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff index 10e978a683acc..c008c2c253de6 100644 --- a/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/invalid_constant.main.ConstProp.diff @@ -16,7 +16,7 @@ debug _invalid_tag => _3; let _6: [Empty; 1]; scope 5 { - debug _enum_without_variants => const [ZeroSized: Empty]; + debug _enum_without_variants => const [ConstValue(ZeroSized): Empty]; let _9: main::Str<"���">; scope 7 { debug _non_utf8_str => const Str::<"���">; @@ -44,8 +44,8 @@ _5 = InvalidTag { int: const 4_u32 }; - _4 = (_5.1: E); - _3 = [move _4]; -+ _4 = const Scalar(0x00000004): E; -+ _3 = [const Scalar(0x00000004): E]; ++ _4 = const ConstValue(Scalar(0x00000004)): E; ++ _3 = [const ConstValue(Scalar(0x00000004)): E]; StorageDead(_4); StorageDead(_5); nop; diff --git a/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff b/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff index 455c2375eff9a..bece171bf11b7 100644 --- a/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff +++ b/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff @@ -17,7 +17,7 @@ let _6: [Empty; 1]; scope 5 { - debug _enum_without_variants => _6; -+ debug _enum_without_variants => const [ZeroSized: Empty]; ++ debug _enum_without_variants => const [ConstValue(ZeroSized): Empty]; let _9: main::Str<"���">; scope 7 { - debug _non_utf8_str => _9; diff --git a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff index 18341ba7db923..170c019782df3 100644 --- a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff @@ -18,13 +18,5 @@ StorageDead(_2); return; } -+ } -+ -+ alloc8 (size: 2, align: 1) { -+ 00 00 │ .. -+ } -+ -+ alloc7 (size: 2, align: 1) { -+ 00 00 │ .. } diff --git a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff index 50763c10f0c22..64227dfd78c2c 100644 --- a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff @@ -18,13 +18,5 @@ StorageDead(_2); return; } -+ } -+ -+ alloc8 (size: 2, align: 1) { -+ 00 00 │ .. -+ } -+ -+ alloc7 (size: 2, align: 1) { -+ 00 00 │ .. } diff --git a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff index 015180db896b1..e1f3f37b37074 100644 --- a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff @@ -23,17 +23,5 @@ StorageDead(_2); return; } -+ } -+ -+ alloc12 (size: 2, align: 1) { -+ 01 02 │ .. -+ } -+ -+ alloc11 (size: 2, align: 1) { -+ 01 02 │ .. -+ } -+ -+ alloc8 (size: 2, align: 1) { -+ 01 02 │ .. } diff --git a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff index 8e41705c1af21..aaa376a95cf66 100644 --- a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff @@ -23,17 +23,5 @@ StorageDead(_2); return; } -+ } -+ -+ alloc12 (size: 2, align: 1) { -+ 01 02 │ .. -+ } -+ -+ alloc11 (size: 2, align: 1) { -+ 01 02 │ .. -+ } -+ -+ alloc8 (size: 2, align: 1) { -+ 01 02 │ .. } diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff index 56a127ae31ebe..0f118c7f59fdf 100644 --- a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff @@ -25,13 +25,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc7 (size: 8, align: 4) { -+ 2a 00 00 00 63 00 00 00 │ *...c... -+ } -+ -+ alloc5 (size: 8, align: 4) { -+ 2a 00 00 00 2b 00 00 00 │ *...+... } diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff index a1b433716c846..a85dcf9c7edf7 100644 --- a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff @@ -46,9 +46,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc7 (size: 8, align: 4) { -+ 01 00 00 00 02 00 00 00 │ ........ } diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff index 2dc514194bc11..15ef0fa4dfff7 100644 --- a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff @@ -46,9 +46,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc7 (size: 8, align: 4) { -+ 01 00 00 00 02 00 00 00 │ ........ } diff --git a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff index 6c9de4764658d..f3b30e0dcde46 100644 --- a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff @@ -17,9 +17,5 @@ + _0 = const 4_u32; return; } -+ } -+ -+ alloc5 (size: 8, align: 4) { -+ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff index 0f079278c43d9..79f85fcef110e 100644 --- a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff @@ -17,9 +17,5 @@ + _0 = const 4_u32; return; } -+ } -+ -+ alloc5 (size: 8, align: 4) { -+ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir index c2488f3944cbb..c8f3f641a6d75 100644 --- a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir +++ b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir @@ -14,7 +14,3 @@ fn add() -> u32 { return; } } - -alloc5 (size: 8, align: 4) { - 04 00 00 00 00 __ __ __ │ .....░░░ -} diff --git a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir index fa0b9c77eaf61..9a06469746361 100644 --- a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir +++ b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir @@ -14,7 +14,3 @@ fn add() -> u32 { return; } } - -alloc5 (size: 8, align: 4) { - 04 00 00 00 00 __ __ __ │ .....░░░ -} diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff index 988ef7dd2254a..9e705695ac0cd 100644 --- a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff @@ -29,17 +29,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc9 (size: 8, align: 4) { -+ 01 00 00 00 02 00 00 00 │ ........ -+ } -+ -+ alloc8 (size: 8, align: 4) { -+ 01 00 00 00 02 00 00 00 │ ........ -+ } -+ -+ alloc6 (size: 8, align: 4) { -+ 01 00 00 00 02 00 00 00 │ ........ } diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff index 298446197203d..882dd97cc16b8 100644 --- a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff @@ -29,17 +29,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc9 (size: 8, align: 4) { -+ 01 00 00 00 02 00 00 00 │ ........ -+ } -+ -+ alloc8 (size: 8, align: 4) { -+ 01 00 00 00 02 00 00 00 │ ........ -+ } -+ -+ alloc6 (size: 8, align: 4) { -+ 01 00 00 00 02 00 00 00 │ ........ } diff --git a/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff index 2130518771a58..c0d43017d0b86 100644 --- a/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff +++ b/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff @@ -17,3 +17,11 @@ } } + alloc2 (size: 5, align: 1) { + 57 6f 72 6c 64 │ World + } + + alloc1 (size: 5, align: 1) { + 48 65 6c 6c 6f │ Hello + } + diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff index d675695eb1047..e26bd20f252af 100644 --- a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff @@ -38,5 +38,9 @@ + StorageLive(_7); + _7 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; } ++ } ++ ++ alloc1 (size: 14, align: 1) { ++ 65 78 70 6c 69 63 69 74 20 70 61 6e 69 63 │ explicit panic } diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff index 1142616115fb7..629af001b18a6 100644 --- a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff @@ -38,5 +38,9 @@ + StorageLive(_7); + _7 = begin_panic::<&str>(const "explicit panic") -> unwind continue; } ++ } ++ ++ alloc1 (size: 14, align: 1) { ++ 65 78 70 6c 69 63 69 74 20 70 61 6e 69 63 │ explicit panic } diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff index 9d8f272abea3a..cb78acb57970d 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -58,3 +58,9 @@ } } + alloc1 (size: 40, align: 1) { + 0x00 │ 69 6e 74 65 72 6e 61 6c 20 65 72 72 6f 72 3a 20 │ internal error: + 0x10 │ 65 6e 74 65 72 65 64 20 75 6e 72 65 61 63 68 61 │ entered unreacha + 0x20 │ 62 6c 65 20 63 6f 64 65 │ ble code + } + diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff index 738b0b1b3e5ac..d83d56b91179c 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff @@ -58,3 +58,9 @@ } } + alloc1 (size: 40, align: 1) { + 0x00 │ 69 6e 74 65 72 6e 61 6c 20 65 72 72 6f 72 3a 20 │ internal error: + 0x10 │ 65 6e 74 65 72 65 64 20 75 6e 72 65 61 63 68 61 │ entered unreacha + 0x20 │ 62 6c 65 20 63 6f 64 65 │ ble code + } + diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir index f8c85941813cc..64b7f5ea10b06 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir @@ -69,3 +69,9 @@ fn num_to_digit(_1: char) -> u32 { return; } } + +alloc4 (size: 43, align: 1) { + 0x00 │ 63 61 6c 6c 65 64 20 60 4f 70 74 69 6f 6e 3a 3a │ called `Option:: + 0x10 │ 75 6e 77 72 61 70 28 29 60 20 6f 6e 20 61 20 60 │ unwrap()` on a ` + 0x20 │ 4e 6f 6e 65 60 20 76 61 6c 75 65 │ None` value +} diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir index df7392edc50c2..f3eb2dbbf0a30 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir @@ -69,3 +69,9 @@ fn num_to_digit(_1: char) -> u32 { return; } } + +alloc4 (size: 43, align: 1) { + 0x00 │ 63 61 6c 6c 65 64 20 60 4f 70 74 69 6f 6e 3a 3a │ called `Option:: + 0x10 │ 75 6e 77 72 61 70 28 29 60 20 6f 6e 20 61 20 60 │ unwrap()` on a ` + 0x20 │ 4e 6f 6e 65 60 20 76 61 6c 75 65 │ None` value +} diff --git a/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir index 1d6b830739019..5f3b0449149e6 100644 --- a/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir +++ b/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir @@ -41,7 +41,7 @@ fn use_x(_1: &'?5 mut i32, _2: &'?6 u32, _3: &'?7 u32, _4: &'?8 u32) -> bool { let mut _0: bool; bb0: { - _0 = const ConstValue(Scalar(0x01): bool); + _0 = const ConstValue(ConstValue(Scalar(0x01)): bool); return; } } diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index c581d0f8471f9..a814cdb785be7 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -44,11 +44,11 @@ fn main() -> () { bb0: { StorageLive(_1); - _1 = [const ConstValue(Scalar(0x00000001): usize), const ConstValue(Scalar(0x00000002): usize), const ConstValue(Scalar(0x00000003): usize)]; + _1 = [const ConstValue(ConstValue(Scalar(0x00000001)): usize), const ConstValue(ConstValue(Scalar(0x00000002)): usize), const ConstValue(ConstValue(Scalar(0x00000003)): usize)]; FakeRead(ForLet(None), _1); StorageLive(_2); StorageLive(_3); - _3 = const ConstValue(Scalar(0x00000000): usize); + _3 = const ConstValue(ConstValue(Scalar(0x00000000)): usize); _4 = Len(_1); _5 = Lt(_3, _4); assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; @@ -61,7 +61,7 @@ fn main() -> () { _6 = _2; FakeRead(ForLet(None), _6); StorageLive(_7); - _7 = const ConstValue(Scalar(0x01): bool); + _7 = const ConstValue(ConstValue(Scalar(0x01)): bool); switchInt(move _7) -> [0: bb4, otherwise: bb2]; } @@ -69,24 +69,24 @@ fn main() -> () { StorageLive(_8); StorageLive(_9); _9 = (*_6); - _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; + _8 = ConstValue(ConstValue(ZeroSized): fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; } bb3: { StorageDead(_9); StorageDead(_8); - _0 = const ConstValue(ZeroSized: ()); + _0 = const ConstValue(ConstValue(ZeroSized): ()); goto -> bb6; } bb4: { StorageLive(_10); - _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; + _10 = ConstValue(ConstValue(ZeroSized): fn(usize) -> bool {use_x})(const ConstValue(ConstValue(Scalar(0x00000016)): usize)) -> [return: bb5, unwind: bb7]; } bb5: { StorageDead(_10); - _0 = const ConstValue(ZeroSized: ()); + _0 = const ConstValue(ConstValue(ZeroSized): ()); goto -> bb6; } diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 48243e34d0825..1afd3f8b81248 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -44,11 +44,11 @@ fn main() -> () { bb0: { StorageLive(_1); - _1 = [const ConstValue(Scalar(0x0000000000000001): usize), const ConstValue(Scalar(0x0000000000000002): usize), const ConstValue(Scalar(0x0000000000000003): usize)]; + _1 = [const ConstValue(ConstValue(Scalar(0x0000000000000001)): usize), const ConstValue(ConstValue(Scalar(0x0000000000000002)): usize), const ConstValue(ConstValue(Scalar(0x0000000000000003)): usize)]; FakeRead(ForLet(None), _1); StorageLive(_2); StorageLive(_3); - _3 = const ConstValue(Scalar(0x0000000000000000): usize); + _3 = const ConstValue(ConstValue(Scalar(0x0000000000000000)): usize); _4 = Len(_1); _5 = Lt(_3, _4); assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; @@ -61,7 +61,7 @@ fn main() -> () { _6 = _2; FakeRead(ForLet(None), _6); StorageLive(_7); - _7 = const ConstValue(Scalar(0x01): bool); + _7 = const ConstValue(ConstValue(Scalar(0x01)): bool); switchInt(move _7) -> [0: bb4, otherwise: bb2]; } @@ -69,24 +69,24 @@ fn main() -> () { StorageLive(_8); StorageLive(_9); _9 = (*_6); - _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; + _8 = ConstValue(ConstValue(ZeroSized): fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; } bb3: { StorageDead(_9); StorageDead(_8); - _0 = const ConstValue(ZeroSized: ()); + _0 = const ConstValue(ConstValue(ZeroSized): ()); goto -> bb6; } bb4: { StorageLive(_10); - _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7]; + _10 = ConstValue(ConstValue(ZeroSized): fn(usize) -> bool {use_x})(const ConstValue(ConstValue(Scalar(0x0000000000000016)): usize)) -> [return: bb5, unwind: bb7]; } bb5: { StorageDead(_10); - _0 = const ConstValue(ZeroSized: ()); + _0 = const ConstValue(ConstValue(ZeroSized): ()); goto -> bb6; } diff --git a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir index 086955236466f..9c39de2e3d26b 100644 --- a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir +++ b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-abort.mir @@ -36,3 +36,7 @@ fn unwrap(_1: Option) -> T { return; } } + +alloc1 (size: 14, align: 1) { + 65 78 70 6c 69 63 69 74 20 70 61 6e 69 63 │ explicit panic +} diff --git a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir index 6276d85484618..c36b5bec984fd 100644 --- a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir +++ b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.panic-unwind.mir @@ -41,3 +41,7 @@ fn unwrap(_1: Option) -> T { resume; } } + +alloc1 (size: 14, align: 1) { + 65 78 70 6c 69 63 69 74 20 70 61 6e 69 63 │ explicit panic +} diff --git a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir index 99a7a6b6154d5..8aacb99372fb2 100644 --- a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir +++ b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir @@ -38,3 +38,5 @@ fn main() -> () { resume; } } + +alloc1 (size: 0, align: 1) {} diff --git a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir index 7364b329e123a..277d3be0f4278 100644 --- a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir +++ b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir @@ -38,3 +38,5 @@ fn main() -> () { resume; } } + +alloc1 (size: 0, align: 1) {} diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff index 681e9666e0fb0..2c607b4c055fa 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff @@ -55,9 +55,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc5 (size: 8, align: 4) { -+ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff index db16b8d82d2cb..b6929f3f93c6c 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff @@ -55,9 +55,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc5 (size: 8, align: 4) { -+ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff index 681e9666e0fb0..2c607b4c055fa 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff @@ -55,9 +55,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc5 (size: 8, align: 4) { -+ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff index db16b8d82d2cb..b6929f3f93c6c 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff @@ -55,9 +55,5 @@ StorageDead(_1); return; } -+ } -+ -+ alloc5 (size: 8, align: 4) { -+ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir index 312565e45c331..b4401a733eb5c 100644 --- a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir @@ -5,7 +5,7 @@ fn ezmap(_1: Option) -> Option { let mut _0: std::option::Option; scope 1 (inlined map::) { debug slf => _1; - debug f => const ZeroSized: [closure@$DIR/simple_option_map.rs:17:12: 17:15]; + debug f => const ConstValue(ZeroSized): [closure@$DIR/simple_option_map.rs:17:12: 17:15]; let mut _2: isize; let _3: i32; let mut _4: i32; diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index 89009864c3293..7a980b2b976cb 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -138,7 +138,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { StorageDead(_9); StorageLive(_12); _12 = _7; - _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ConstValue(ZeroSized): PhantomData<&T> }; StorageDead(_12); StorageDead(_11); StorageDead(_7); diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 3d76bab7ce70e..bebf0d38a6466 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -138,7 +138,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { StorageDead(_9); StorageLive(_12); _12 = _7; - _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ConstValue(ZeroSized): PhantomData<&T> }; StorageDead(_12); StorageDead(_11); StorageDead(_7); diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 146fa57a0b188..315e2063e31db 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -128,7 +128,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageDead(_9); StorageLive(_12); _12 = _7; - _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ConstValue(ZeroSized): PhantomData<&T> }; StorageDead(_12); StorageDead(_11); StorageDead(_7); diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index e8586cec981c3..ab383b3ccbefc 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -128,7 +128,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageDead(_9); StorageLive(_12); _12 = _7; - _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ConstValue(ZeroSized): PhantomData<&T> }; StorageDead(_12); StorageDead(_11); StorageDead(_7); diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index 549cb4f46a0e2..de41ac9fe2815 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -140,7 +140,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageDead(_9); StorageLive(_12); _12 = _7; - _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ConstValue(ZeroSized): PhantomData<&T> }; StorageDead(_12); StorageDead(_11); StorageDead(_7); diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 3cdc49f6056bd..c3088f4caa96e 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -140,7 +140,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageDead(_9); StorageLive(_12); _12 = _7; - _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> }; + _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ConstValue(ZeroSized): PhantomData<&T> }; StorageDead(_12); StorageDead(_11); StorageDead(_7); diff --git a/tests/mir-opt/sroa/structs.flat.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/structs.flat.ScalarReplacementOfAggregates.diff index a84048365a4ba..a32a6ce4a92ab 100644 --- a/tests/mir-opt/sroa/structs.flat.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/structs.flat.ScalarReplacementOfAggregates.diff @@ -75,3 +75,7 @@ } } + alloc1 (size: 1, align: 1) { + 61 │ a + } + diff --git a/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index 474f43104bb43..9df9ed084ee78 100644 --- a/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -58,3 +58,15 @@ fn main() -> () { return; } } + +alloc7 (size: 1, align: 1) { + 45 │ E +} + +alloc6 (size: 1, align: 1) { + 44 │ D +} + +alloc5 (size: 1, align: 1) { + 43 │ C +} diff --git a/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff index 9db95abec34c8..d70ecbd716f0a 100644 --- a/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff +++ b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff @@ -78,3 +78,23 @@ } } + alloc7 (size: 1, align: 1) { + 45 │ E + } + + alloc6 (size: 1, align: 1) { + 44 │ D + } + + alloc5 (size: 1, align: 1) { + 43 │ C + } + + alloc4 (size: 8, align: 1) { + 42 28 45 6d 70 74 79 29 │ B(Empty) + } + + alloc3 (size: 8, align: 1) { + 41 28 45 6d 70 74 79 29 │ A(Empty) + } + diff --git a/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index 9c0c5d18917ae..43155af862f02 100644 --- a/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -83,3 +83,19 @@ fn main() -> () { return; } } + +alloc8 (size: 1, align: 1) { + 44 │ D +} + +alloc7 (size: 1, align: 1) { + 43 │ C +} + +alloc4 (size: 1, align: 1) { + 44 │ D +} + +alloc3 (size: 1, align: 1) { + 43 │ C +} diff --git a/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff index 12ce6505af948..f1945d6c1cfab 100644 --- a/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff +++ b/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff @@ -113,3 +113,35 @@ } } + alloc8 (size: 1, align: 1) { + 44 │ D + } + + alloc7 (size: 1, align: 1) { + 43 │ C + } + + alloc6 (size: 8, align: 1) { + 42 28 45 6d 70 74 79 29 │ B(Empty) + } + + alloc5 (size: 8, align: 1) { + 41 28 45 6d 70 74 79 29 │ A(Empty) + } + + alloc4 (size: 1, align: 1) { + 44 │ D + } + + alloc3 (size: 1, align: 1) { + 43 │ C + } + + alloc2 (size: 8, align: 1) { + 42 28 45 6d 70 74 79 29 │ B(Empty) + } + + alloc1 (size: 8, align: 1) { + 41 28 45 6d 70 74 79 29 │ A(Empty) + } + diff --git a/tests/ui/consts/const-eval/issue-49296.stderr b/tests/ui/consts/const-eval/issue-49296.stderr index 45ba0ea183ec1..6ae5d7473156d 100644 --- a/tests/ui/consts/const-eval/issue-49296.stderr +++ b/tests/ui/consts/const-eval/issue-49296.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/issue-49296.rs:9:16 | LL | const X: u64 = *wat(42); - | ^^^^^^^^ dereferencing pointer failed: alloc3 has been freed, so this pointer is dangling + | ^^^^^^^^ dereferencing pointer failed: alloc5 has been freed, so this pointer is dangling error: aborting due to previous error diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr index 97ff6efdd791c..fdc93c28e13a6 100644 --- a/tests/ui/consts/offset_from_ub.stderr +++ b/tests/ui/consts/offset_from_ub.stderr @@ -39,19 +39,19 @@ error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:53:14 | LL | unsafe { ptr_offset_from(end_ptr, start_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: alloc17 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: alloc18 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:62:14 | LL | unsafe { ptr_offset_from(start_ptr, end_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: alloc20 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: alloc21 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:70:14 | LL | unsafe { ptr_offset_from(end_ptr, end_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: alloc23 has size 4, so pointer at offset 10 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: alloc24 has size 4, so pointer at offset 10 is out-of-bounds error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:79:14