From d1b2d29528b7794b41e66fc2136e395a02f8529b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:59:35 +0200 Subject: Merging upstream version 1.73.0+dfsg1. Signed-off-by: Daniel Baumann --- .../rustc_middle/src/mir/interpret/allocation.rs | 71 ++++++++++++++-------- .../src/mir/interpret/allocation/init_mask.rs | 6 +- .../src/mir/interpret/allocation/provenance_map.rs | 14 +++-- compiler/rustc_middle/src/mir/interpret/error.rs | 63 +++++++++---------- compiler/rustc_middle/src/mir/interpret/mod.rs | 22 +++---- compiler/rustc_middle/src/mir/interpret/queries.rs | 29 ++++----- compiler/rustc_middle/src/mir/interpret/value.rs | 29 ++++++--- 7 files changed, 126 insertions(+), 108 deletions(-) (limited to 'compiler/rustc_middle/src/mir/interpret') diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index b8030d9db..c787481bf 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -18,9 +18,9 @@ use rustc_span::DUMMY_SP; use rustc_target::abi::{Align, HasDataLayout, Size}; use super::{ - read_target_uint, write_target_uint, AllocId, InterpError, InterpResult, Pointer, Provenance, - ResourceExhaustionInfo, Scalar, ScalarSizeMismatch, UndefinedBehaviorInfo, UninitBytesAccess, - UnsupportedOpInfo, + read_target_uint, write_target_uint, AllocId, BadBytesAccess, InterpError, InterpResult, + Pointer, PointerArithmetic, Provenance, ResourceExhaustionInfo, Scalar, ScalarSizeMismatch, + UndefinedBehaviorInfo, UnsupportedOpInfo, }; use crate::ty; use init_mask::*; @@ -173,13 +173,13 @@ pub enum AllocError { /// A scalar had the wrong size. ScalarSizeMismatch(ScalarSizeMismatch), /// Encountered a pointer where we needed raw bytes. - ReadPointerAsBytes, + ReadPointerAsInt(Option), /// Partially overwriting a pointer. - PartialPointerOverwrite(Size), + OverwritePartialPointer(Size), /// Partially copying a pointer. - PartialPointerCopy(Size), + ReadPartialPointer(Size), /// Using uninitialized data where it is not allowed. - InvalidUninitBytes(Option), + InvalidUninitBytes(Option), } pub type AllocResult = Result; @@ -196,12 +196,14 @@ impl AllocError { ScalarSizeMismatch(s) => { InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ScalarSizeMismatch(s)) } - ReadPointerAsBytes => InterpError::Unsupported(UnsupportedOpInfo::ReadPointerAsBytes), - PartialPointerOverwrite(offset) => InterpError::Unsupported( - UnsupportedOpInfo::PartialPointerOverwrite(Pointer::new(alloc_id, offset)), + ReadPointerAsInt(info) => InterpError::Unsupported( + UnsupportedOpInfo::ReadPointerAsInt(info.map(|b| (alloc_id, b))), ), - PartialPointerCopy(offset) => InterpError::Unsupported( - UnsupportedOpInfo::PartialPointerCopy(Pointer::new(alloc_id, offset)), + OverwritePartialPointer(offset) => InterpError::Unsupported( + UnsupportedOpInfo::OverwritePartialPointer(Pointer::new(alloc_id, offset)), + ), + ReadPartialPointer(offset) => InterpError::Unsupported( + UnsupportedOpInfo::ReadPartialPointer(Pointer::new(alloc_id, offset)), ), InvalidUninitBytes(info) => InterpError::UndefinedBehavior( UndefinedBehaviorInfo::InvalidUninitBytes(info.map(|b| (alloc_id, b))), @@ -327,6 +329,9 @@ impl Allocation { /// Try to create an Allocation of `size` bytes, panics if there is not enough memory /// available to the compiler to do so. + /// + /// Example use case: To obtain an Allocation filled with specific data, + /// first call this function and then call write_scalar to fill in the right data. pub fn uninit(size: Size, align: Align) -> Self { match Self::uninit_inner(size, align, || { panic!("Allocation::uninit called with panic_on_fail had allocation failure"); @@ -433,14 +438,26 @@ impl Allocation range: AllocRange, ) -> AllocResult<&[u8]> { self.init_mask.is_range_initialized(range).map_err(|uninit_range| { - AllocError::InvalidUninitBytes(Some(UninitBytesAccess { + AllocError::InvalidUninitBytes(Some(BadBytesAccess { access: range, - uninit: uninit_range, + bad: uninit_range, })) })?; if !Prov::OFFSET_IS_ADDR { if !self.provenance.range_empty(range, cx) { - return Err(AllocError::ReadPointerAsBytes); + // Find the provenance. + let (offset, _prov) = self + .provenance + .range_get_ptrs(range, cx) + .first() + .copied() + .expect("there must be provenance somewhere here"); + let start = offset.max(range.start); // the pointer might begin before `range`! + let end = (offset + cx.pointer_size()).min(range.end()); // the pointer might end after `range`! + return Err(AllocError::ReadPointerAsInt(Some(BadBytesAccess { + access: range, + bad: AllocRange::from(start..end), + }))); } } Ok(self.get_bytes_unchecked(range)) @@ -536,23 +553,25 @@ impl Allocation // Now use this provenance. let ptr = Pointer::new(prov, Size::from_bytes(bits)); return Ok(Scalar::from_maybe_pointer(ptr, cx)); + } else { + // Without OFFSET_IS_ADDR, the only remaining case we can handle is total absence of + // provenance. + if self.provenance.range_empty(range, cx) { + return Ok(Scalar::from_uint(bits, range.size)); + } + // Else we have mixed provenance, that doesn't work. + return Err(AllocError::ReadPartialPointer(range.start)); } } else { // We are *not* reading a pointer. - // If we can just ignore provenance, do exactly that. - if Prov::OFFSET_IS_ADDR { + // If we can just ignore provenance or there is none, that's easy. + if Prov::OFFSET_IS_ADDR || self.provenance.range_empty(range, cx) { // We just strip provenance. return Ok(Scalar::from_uint(bits, range.size)); } + // There is some provenance and we don't have OFFSET_IS_ADDR. This doesn't work. + return Err(AllocError::ReadPointerAsInt(None)); } - - // Fallback path for when we cannot treat provenance bytewise or ignore it. - assert!(!Prov::OFFSET_IS_ADDR); - if !self.provenance.range_empty(range, cx) { - return Err(AllocError::ReadPointerAsBytes); - } - // There is no provenance, we can just return the bits. - Ok(Scalar::from_uint(bits, range.size)) } /// Writes a *non-ZST* scalar. @@ -571,7 +590,7 @@ impl Allocation assert!(self.mutability == Mutability::Mut); // `to_bits_or_ptr_internal` is the right method because we just want to store this data - // as-is into memory. + // as-is into memory. This also double-checks that `val.size()` matches `range.size`. let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? { Right(ptr) => { let (provenance, offset) = ptr.into_parts(); diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs index d4dd56a42..2c6bb908f 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs @@ -542,11 +542,7 @@ impl InitMaskMaterialized { debug_assert_eq!( result, find_bit_slow(self, start, end, is_init), - "optimized implementation of find_bit is wrong for start={:?} end={:?} is_init={} init_mask={:#?}", - start, - end, - is_init, - self + "optimized implementation of find_bit is wrong for start={start:?} end={end:?} is_init={is_init} init_mask={self:#?}" ); result diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index 318f93e12..0243fc451 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -66,7 +66,11 @@ impl ProvenanceMap { /// Returns all ptr-sized provenance in the given range. /// If the range has length 0, returns provenance that crosses the edge between `start-1` and /// `start`. - fn range_get_ptrs(&self, range: AllocRange, cx: &impl HasDataLayout) -> &[(Size, Prov)] { + pub(super) fn range_get_ptrs( + &self, + range: AllocRange, + cx: &impl HasDataLayout, + ) -> &[(Size, Prov)] { // We have to go back `pointer_size - 1` bytes, as that one would still overlap with // the beginning of this range. let adjusted_start = Size::from_bytes( @@ -158,7 +162,7 @@ impl ProvenanceMap { if first < start { if !Prov::OFFSET_IS_ADDR { // We can't split up the provenance into less than a pointer. - return Err(AllocError::PartialPointerOverwrite(first)); + return Err(AllocError::OverwritePartialPointer(first)); } // Insert the remaining part in the bytewise provenance. let prov = self.ptrs[&first]; @@ -171,7 +175,7 @@ impl ProvenanceMap { let begin_of_last = last - cx.data_layout().pointer_size; if !Prov::OFFSET_IS_ADDR { // We can't split up the provenance into less than a pointer. - return Err(AllocError::PartialPointerOverwrite(begin_of_last)); + return Err(AllocError::OverwritePartialPointer(begin_of_last)); } // Insert the remaining part in the bytewise provenance. let prov = self.ptrs[&begin_of_last]; @@ -246,10 +250,10 @@ impl ProvenanceMap { if !Prov::OFFSET_IS_ADDR { // There can't be any bytewise provenance, and we cannot split up the begin/end overlap. if let Some(entry) = begin_overlap { - return Err(AllocError::PartialPointerCopy(entry.0)); + return Err(AllocError::ReadPartialPointer(entry.0)); } if let Some(entry) = end_overlap { - return Err(AllocError::PartialPointerCopy(entry.0)); + return Err(AllocError::ReadPartialPointer(entry.0)); } debug_assert!(self.bytes.is_none()); } else { diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 2435bc59e..e6ef5a41e 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -12,7 +12,8 @@ use rustc_errors::{ use rustc_macros::HashStable; use rustc_session::CtfeBacktrace; use rustc_span::def_id::DefId; -use rustc_target::abi::{call, Align, Size, WrappingRange}; +use rustc_target::abi::{call, Align, Size, VariantIdx, WrappingRange}; + use std::borrow::Cow; use std::{any::Any, backtrace::Backtrace, fmt}; @@ -22,7 +23,7 @@ pub enum ErrorHandled { /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`. Reported(ReportedErrorInfo), /// Don't emit an error, the evaluation failed because the MIR was generic - /// and the substs didn't fully monomorphize it. + /// and the args didn't fully monomorphize it. TooGeneric, } @@ -66,9 +67,7 @@ impl Into for ReportedErrorInfo { } } -TrivialTypeTraversalAndLiftImpls! { - ErrorHandled, -} +TrivialTypeTraversalAndLiftImpls! { ErrorHandled } pub type EvalToAllocationRawResult<'tcx> = Result, ErrorHandled>; pub type EvalToConstValueResult<'tcx> = Result, ErrorHandled>; @@ -135,10 +134,6 @@ impl InterpErrorBacktrace { } impl<'tcx> InterpErrorInfo<'tcx> { - pub fn from_parts(kind: InterpError<'tcx>, backtrace: InterpErrorBacktrace) -> Self { - Self(Box::new(InterpErrorInfoInner { kind, backtrace })) - } - pub fn into_parts(self) -> (InterpError<'tcx>, InterpErrorBacktrace) { let InterpErrorInfo(box InterpErrorInfoInner { kind, backtrace }) = self; (kind, backtrace) @@ -156,7 +151,7 @@ impl<'tcx> InterpErrorInfo<'tcx> { } fn print_backtrace(backtrace: &Backtrace) { - eprintln!("\n\nAn error occurred in miri:\n{}", backtrace); + eprintln!("\n\nAn error occurred in the MIR interpreter:\n{backtrace}"); } impl From for InterpErrorInfo<'_> { @@ -189,11 +184,8 @@ pub enum InvalidProgramInfo<'tcx> { /// (which unfortunately typeck does not reject). /// Not using `FnAbiError` as that contains a nested `LayoutError`. FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), - /// SizeOf of unsized type was requested. - SizeOfUnsizedType(Ty<'tcx>), - /// An unsized local was accessed without having been initialized. - /// This is not meaningful as we can't even have backing memory for such locals. - UninitUnsizedLocal, + /// We are runnning into a nonsense situation due to ConstProp violating our invariants. + ConstPropNonsense, } /// Details of why a pointer had to be in-bounds. @@ -228,13 +220,13 @@ impl IntoDiagnosticArg for InvalidMetaKind { } } -/// Details of an access to uninitialized bytes where it is not allowed. +/// Details of an access to uninitialized bytes / bad pointer bytes where it is not allowed. #[derive(Debug, Clone, Copy)] -pub struct UninitBytesAccess { +pub struct BadBytesAccess { /// Range of the original memory access. pub access: AllocRange, - /// Range of the uninit memory that was encountered. (Might not be maximal.) - pub uninit: AllocRange, + /// Range of the bad memory that was encountered. (Might not be maximal.) + pub bad: AllocRange, } /// Information about a size mismatch. @@ -284,8 +276,8 @@ pub enum UndefinedBehaviorInfo<'a> { InvalidMeta(InvalidMetaKind), /// Reading a C string that does not end within its allocation. UnterminatedCString(Pointer), - /// Dereferencing a dangling pointer after it got freed. - PointerUseAfterFree(AllocId), + /// Using a pointer after it got freed. + PointerUseAfterFree(AllocId, CheckInAllocMsg), /// Used a pointer outside the bounds it is valid for. /// (If `ptr_size > 0`, determines the size of the memory range that was expected to be in-bounds.) PointerOutOfBounds { @@ -318,15 +310,17 @@ pub enum UndefinedBehaviorInfo<'a> { /// Using a string that is not valid UTF-8, InvalidStr(std::str::Utf8Error), /// Using uninitialized data where it is not allowed. - InvalidUninitBytes(Option<(AllocId, UninitBytesAccess)>), + InvalidUninitBytes(Option<(AllocId, BadBytesAccess)>), /// Working with a local that is not currently live. DeadLocal, /// Data size is not equal to target size. ScalarSizeMismatch(ScalarSizeMismatch), /// A discriminant of an uninhabited enum variant is written. - UninhabitedEnumVariantWritten, + UninhabitedEnumVariantWritten(VariantIdx), + /// An uninhabited enum variant is projected. + UninhabitedEnumVariantRead(VariantIdx), /// Validation error. - Validation(ValidationErrorInfo<'a>), + ValidationError(ValidationErrorInfo<'a>), // FIXME(fee1-dead) these should all be actual variants of the enum instead of dynamically // dispatched /// A custom (free-form) error, created by `err_ub_custom!`. @@ -368,6 +362,8 @@ pub enum ExpectedKind { Float, Int, FnPtr, + EnumTag, + Str, } impl From for ExpectedKind { @@ -381,10 +377,11 @@ impl From for ExpectedKind { #[derive(Debug)] pub enum ValidationErrorKind<'tcx> { + PointerAsInt { expected: ExpectedKind }, + PartialPointer, PtrToUninhabited { ptr_kind: PointerKind, ty: Ty<'tcx> }, PtrToStatic { ptr_kind: PointerKind }, PtrToMut { ptr_kind: PointerKind }, - ExpectedNonPtr { value: String }, MutableRefInConst, NullFnPtr, NeverVal, @@ -394,10 +391,8 @@ pub enum ValidationErrorKind<'tcx> { UnsafeCell, UninhabitedVal { ty: Ty<'tcx> }, InvalidEnumTag { value: String }, - UninitEnumTag, - UninitStr, + UninhabitedEnumVariant, Uninit { expected: ExpectedKind }, - UninitVal, InvalidVTablePtr { value: String }, InvalidMetaSliceTooLarge { ptr_kind: PointerKind }, InvalidMetaTooLarge { ptr_kind: PointerKind }, @@ -425,12 +420,12 @@ pub enum UnsupportedOpInfo { // /// Overwriting parts of a pointer; without knowing absolute addresses, the resulting state /// cannot be represented by the CTFE interpreter. - PartialPointerOverwrite(Pointer), - /// Attempting to `copy` parts of a pointer to somewhere else; without knowing absolute + OverwritePartialPointer(Pointer), + /// Attempting to read or copy parts of a pointer to somewhere else; without knowing absolute /// addresses, the resulting state cannot be represented by the CTFE interpreter. - PartialPointerCopy(Pointer), - /// Encountered a pointer where we needed raw bytes. - ReadPointerAsBytes, + ReadPartialPointer(Pointer), + /// Encountered a pointer where we needed an integer. + ReadPointerAsInt(Option<(AllocId, BadBytesAccess)>), /// Accessing thread local statics ThreadLocalStatic(DefId), /// Accessing an unsupported extern static. @@ -496,7 +491,7 @@ impl InterpError<'_> { matches!( self, InterpError::Unsupported(UnsupportedOpInfo::Unsupported(_)) - | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::Validation { .. }) + | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError { .. }) | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_)) ) } diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 2d2cfee1b..3543158bf 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -138,15 +138,15 @@ use rustc_target::abi::{AddressSpace, Endian, HasDataLayout}; use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::subst::GenericArgKind; +use crate::ty::GenericArgKind; use crate::ty::{self, Instance, Ty, TyCtxt}; pub use self::error::{ - struct_error, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult, - EvalToValTreeResult, ExpectedKind, InterpError, InterpErrorInfo, InterpResult, InvalidMetaKind, - InvalidProgramInfo, MachineStopType, PointerKind, ReportedErrorInfo, ResourceExhaustionInfo, - ScalarSizeMismatch, UndefinedBehaviorInfo, UninitBytesAccess, UnsupportedOpInfo, - ValidationErrorInfo, ValidationErrorKind, + struct_error, BadBytesAccess, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, + EvalToConstValueResult, EvalToValTreeResult, ExpectedKind, InterpError, InterpErrorInfo, + InterpResult, InvalidMetaKind, InvalidProgramInfo, MachineStopType, PointerKind, + ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo, + UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind, }; pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar}; @@ -176,7 +176,7 @@ impl<'tcx> GlobalId<'tcx> { pub fn display(self, tcx: TyCtxt<'tcx>) -> String { let instance_name = with_no_trimmed_paths!(tcx.def_path_str(self.instance.def.def_id())); if let Some(promoted) = self.promoted { - format!("{}::{:?}", instance_name, promoted) + format!("{instance_name}::{promoted:?}") } else { instance_name } @@ -274,7 +274,7 @@ pub struct AllocDecodingState { // For each `AllocId`, we keep track of which decoding state it's currently in. decoding_state: Vec>, // The offsets of each allocation in the data stream. - data_offsets: Vec, + data_offsets: Vec, } impl AllocDecodingState { @@ -289,7 +289,7 @@ impl AllocDecodingState { AllocDecodingSession { state: self, session_id } } - pub fn new(data_offsets: Vec) -> Self { + pub fn new(data_offsets: Vec) -> Self { let decoding_state = std::iter::repeat_with(|| Lock::new(State::Empty)).take(data_offsets.len()).collect(); @@ -559,7 +559,7 @@ impl<'tcx> TyCtxt<'tcx> { // However, formatting code relies on function identity (see #58320), so we only do // this for generic functions. Lifetime parameters are ignored. let is_generic = instance - .substs + .args .into_iter() .any(|kind| !matches!(kind.unpack(), GenericArgKind::Lifetime(_))); if is_generic { @@ -609,7 +609,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Panics in case the `AllocId` is dangling. Since that is impossible for `AllocId`s in /// constants (as all constants must pass interning and validation that check for dangling /// ids), this function is frequently used throughout rustc, but should not be used within - /// the miri engine. + /// the interpreter. pub fn global_alloc(self, id: AllocId) -> GlobalAlloc<'tcx> { match self.try_get_global_alloc(id) { Some(alloc) => alloc, diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 9c97431f3..fc659ce18 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -2,8 +2,8 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId} use crate::mir; use crate::query::{TyCtxtAt, TyCtxtEnsure}; -use crate::ty::subst::InternalSubsts; use crate::ty::visit::TypeVisitableExt; +use crate::ty::GenericArgs; use crate::ty::{self, TyCtxt}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; @@ -20,8 +20,8 @@ impl<'tcx> TyCtxt<'tcx> { // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are // encountered. - let substs = InternalSubsts::identity_for_item(self, def_id); - let instance = ty::Instance::new(def_id, substs); + let args = GenericArgs::identity_for_item(self, def_id); + let instance = ty::Instance::new(def_id, args); let cid = GlobalId { instance, promoted: None }; let param_env = self.param_env(def_id).with_reveal_all_normalized(self); self.const_eval_global_id(param_env, cid, None) @@ -48,14 +48,14 @@ impl<'tcx> TyCtxt<'tcx> { // // When trying to evaluate constants containing inference variables, // use `Infcx::const_eval_resolve` instead. - if ct.substs.has_non_region_infer() { + if ct.args.has_non_region_infer() { bug!("did not expect inference variables here"); } match ty::Instance::resolve( self, param_env, // FIXME: maybe have a separate version for resolving mir::UnevaluatedConst? - ct.def, ct.substs, + ct.def, ct.args, ) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: ct.promoted }; @@ -79,11 +79,11 @@ impl<'tcx> TyCtxt<'tcx> { // // When trying to evaluate constants containing inference variables, // use `Infcx::const_eval_resolve` instead. - if ct.substs.has_non_region_infer() { + if ct.args.has_non_region_infer() { bug!("did not expect inference variables here"); } - match ty::Instance::resolve(self, param_env, ct.def, ct.substs) { + match ty::Instance::resolve(self, param_env, ct.def, ct.args) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: None }; self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| { @@ -94,7 +94,7 @@ impl<'tcx> TyCtxt<'tcx> { // @lcnr believes that successfully evaluating even though there are // used generic parameters is a bug of evaluation, so checking for it // here does feel somewhat sensible. - if !self.features().generic_const_exprs && ct.substs.has_non_region_param() { + if !self.features().generic_const_exprs && ct.args.has_non_region_param() { let def_kind = self.def_kind(instance.def_id()); assert!( matches!( @@ -139,7 +139,6 @@ impl<'tcx> TyCtxt<'tcx> { cid: GlobalId<'tcx>, span: Option, ) -> EvalToConstValueResult<'tcx> { - let param_env = param_env.with_const(); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(param_env.and(cid)); @@ -158,8 +157,6 @@ impl<'tcx> TyCtxt<'tcx> { cid: GlobalId<'tcx>, span: Option, ) -> EvalToValTreeResult<'tcx> { - let param_env = param_env.with_const(); - debug!(?param_env); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(param_env.and(cid)); @@ -204,7 +201,6 @@ impl<'tcx> TyCtxtAt<'tcx> { gid: GlobalId<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Result, ErrorHandled> { - let param_env = param_env.with_const(); trace!("eval_to_allocation: Need to compute {:?}", gid); let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?; Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) @@ -221,11 +217,10 @@ impl<'tcx> TyCtxtEnsure<'tcx> { // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are // encountered. - let substs = InternalSubsts::identity_for_item(self.tcx, def_id); - let instance = ty::Instance::new(def_id, substs); + let args = GenericArgs::identity_for_item(self.tcx, def_id); + let instance = ty::Instance::new(def_id, args); let cid = GlobalId { instance, promoted: None }; - let param_env = - self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx).with_const(); + let param_env = self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.tcx.erase_regions(param_env.and(cid)); @@ -238,7 +233,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> { assert!(self.tcx.is_static(def_id)); let instance = ty::Instance::mono(self.tcx, def_id); let gid = GlobalId { instance, promoted: None }; - let param_env = ty::ParamEnv::reveal_all().with_const(); + let param_env = ty::ParamEnv::reveal_all(); trace!("eval_to_allocation: Need to compute {:?}", gid); self.eval_to_allocation_raw(param_env.and(gid)) } diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 0416411df..5345a6588 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -135,8 +135,8 @@ static_assert_size!(Scalar, 24); impl fmt::Debug for Scalar { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Scalar::Ptr(ptr, _size) => write!(f, "{:?}", ptr), - Scalar::Int(int) => write!(f, "{:?}", int), + Scalar::Ptr(ptr, _size) => write!(f, "{ptr:?}"), + Scalar::Int(int) => write!(f, "{int:?}"), } } } @@ -144,8 +144,8 @@ impl fmt::Debug for Scalar { impl fmt::Display for Scalar { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Scalar::Ptr(ptr, _size) => write!(f, "pointer to {:?}", ptr), - Scalar::Int(int) => write!(f, "{}", int), + Scalar::Ptr(ptr, _size) => write!(f, "pointer to {ptr:?}"), + Scalar::Int(int) => write!(f, "{int}"), } } } @@ -153,8 +153,8 @@ impl fmt::Display for Scalar { impl fmt::LowerHex for Scalar { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Scalar::Ptr(ptr, _size) => write!(f, "pointer to {:?}", ptr), - Scalar::Int(int) => write!(f, "{:#x}", int), + Scalar::Ptr(ptr, _size) => write!(f, "pointer to {ptr:?}"), + Scalar::Int(int) => write!(f, "{int:#x}"), } } } @@ -320,6 +320,14 @@ impl Scalar { } }) } + + #[inline] + pub fn size(self) -> Size { + match self { + Scalar::Int(int) => int.size(), + Scalar::Ptr(_ptr, sz) => Size::from_bytes(sz), + } + } } impl<'tcx, Prov: Provenance> Scalar { @@ -370,15 +378,16 @@ impl<'tcx, Prov: Provenance> Scalar { #[inline] pub fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> { assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST"); - self.try_to_int().map_err(|_| err_unsup!(ReadPointerAsBytes))?.to_bits(target_size).map_err( - |size| { + self.try_to_int() + .map_err(|_| err_unsup!(ReadPointerAsInt(None)))? + .to_bits(target_size) + .map_err(|size| { err_ub!(ScalarSizeMismatch(ScalarSizeMismatch { target_size: target_size.bytes(), data_size: size.bytes(), })) .into() - }, - ) + }) } #[inline(always)] -- cgit v1.2.3