move ConstValue into mir
this way we have mir::ConstValue and ty::ValTree as reasonably parallel
This commit is contained in:
parent
be8f5f6e7f
commit
5a0a1ff0cd
@ -2,7 +2,8 @@
|
||||
|
||||
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, GlobalAlloc, Scalar};
|
||||
use rustc_middle::mir::interpret::{read_target_uint, AllocId, GlobalAlloc, Scalar};
|
||||
use rustc_middle::mir::ConstValue;
|
||||
|
||||
use cranelift_module::*;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::mir::interpret::ConstValue;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
|
||||
@ -194,10 +194,10 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
pub fn asm_const_to_str<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
sp: Span,
|
||||
const_value: ConstValue<'tcx>,
|
||||
const_value: mir::ConstValue<'tcx>,
|
||||
ty_and_layout: TyAndLayout<'tcx>,
|
||||
) -> String {
|
||||
let ConstValue::Scalar(scalar) = const_value else {
|
||||
let mir::ConstValue::Scalar(scalar) = const_value else {
|
||||
span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value)
|
||||
};
|
||||
let value = scalar.assert_bits(ty_and_layout.size);
|
||||
|
@ -2,7 +2,7 @@
|
||||
use crate::mir::operand::OperandRef;
|
||||
use crate::traits::*;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::layout::HasTyCtxt;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_target::abi::Abi;
|
||||
@ -20,7 +20,7 @@ pub fn eval_mir_constant_to_operand(
|
||||
OperandRef::from_const(bx, val, ty)
|
||||
}
|
||||
|
||||
pub fn eval_mir_constant(&self, constant: &mir::Constant<'tcx>) -> ConstValue<'tcx> {
|
||||
pub fn eval_mir_constant(&self, constant: &mir::Constant<'tcx>) -> mir::ConstValue<'tcx> {
|
||||
self.monomorphize(constant.literal)
|
||||
.eval(self.cx.tcx(), ty::ParamEnv::reveal_all(), Some(constant.span))
|
||||
.expect("erroneous constant not captured by required_consts")
|
||||
|
@ -6,8 +6,8 @@
|
||||
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, Pointer, Scalar};
|
||||
use rustc_middle::mir::{self, ConstValue};
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_target::abi::{self, Abi, Align, Size};
|
||||
@ -86,7 +86,7 @@ pub fn zero_sized(layout: TyAndLayout<'tcx>) -> OperandRef<'tcx, V> {
|
||||
|
||||
pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
|
||||
bx: &mut Bx,
|
||||
val: ConstValue<'tcx>,
|
||||
val: mir::ConstValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Self {
|
||||
let layout = bx.layout_of(ty);
|
||||
|
@ -4,9 +4,9 @@
|
||||
use either::{Left, Right};
|
||||
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, InterpErrorInfo};
|
||||
use rustc_middle::mir::pretty::write_allocation_bytes;
|
||||
use rustc_middle::mir::{self, ConstAlloc, ConstValue};
|
||||
use rustc_middle::traits::Reveal;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
@ -18,9 +18,8 @@
|
||||
use crate::errors;
|
||||
use crate::interpret::eval_nullary_intrinsic;
|
||||
use crate::interpret::{
|
||||
intern_const_alloc_recursive, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId, Immediate,
|
||||
InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking,
|
||||
StackPopCleanup,
|
||||
intern_const_alloc_recursive, CtfeValidationMode, GlobalId, Immediate, InternKind, InterpCx,
|
||||
InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup,
|
||||
};
|
||||
|
||||
// Returns a pointer to where the result lives
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Not in interpret to make sure we do not use private implementation details
|
||||
|
||||
use crate::errors::MaxNumNodesInConstErr;
|
||||
use crate::interpret::{intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, Scalar};
|
||||
use crate::interpret::{intern_const_alloc_recursive, InternKind, InterpCx, Scalar};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
@ -22,7 +22,7 @@
|
||||
pub(crate) fn const_caller_location(
|
||||
tcx: TyCtxt<'_>,
|
||||
(file, line, col): (Symbol, u32, u32),
|
||||
) -> ConstValue<'_> {
|
||||
) -> mir::ConstValue<'_> {
|
||||
trace!("const_caller_location: {}:{}:{}", file, line, col);
|
||||
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), CanAccessStatics::No);
|
||||
|
||||
@ -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))
|
||||
mir::ConstValue::Scalar(Scalar::from_maybe_pointer(loc_place.ptr(), &tcx))
|
||||
}
|
||||
|
||||
// We forbid type-level constants that contain more than `VALTREE_MAX_NODES` nodes.
|
||||
@ -87,7 +87,7 @@ pub(crate) fn eval_to_valtree<'tcx>(
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
pub(crate) fn try_destructure_mir_constant_for_diagnostics<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
val: ConstValue<'tcx>,
|
||||
val: mir::ConstValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<mir::DestructuredConstant<'tcx>> {
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
|
@ -4,9 +4,10 @@
|
||||
use crate::const_eval::CanAccessStatics;
|
||||
use crate::interpret::MPlaceTy;
|
||||
use crate::interpret::{
|
||||
intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta,
|
||||
MemoryKind, PlaceTy, Projectable, Scalar,
|
||||
intern_const_alloc_recursive, ImmTy, Immediate, InternKind, MemPlaceMeta, MemoryKind, PlaceTy,
|
||||
Projectable, Scalar,
|
||||
};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_span::source_map::DUMMY_SP;
|
||||
@ -206,7 +207,7 @@ pub fn valtree_to_const_value<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
|
||||
valtree: ty::ValTree<'tcx>,
|
||||
) -> ConstValue<'tcx> {
|
||||
) -> mir::ConstValue<'tcx> {
|
||||
// Basic idea: We directly construct `Scalar` values from trivial `ValTree`s
|
||||
// (those for constants with type bool, int, uint, float or char).
|
||||
// For all other types we create an `MPlace` and fill that by walking
|
||||
@ -219,10 +220,10 @@ pub fn valtree_to_const_value<'tcx>(
|
||||
match ty.kind() {
|
||||
ty::FnDef(..) => {
|
||||
assert!(valtree.unwrap_branch().is_empty());
|
||||
ConstValue::ZeroSized
|
||||
mir::ConstValue::ZeroSized
|
||||
}
|
||||
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) => mir::ConstValue::Scalar(Scalar::Int(scalar_int)),
|
||||
ty::ValTree::Branch(_) => bug!(
|
||||
"ValTrees for Bool, Int, Uint, Float or Char should have the form ValTree::Leaf"
|
||||
),
|
||||
@ -237,7 +238,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 mir::ConstValue::ZeroSized;
|
||||
}
|
||||
if layout.abi.is_scalar()
|
||||
&& (matches!(ty.kind(), ty::Tuple(_))
|
||||
|
@ -5,10 +5,8 @@
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::mir::{
|
||||
self,
|
||||
interpret::{
|
||||
Allocation, ConstAllocation, ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar,
|
||||
},
|
||||
BinOp, NonDivergingIntrinsic,
|
||||
interpret::{Allocation, ConstAllocation, GlobalId, InterpResult, PointerArithmetic, Scalar},
|
||||
BinOp, ConstValue, NonDivergingIntrinsic,
|
||||
};
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement};
|
||||
|
@ -13,9 +13,8 @@
|
||||
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size};
|
||||
|
||||
use super::{
|
||||
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, ConstValue, Frame, InterpCx,
|
||||
InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, Projectable,
|
||||
Provenance, Scalar,
|
||||
alloc_range, from_known_layout, mir_assign_valid_types, AllocId, Frame, InterpCx, InterpResult,
|
||||
MPlaceTy, Machine, MemPlace, MemPlaceMeta, PlaceTy, Pointer, Projectable, Provenance, Scalar,
|
||||
};
|
||||
|
||||
/// An `Immediate` represents a single immediate self-contained Rust value.
|
||||
@ -702,7 +701,7 @@ pub fn eval_operand(
|
||||
|
||||
pub(crate) fn const_val_to_op(
|
||||
&self,
|
||||
val_val: ConstValue<'tcx>,
|
||||
val_val: mir::ConstValue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
|
||||
@ -715,15 +714,15 @@ pub(crate) fn const_val_to_op(
|
||||
};
|
||||
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 } => {
|
||||
mir::ConstValue::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 } => {
|
||||
mir::ConstValue::Scalar(x) => Operand::Immediate(adjust_scalar(x)?.into()),
|
||||
mir::ConstValue::ZeroSized => Operand::Immediate(Immediate::Uninit),
|
||||
mir::ConstValue::Slice { data, start, end } => {
|
||||
// We rely on mutability being set correctly in `data` to prevent writes
|
||||
// where none should happen.
|
||||
let ptr = Pointer::new(
|
||||
|
@ -9,16 +9,15 @@
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_index::IndexSlice;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::PointerArithmetic;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_target::abi::{Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_VARIANT};
|
||||
|
||||
use super::{
|
||||
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
|
||||
ConstAlloc, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand,
|
||||
Pointer, Projectable, Provenance, Readable, Scalar,
|
||||
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, ImmTy,
|
||||
Immediate, InterpCx, InterpResult, Machine, MemoryKind, OpTy, Operand, Pointer,
|
||||
PointerArithmetic, Projectable, Provenance, Readable, Scalar,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
|
||||
@ -1037,7 +1036,7 @@ pub fn write_aggregate(
|
||||
|
||||
pub fn raw_const_to_mplace(
|
||||
&self,
|
||||
raw: ConstAlloc<'tcx>,
|
||||
raw: mir::ConstAlloc<'tcx>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
|
||||
// This must be an allocation in `tcx`
|
||||
let _ = self.tcx.global_alloc(raw.alloc_id);
|
||||
|
@ -4,14 +4,169 @@
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::{self as hir};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::Size;
|
||||
use rustc_target::abi::{HasDataLayout, Size};
|
||||
|
||||
use crate::mir::interpret::{ConstValue, ErrorHandled, GlobalAlloc, Scalar};
|
||||
use crate::mir::{interpret, pretty_print_const_value, Promoted};
|
||||
use crate::mir::interpret::{
|
||||
alloc_range, AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar,
|
||||
};
|
||||
use crate::mir::{pretty_print_const_value, Promoted};
|
||||
use crate::ty::{self, print::pretty_print_const, List, Ty, TyCtxt};
|
||||
use crate::ty::{GenericArgs, GenericArgsRef};
|
||||
use crate::ty::{ScalarInt, UserTypeAnnotationIndex};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// Evaluated Constants
|
||||
|
||||
/// Represents the result of const evaluation via the `eval_to_allocation` query.
|
||||
/// Not to be confused with `ConstAllocation`, which directly refers to the underlying data!
|
||||
/// Here we indirect via an `AllocId`.
|
||||
#[derive(Copy, Clone, HashStable, TyEncodable, TyDecodable, Debug, Hash, Eq, PartialEq)]
|
||||
pub struct ConstAlloc<'tcx> {
|
||||
/// The value lives here, at offset 0, and that allocation definitely is an `AllocKind::Memory`
|
||||
/// (so you can use `AllocMap::unwrap_memory`).
|
||||
pub alloc_id: AllocId,
|
||||
pub ty: Ty<'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> {
|
||||
/// Used for types with `layout::abi::Scalar` ABI.
|
||||
///
|
||||
/// Not using the enum `Value` to encode that this must not be `Uninit`.
|
||||
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.
|
||||
Indirect {
|
||||
/// The backing memory of the value. May contain more memory than needed for just the value
|
||||
/// if this points into some other larger ConstValue.
|
||||
///
|
||||
/// We use an `AllocId` here instead of a `ConstAllocation<'tcx>` to make sure that when a
|
||||
/// raw constant (which is basically just an `AllocId`) is turned into a `ConstValue` and
|
||||
/// back, we can preserve the original `AllocId`.
|
||||
alloc_id: AllocId,
|
||||
/// Offset into `alloc`
|
||||
offset: Size,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(ConstValue<'_>, 32);
|
||||
|
||||
impl<'tcx> ConstValue<'tcx> {
|
||||
#[inline]
|
||||
pub fn try_to_scalar(&self) -> Option<Scalar<AllocId>> {
|
||||
match *self {
|
||||
ConstValue::Indirect { .. } | ConstValue::Slice { .. } | ConstValue::ZeroSized => None,
|
||||
ConstValue::Scalar(val) => Some(val),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_to_scalar_int(&self) -> Option<ScalarInt> {
|
||||
self.try_to_scalar()?.try_to_int().ok()
|
||||
}
|
||||
|
||||
pub fn try_to_bits(&self, size: Size) -> Option<u128> {
|
||||
self.try_to_scalar_int()?.to_bits(size).ok()
|
||||
}
|
||||
|
||||
pub fn try_to_bool(&self) -> Option<bool> {
|
||||
self.try_to_scalar_int()?.try_into().ok()
|
||||
}
|
||||
|
||||
pub fn try_to_target_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
|
||||
self.try_to_scalar_int()?.try_to_target_usize(tcx).ok()
|
||||
}
|
||||
|
||||
pub fn try_to_bits_for_ty(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<u128> {
|
||||
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
|
||||
self.try_to_bits(size)
|
||||
}
|
||||
|
||||
pub fn from_bool(b: bool) -> Self {
|
||||
ConstValue::Scalar(Scalar::from_bool(b))
|
||||
}
|
||||
|
||||
pub fn from_u64(i: u64) -> Self {
|
||||
ConstValue::Scalar(Scalar::from_u64(i))
|
||||
}
|
||||
|
||||
pub fn from_u128(i: u128) -> Self {
|
||||
ConstValue::Scalar(Scalar::from_u128(i))
|
||||
}
|
||||
|
||||
pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self {
|
||||
ConstValue::Scalar(Scalar::from_target_usize(i, cx))
|
||||
}
|
||||
|
||||
/// 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 => {
|
||||
bug!("`try_get_slice_bytes` on non-slice constant")
|
||||
}
|
||||
&ConstValue::Slice { data, start, end } => (data, start, end),
|
||||
&ConstValue::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();
|
||||
let ptr_size = tcx.data_layout.pointer_size;
|
||||
if a.size() < offset + 2 * ptr_size {
|
||||
// (partially) dangling reference
|
||||
return None;
|
||||
}
|
||||
// Read the wide pointer components.
|
||||
let ptr = a
|
||||
.read_scalar(
|
||||
&tcx,
|
||||
alloc_range(offset, ptr_size),
|
||||
/* read_provenance */ true,
|
||||
)
|
||||
.ok()?;
|
||||
let ptr = ptr.to_pointer(&tcx).ok()?;
|
||||
let len = a
|
||||
.read_scalar(
|
||||
&tcx,
|
||||
alloc_range(offset + ptr_size, ptr_size),
|
||||
/* read_provenance */ false,
|
||||
)
|
||||
.ok()?;
|
||||
let len = len.to_target_usize(&tcx).ok()?;
|
||||
let len: usize = len.try_into().ok()?;
|
||||
if len == 0 {
|
||||
return Some(&[]);
|
||||
}
|
||||
// Non-empty slice, must have memory. We know this is a relative pointer.
|
||||
let (inner_alloc_id, offset) = ptr.into_parts();
|
||||
let data = tcx.global_alloc(inner_alloc_id?).unwrap_memory();
|
||||
(data, offset.bytes_usize(), offset.bytes_usize() + len)
|
||||
}
|
||||
};
|
||||
|
||||
// This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`.
|
||||
Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end))
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
///
|
||||
@ -49,7 +204,7 @@ pub enum ConstantKind<'tcx> {
|
||||
|
||||
/// This constant cannot go back into the type system, as it represents
|
||||
/// something the type system cannot handle (e.g. pointers).
|
||||
Val(interpret::ConstValue<'tcx>, Ty<'tcx>),
|
||||
Val(ConstValue<'tcx>, Ty<'tcx>),
|
||||
}
|
||||
|
||||
impl<'tcx> Constant<'tcx> {
|
||||
@ -116,7 +271,7 @@ pub fn eval(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
span: Option<Span>,
|
||||
) -> Result<interpret::ConstValue<'tcx>, ErrorHandled> {
|
||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||
match self {
|
||||
ConstantKind::Ty(c) => {
|
||||
// We want to consistently have a "clean" value for type system constants (i.e., no
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar};
|
||||
use super::{AllocId, AllocRange, Pointer, Scalar};
|
||||
|
||||
use crate::error;
|
||||
use crate::mir::interpret::ConstValue;
|
||||
use crate::mir::{ConstAlloc, ConstValue};
|
||||
use crate::query::TyCtxtAt;
|
||||
use crate::ty::{layout, tls, Ty, TyCtxt, ValTree};
|
||||
|
||||
|
@ -149,7 +149,7 @@ macro_rules! throw_ub_custom {
|
||||
UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind,
|
||||
};
|
||||
|
||||
pub use self::value::{ConstAlloc, ConstValue, Scalar};
|
||||
pub use self::value::Scalar;
|
||||
|
||||
pub use self::allocation::{
|
||||
alloc_range, AllocBytes, AllocError, AllocRange, AllocResult, Allocation, ConstAllocation,
|
||||
|
@ -9,163 +9,9 @@
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_target::abi::{HasDataLayout, Size};
|
||||
|
||||
use crate::{
|
||||
mir::interpret::alloc_range,
|
||||
ty::{ParamEnv, ScalarInt, Ty, TyCtxt},
|
||||
};
|
||||
use crate::ty::ScalarInt;
|
||||
|
||||
use super::{
|
||||
AllocId, ConstAllocation, InterpResult, Pointer, PointerArithmetic, Provenance,
|
||||
ScalarSizeMismatch,
|
||||
};
|
||||
|
||||
/// Represents the result of const evaluation via the `eval_to_allocation` query.
|
||||
#[derive(Copy, Clone, HashStable, TyEncodable, TyDecodable, Debug, Hash, Eq, PartialEq)]
|
||||
pub struct ConstAlloc<'tcx> {
|
||||
/// The value lives here, at offset 0, and that allocation definitely is an `AllocKind::Memory`
|
||||
/// (so you can use `AllocMap::unwrap_memory`).
|
||||
pub alloc_id: AllocId,
|
||||
pub ty: Ty<'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> {
|
||||
/// Used for types with `layout::abi::Scalar` ABI.
|
||||
///
|
||||
/// Not using the enum `Value` to encode that this must not be `Uninit`.
|
||||
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.
|
||||
Indirect {
|
||||
/// The backing memory of the value. May contain more memory than needed for just the value
|
||||
/// if this points into some other larger ConstValue.
|
||||
///
|
||||
/// We use an `AllocId` here instead of a `ConstAllocation<'tcx>` to make sure that when a
|
||||
/// raw constant (which is basically just an `AllocId`) is turned into a `ConstValue` and
|
||||
/// back, we can preserve the original `AllocId`.
|
||||
alloc_id: AllocId,
|
||||
/// Offset into `alloc`
|
||||
offset: Size,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(ConstValue<'_>, 32);
|
||||
|
||||
impl<'tcx> ConstValue<'tcx> {
|
||||
#[inline]
|
||||
pub fn try_to_scalar(&self) -> Option<Scalar<AllocId>> {
|
||||
match *self {
|
||||
ConstValue::Indirect { .. } | ConstValue::Slice { .. } | ConstValue::ZeroSized => None,
|
||||
ConstValue::Scalar(val) => Some(val),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_to_scalar_int(&self) -> Option<ScalarInt> {
|
||||
self.try_to_scalar()?.try_to_int().ok()
|
||||
}
|
||||
|
||||
pub fn try_to_bits(&self, size: Size) -> Option<u128> {
|
||||
self.try_to_scalar_int()?.to_bits(size).ok()
|
||||
}
|
||||
|
||||
pub fn try_to_bool(&self) -> Option<bool> {
|
||||
self.try_to_scalar_int()?.try_into().ok()
|
||||
}
|
||||
|
||||
pub fn try_to_target_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
|
||||
self.try_to_scalar_int()?.try_to_target_usize(tcx).ok()
|
||||
}
|
||||
|
||||
pub fn try_to_bits_for_ty(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<u128> {
|
||||
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
|
||||
self.try_to_bits(size)
|
||||
}
|
||||
|
||||
pub fn from_bool(b: bool) -> Self {
|
||||
ConstValue::Scalar(Scalar::from_bool(b))
|
||||
}
|
||||
|
||||
pub fn from_u64(i: u64) -> Self {
|
||||
ConstValue::Scalar(Scalar::from_u64(i))
|
||||
}
|
||||
|
||||
pub fn from_u128(i: u128) -> Self {
|
||||
ConstValue::Scalar(Scalar::from_u128(i))
|
||||
}
|
||||
|
||||
pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self {
|
||||
ConstValue::Scalar(Scalar::from_target_usize(i, cx))
|
||||
}
|
||||
|
||||
/// 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 => {
|
||||
bug!("`try_get_slice_bytes` on non-slice constant")
|
||||
}
|
||||
&ConstValue::Slice { data, start, end } => (data, start, end),
|
||||
&ConstValue::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();
|
||||
let ptr_size = tcx.data_layout.pointer_size;
|
||||
if a.size() < offset + 2 * ptr_size {
|
||||
// (partially) dangling reference
|
||||
return None;
|
||||
}
|
||||
// Read the wide pointer components.
|
||||
let ptr = a
|
||||
.read_scalar(
|
||||
&tcx,
|
||||
alloc_range(offset, ptr_size),
|
||||
/* read_provenance */ true,
|
||||
)
|
||||
.ok()?;
|
||||
let ptr = ptr.to_pointer(&tcx).ok()?;
|
||||
let len = a
|
||||
.read_scalar(
|
||||
&tcx,
|
||||
alloc_range(offset + ptr_size, ptr_size),
|
||||
/* read_provenance */ false,
|
||||
)
|
||||
.ok()?;
|
||||
let len = len.to_target_usize(&tcx).ok()?;
|
||||
let len: usize = len.try_into().ok()?;
|
||||
if len == 0 {
|
||||
return Some(&[]);
|
||||
}
|
||||
// Non-empty slice, must have memory. We know this is a relative pointer.
|
||||
let (inner_alloc_id, offset) = ptr.into_parts();
|
||||
let data = tcx.global_alloc(inner_alloc_id?).unwrap_memory();
|
||||
(data, offset.bytes_usize(), offset.bytes_usize() + len)
|
||||
}
|
||||
};
|
||||
|
||||
// This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`.
|
||||
Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end))
|
||||
}
|
||||
}
|
||||
use super::{AllocId, InterpResult, Pointer, PointerArithmetic, Provenance, ScalarSizeMismatch};
|
||||
|
||||
/// A `Scalar` represents an immediate, primitive value existing outside of a
|
||||
/// `memory::Allocation`. It is in many ways like a small chunk of an `Allocation`, up to 16 bytes in
|
||||
|
@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
|
||||
|
||||
use crate::mir::interpret::{AllocRange, ErrorHandled, ConstAllocation, ConstValue, Scalar};
|
||||
use crate::mir::interpret::{AllocRange, ConstAllocation, ErrorHandled, Scalar};
|
||||
use crate::mir::visit::MirVisitable;
|
||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
|
@ -12,8 +12,8 @@
|
||||
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,
|
||||
alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, ConstAllocation, GlobalAlloc,
|
||||
Pointer, Provenance,
|
||||
};
|
||||
use rustc_middle::mir::visit::Visitor;
|
||||
use rustc_middle::mir::*;
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! Values computed by queries that use MIR.
|
||||
|
||||
use crate::mir::interpret::ConstValue;
|
||||
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
@ -16,7 +15,7 @@
|
||||
use std::cell::Cell;
|
||||
use std::fmt::{self, Debug};
|
||||
|
||||
use super::SourceInfo;
|
||||
use super::{ConstValue, SourceInfo};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
|
||||
pub enum UnsafetyViolationKind {
|
||||
|
@ -121,16 +121,12 @@ impl EraseType for Result<mir::ConstantKind<'_>, mir::interpret::LitToConstError
|
||||
[u8; size_of::<Result<mir::ConstantKind<'static>, mir::interpret::LitToConstError>>()];
|
||||
}
|
||||
|
||||
impl EraseType for Result<mir::interpret::ConstAlloc<'_>, mir::interpret::ErrorHandled> {
|
||||
type Result = [u8; size_of::<
|
||||
Result<mir::interpret::ConstAlloc<'static>, mir::interpret::ErrorHandled>,
|
||||
>()];
|
||||
impl EraseType for Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled> {
|
||||
type Result = [u8; size_of::<Result<mir::ConstAlloc<'static>, mir::interpret::ErrorHandled>>()];
|
||||
}
|
||||
|
||||
impl EraseType for Result<mir::interpret::ConstValue<'_>, mir::interpret::ErrorHandled> {
|
||||
type Result = [u8; size_of::<
|
||||
Result<mir::interpret::ConstValue<'static>, mir::interpret::ErrorHandled>,
|
||||
>()];
|
||||
impl EraseType for Result<mir::ConstValue<'_>, mir::interpret::ErrorHandled> {
|
||||
type Result = [u8; size_of::<Result<mir::ConstValue<'static>, mir::interpret::ErrorHandled>>()];
|
||||
}
|
||||
|
||||
impl EraseType for Result<Option<ty::ValTree<'_>>, mir::interpret::ErrorHandled> {
|
||||
@ -317,8 +313,8 @@ impl<'tcx> EraseType for $($fake_path)::+<'tcx> {
|
||||
rustc_middle::middle::exported_symbols::ExportedSymbol,
|
||||
rustc_middle::mir::ConstantKind,
|
||||
rustc_middle::mir::DestructuredConstant,
|
||||
rustc_middle::mir::interpret::ConstAlloc,
|
||||
rustc_middle::mir::interpret::ConstValue,
|
||||
rustc_middle::mir::ConstAlloc,
|
||||
rustc_middle::mir::ConstValue,
|
||||
rustc_middle::mir::interpret::GlobalId,
|
||||
rustc_middle::mir::interpret::LitToConstInput,
|
||||
rustc_middle::traits::query::MethodAutoderefStepsResult,
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
use crate::infer::canonical::Canonical;
|
||||
use crate::mir;
|
||||
use crate::mir::interpret::ConstValue;
|
||||
use crate::traits;
|
||||
use crate::ty::fast_reject::SimplifiedType;
|
||||
use crate::ty::layout::{TyAndLayout, ValidityRequirement};
|
||||
@ -369,7 +368,7 @@ fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ConstValue<'tcx>, Ty<'tcx>) {
|
||||
impl<'tcx> Key for (mir::ConstValue<'tcx>, Ty<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
@ -377,7 +376,7 @@ fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for mir::interpret::ConstAlloc<'tcx> {
|
||||
impl<'tcx> Key for mir::ConstAlloc<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||
|
@ -21,7 +21,7 @@
|
||||
use crate::mir;
|
||||
use crate::mir::interpret::GlobalId;
|
||||
use crate::mir::interpret::{
|
||||
ConstValue, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult,
|
||||
EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult,
|
||||
};
|
||||
use crate::mir::interpret::{LitToConstError, LitToConstInput};
|
||||
use crate::mir::mono::CodegenUnit;
|
||||
@ -1091,7 +1091,7 @@
|
||||
}
|
||||
|
||||
/// Converts a type level constant value into `ConstValue`
|
||||
query valtree_to_const_val(key: (Ty<'tcx>, ty::ValTree<'tcx>)) -> ConstValue<'tcx> {
|
||||
query valtree_to_const_val(key: (Ty<'tcx>, ty::ValTree<'tcx>)) -> mir::ConstValue<'tcx> {
|
||||
desc { "converting type-level constant value to mir constant value"}
|
||||
}
|
||||
|
||||
@ -1104,14 +1104,14 @@
|
||||
/// Tries to destructure an `mir::ConstantKind` ADT or array into its variant index
|
||||
/// and its field values. This should only be used for pretty printing.
|
||||
query try_destructure_mir_constant_for_diagnostics(
|
||||
key: (ConstValue<'tcx>, Ty<'tcx>)
|
||||
key: (mir::ConstValue<'tcx>, Ty<'tcx>)
|
||||
) -> Option<mir::DestructuredConstant<'tcx>> {
|
||||
desc { "destructuring MIR constant"}
|
||||
no_hash
|
||||
eval_always
|
||||
}
|
||||
|
||||
query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
|
||||
query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> mir::ConstValue<'tcx> {
|
||||
desc { "getting a &core::panic::Location referring to a span" }
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use rustc_middle::mir::interpret::{ConstValue, Scalar};
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
use rustc_middle::ty::cast::mir_cast_kind;
|
||||
use rustc_middle::{mir::*, thir::*, ty};
|
||||
|
@ -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::{Allocation, LitToConstError, LitToConstInput, Scalar};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::thir::*;
|
||||
use rustc_middle::ty::{
|
||||
|
@ -15,7 +15,6 @@
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::mir::interpret::ConstValue;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::thir::{
|
||||
|
@ -18,7 +18,7 @@
|
||||
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};
|
||||
@ -855,8 +855,8 @@ pub(crate) fn compare_const_vals<'tcx>(
|
||||
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),
|
||||
mir::ConstantKind::Val(mir::ConstValue::Scalar(Scalar::Int(a)), _a_ty),
|
||||
mir::ConstantKind::Val(mir::ConstValue::Scalar(Scalar::Int(b)), _b_ty),
|
||||
) => return Some(a.cmp(&b)),
|
||||
(mir::ConstantKind::Ty(a), mir::ConstantKind::Ty(b)) => {
|
||||
return Some(a.kind().cmp(&b.kind()));
|
||||
|
@ -4,7 +4,7 @@
|
||||
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};
|
||||
|
@ -22,8 +22,8 @@
|
||||
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.
|
||||
|
@ -6,7 +6,7 @@
|
||||
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;
|
||||
|
@ -153,7 +153,7 @@ fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::Val(
|
||||
interpret::ConstValue::Indirect { alloc_id, offset: Size::ZERO },
|
||||
ConstValue::Indirect { alloc_id, offset: Size::ZERO },
|
||||
tmp_ty,
|
||||
),
|
||||
};
|
||||
|
@ -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};
|
||||
|
@ -170,8 +170,7 @@
|
||||
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::{ErrorHandled, GlobalAlloc, Scalar};
|
||||
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, GlobalAlloc, Scalar};
|
||||
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
|
||||
use rustc_middle::mir::visit::Visitor as MirVisitor;
|
||||
use rustc_middle::mir::{self, Local, Location};
|
||||
@ -1442,13 +1441,15 @@ fn collect_used_items<'tcx>(
|
||||
#[instrument(skip(tcx, output), level = "debug")]
|
||||
fn collect_const_value<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
value: ConstValue<'tcx>,
|
||||
value: mir::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: _ } => {
|
||||
mir::ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => {
|
||||
collect_alloc(tcx, ptr.provenance, output)
|
||||
}
|
||||
mir::ConstValue::Indirect { alloc_id, .. } => collect_alloc(tcx, alloc_id, output),
|
||||
mir::ConstValue::Slice { data, start: _, end: _ } => {
|
||||
for &id in data.inner().provenance().ptrs().values() {
|
||||
collect_alloc(tcx, id, output);
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer};
|
||||
use rustc_middle::mir::{
|
||||
interpret::{alloc_range, AllocRange, Pointer},
|
||||
ConstValue,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
rustc_smir::{Stable, Tables},
|
||||
|
@ -16,7 +16,6 @@
|
||||
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 _;
|
||||
@ -282,8 +281,8 @@ pub(crate) fn print_evaluated_const(
|
||||
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||
match (val, ty.kind()) {
|
||||
(_, &ty::Ref(..)) => None,
|
||||
(ConstValue::Scalar(_), &ty::Adt(_, _)) => None,
|
||||
(ConstValue::Scalar(_), _) => {
|
||||
(mir::ConstValue::Scalar(_), &ty::Adt(_, _)) => None,
|
||||
(mir::ConstValue::Scalar(_), _) => {
|
||||
let const_ = mir::ConstantKind::from_value(val, ty);
|
||||
Some(print_const_with_custom_print_scalar(tcx, const_, underscores_and_type))
|
||||
}
|
||||
@ -326,14 +325,14 @@ fn print_const_with_custom_print_scalar<'tcx>(
|
||||
// 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)) => {
|
||||
(mir::ConstantKind::Val(mir::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()
|
||||
}
|
||||
}
|
||||
(mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Int(i)) => {
|
||||
(mir::ConstantKind::Val(mir::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);
|
||||
|
@ -656,7 +656,7 @@ fn binop(&mut self, op: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> Option<Cons
|
||||
}
|
||||
|
||||
pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'tcx>) -> Option<Constant<'tcx>> {
|
||||
use rustc_middle::mir::interpret::ConstValue;
|
||||
use rustc_middle::mir::ConstValue;
|
||||
match result {
|
||||
mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() {
|
||||
ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)),
|
||||
|
@ -13,7 +13,7 @@
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::interpret::{ConstValue, Scalar};
|
||||
use rustc_middle::mir::{ConstValue, interpret::Scalar};
|
||||
use rustc_middle::traits::EvaluationResult;
|
||||
use rustc_middle::ty::layout::ValidityRequirement;
|
||||
use rustc_middle::ty::{
|
||||
|
Loading…
Reference in New Issue
Block a user