From 37e79eb0a7d95f008d92bc7fbf42ae99f38d621d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 9 Oct 2023 15:42:03 +0000 Subject: [PATCH 1/7] The mutability was ignored anyway, so just check for staticness --- .../rustc_const_eval/src/const_eval/eval_queries.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) 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 6b612c3483710..936f3a68264a3 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -335,13 +335,16 @@ pub fn eval_to_allocation_raw_provider<'tcx>( let mut ref_tracking = RefTracking::new(mplace.clone()); let mut inner = false; while let Some((mplace, path)) = ref_tracking.todo.pop() { - let mode = match tcx.static_mutability(cid.instance.def_id()) { - Some(_) if cid.promoted.is_some() => { + let mode = if is_static { + if cid.promoted.is_some() { // Promoteds in statics are allowed to point to statics. CtfeValidationMode::Const { inner, allow_static_ptrs: true } + } else { + // a `static` + CtfeValidationMode::Regular } - Some(_) => CtfeValidationMode::Regular, // a `static` - None => CtfeValidationMode::Const { inner, allow_static_ptrs: false }, + } else { + CtfeValidationMode::Const { inner, allow_static_ptrs: false } }; ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)?; inner = true; From 500dbd434d74e9ae74ffd1d0020492d064dfdb79 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 10 Oct 2023 07:02:45 +0000 Subject: [PATCH 2/7] Pull mplace validation logic out into an interpreter method --- .../src/const_eval/eval_queries.rs | 27 ++++------------- .../src/interpret/validity.rs | 30 ++++++++++++++++++- 2 files changed, 34 insertions(+), 23 deletions(-) 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 936f3a68264a3..8f2ac0def2cbf 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -3,7 +3,7 @@ use std::mem; use either::{Left, Right}; use rustc_hir::def::DefKind; -use rustc_middle::mir::interpret::{ErrorHandled, InterpErrorInfo}; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::pretty::write_allocation_bytes; use rustc_middle::mir::{self, ConstAlloc, ConstValue}; use rustc_middle::traits::Reveal; @@ -19,8 +19,8 @@ use crate::errors; use crate::errors::ConstEvalError; use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ - intern_const_alloc_recursive, CtfeValidationMode, GlobalId, Immediate, InternKind, InterpCx, - InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, + intern_const_alloc_recursive, GlobalId, Immediate, InternKind, InterpCx, InterpError, + InterpResult, MPlaceTy, MemoryKind, OpTy, StackPopCleanup, }; // Returns a pointer to where the result lives @@ -331,25 +331,8 @@ pub fn eval_to_allocation_raw_provider<'tcx>( Ok(mplace) => { // Since evaluation had no errors, validate the resulting constant. // This is a separate `try` block to provide more targeted error reporting. - let validation: Result<_, InterpErrorInfo<'_>> = try { - let mut ref_tracking = RefTracking::new(mplace.clone()); - let mut inner = false; - while let Some((mplace, path)) = ref_tracking.todo.pop() { - let mode = if is_static { - if cid.promoted.is_some() { - // Promoteds in statics are allowed to point to statics. - CtfeValidationMode::Const { inner, allow_static_ptrs: true } - } else { - // a `static` - CtfeValidationMode::Regular - } - } else { - CtfeValidationMode::Const { inner, allow_static_ptrs: false } - }; - ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)?; - inner = true; - } - }; + let validation = ecx.const_validate_mplace(&mplace, is_static, cid.promoted.is_some()); + let alloc_id = mplace.ptr().provenance.unwrap(); // Validation failed, report an error. diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 082e5466fe2e7..3eb367accb313 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -929,7 +929,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// - no pointers to statics. /// - no `UnsafeCell` or non-ZST `&mut`. #[inline(always)] - pub fn const_validate_operand( + fn const_validate_operand( &self, op: &OpTy<'tcx, M::Provenance>, path: Vec, @@ -939,6 +939,34 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.validate_operand_internal(op, path, Some(ref_tracking), Some(ctfe_mode)) } + #[inline(always)] + pub fn const_validate_mplace( + &self, + mplace: &MPlaceTy<'tcx, M::Provenance>, + is_static: bool, + is_promoted: bool, + ) -> InterpResult<'tcx> { + let mut ref_tracking = RefTracking::new(mplace.clone()); + let mut inner = false; + while let Some((mplace, path)) = ref_tracking.todo.pop() { + let mode = if is_static { + if is_promoted { + // Promoteds in statics are allowed to point to statics. + CtfeValidationMode::Const { inner, allow_static_ptrs: true } + } else { + // a `static` + CtfeValidationMode::Regular + } + } else { + CtfeValidationMode::Const { inner, allow_static_ptrs: false } + }; + self.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)?; + inner = true; + } + + Ok(()) + } + /// This function checks the data at `op` to be runtime-valid. /// `op` is assumed to cover valid memory if it is an indirect operand. /// It will error if the bits at the destination do not match the ones described by the layout. From 13a29b89524bf82dccd8846be3d81e997db09ba6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 10 Oct 2023 08:03:04 +0000 Subject: [PATCH 3/7] Pull out const error reporting into its own function --- .../rustc_const_eval/src/const_eval/error.rs | 2 +- .../src/const_eval/eval_queries.rs | 36 ++--------------- .../src/interpret/validity.rs | 39 +++++++++++++++++-- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index bf1e0a370734d..279c415a2aa5a 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -117,7 +117,7 @@ where /// This will use the `mk` function for creating the error which will get passed labels according to /// the `InterpError` and the span and a stacktrace of current execution according to /// `get_span_and_frames`. -pub(super) fn report<'tcx, C, F, E>( +pub(crate) fn report<'tcx, C, F, E>( tcx: TyCtxt<'tcx>, error: InterpError<'tcx>, span: Option, 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 8f2ac0def2cbf..a3b430b47db38 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -4,7 +4,6 @@ use either::{Left, Right}; use rustc_hir::def::DefKind; use rustc_middle::mir::interpret::ErrorHandled; -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; @@ -19,8 +18,8 @@ use crate::errors; use crate::errors::ConstEvalError; use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ - intern_const_alloc_recursive, GlobalId, Immediate, InternKind, InterpCx, InterpError, - InterpResult, MPlaceTy, MemoryKind, OpTy, StackPopCleanup, + intern_const_alloc_recursive, GlobalId, Immediate, InternKind, InterpCx, InterpResult, + MPlaceTy, MemoryKind, OpTy, StackPopCleanup, }; // Returns a pointer to where the result lives @@ -337,36 +336,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( // Validation failed, report an error. if let Err(error) = validation { - let (error, backtrace) = error.into_parts(); - backtrace.print_backtrace(); - - let ub_note = matches!(error, InterpError::UndefinedBehavior(_)).then(|| {}); - - let alloc = ecx.tcx.global_alloc(alloc_id).unwrap_memory().inner(); - let mut bytes = String::new(); - if alloc.size() != abi::Size::ZERO { - bytes = "\n".into(); - // FIXME(translation) there might be pieces that are translatable. - write_allocation_bytes(*ecx.tcx, alloc, &mut bytes, " ").unwrap(); - } - let raw_bytes = errors::RawBytesNote { - size: alloc.size().bytes(), - align: alloc.align.bytes(), - bytes, - }; - - Err(super::report( - *ecx.tcx, - error, - None, - || super::get_span_and_frames(&ecx), - move |span, frames| errors::UndefinedBehavior { - span, - ub_note, - frames, - raw_bytes, - }, - )) + Err(ecx.const_report_error(error, alloc_id)) } else { // Convert to raw constant Ok(ConstAlloc { alloc_id, ty: mplace.layout.ty }) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 3eb367accb313..8975fafe99244 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -13,18 +13,21 @@ use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_middle::mir::interpret::{ - ExpectedKind, InterpError, InvalidMetaKind, Misalignment, PointerKind, ValidationErrorInfo, - ValidationErrorKind, ValidationErrorKind::*, + ErrorHandled, ExpectedKind, InterpError, InterpErrorInfo, InvalidMetaKind, Misalignment, + PointerKind, ValidationErrorInfo, ValidationErrorKind, ValidationErrorKind::*, }; +use rustc_middle::mir::pretty::write_allocation_bytes; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::{ - Abi, FieldIdx, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange, + self, Abi, FieldIdx, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange, }; use std::hash::Hash; +use crate::errors; + use super::{ AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar, ValueVisitor, @@ -967,6 +970,36 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(()) } + #[inline(always)] + pub fn const_report_error( + &self, + error: InterpErrorInfo<'tcx>, + alloc_id: AllocId, + ) -> ErrorHandled { + let (error, backtrace) = error.into_parts(); + backtrace.print_backtrace(); + + let ub_note = matches!(error, InterpError::UndefinedBehavior(_)).then(|| {}); + + let alloc = self.tcx.global_alloc(alloc_id).unwrap_memory().inner(); + let mut bytes = String::new(); + if alloc.size() != abi::Size::ZERO { + bytes = "\n".into(); + // FIXME(translation) there might be pieces that are translatable. + write_allocation_bytes(*self.tcx, alloc, &mut bytes, " ").unwrap(); + } + let raw_bytes = + errors::RawBytesNote { size: alloc.size().bytes(), align: alloc.align.bytes(), bytes }; + + crate::const_eval::report( + *self.tcx, + error, + None, + || crate::const_eval::get_span_and_frames(self), + move |span, frames| errors::UndefinedBehavior { span, ub_note, frames, raw_bytes }, + ) + } + /// This function checks the data at `op` to be runtime-valid. /// `op` is assumed to cover valid memory if it is an indirect operand. /// It will error if the bits at the destination do not match the ones described by the layout. From ad6e2503661917b37265c174d91f8d24ef39e681 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 10 Oct 2023 08:11:03 +0000 Subject: [PATCH 4/7] Use Result combinators instead of manual matching --- .../rustc_const_eval/src/const_eval/eval_queries.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) 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 a3b430b47db38..aafd988ce1cbc 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -334,13 +334,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>( let alloc_id = mplace.ptr().provenance.unwrap(); - // Validation failed, report an error. - if let Err(error) = validation { - Err(ecx.const_report_error(error, alloc_id)) - } else { + validation + // Validation failed, report an error. + .map_err(|error| ecx.const_report_error(error, alloc_id)) // Convert to raw constant - Ok(ConstAlloc { alloc_id, ty: mplace.layout.ty }) - } + .map(|()| ConstAlloc { alloc_id, ty: mplace.layout.ty }) } } } From b443c22908e15f9848bb1b3e5a29e4f30a46bfd2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 10 Oct 2023 08:35:39 +0000 Subject: [PATCH 5/7] Split `eval_to_allocation_raw_provider` --- .../rustc_const_eval/src/const_eval/eval_queries.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) 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 aafd988ce1cbc..dda01e39c218c 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -284,7 +284,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( let def = cid.instance.def.def_id(); let is_static = tcx.is_static(def); - let mut ecx = InterpCx::new( + let ecx = InterpCx::new( tcx, tcx.def_span(def), key.param_env, @@ -292,7 +292,14 @@ pub fn eval_to_allocation_raw_provider<'tcx>( // they do not have to behave "as if" they were evaluated at runtime. CompileTimeInterpreter::new(CanAccessStatics::from(is_static), CheckAlignment::Error), ); + eval_in_interpreter(ecx, cid, is_static) +} +pub fn eval_in_interpreter<'mir, 'tcx>( + mut ecx: InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, + cid: GlobalId<'tcx>, + is_static: bool, +) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> { let res = ecx.load_mir(cid.instance.def, cid.promoted); match res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body)) { Err(error) => { @@ -305,7 +312,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( // If the current item has generics, we'd like to enrich the message with the // instance and its args: to show the actual compile-time values, in addition to // the expression, leading to the const eval error. - let instance = &key.value.instance; + let instance = &cid.instance; if !instance.args.is_empty() { let instance = with_no_trimmed_paths!(instance.to_string()); ("const_with_path", instance) From 32b6f243f8b50fd0432506e386cb306cf7cc3783 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 12 Oct 2023 08:37:52 +0000 Subject: [PATCH 6/7] Use the dedicated method for evaluating statics This hardens the API against future changes to how we evaluate statics and avoids the explanation around `ParamEnv::reveal_all` --- .../src/interpret/eval_context.rs | 40 +++++++++++++------ src/tools/miri/src/helpers.rs | 6 +-- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 1c2e8d807f4e6..795aa87dcfbb4 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -7,7 +7,7 @@ use hir::CRATE_HIR_ID; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_index::IndexVec; use rustc_middle::mir; -use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo}; +use rustc_middle::mir::interpret::{alloc_range, ErrorHandled, InvalidMetaKind, ReportedErrorInfo}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, @@ -17,6 +17,7 @@ use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_session::Limit; use rustc_span::Span; +use rustc_target::abi::{self, Abi}; use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout}; use super::{ @@ -1069,23 +1070,36 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }) } - pub fn eval_global( + pub fn eval_global_scalar( &self, instance: ty::Instance<'tcx>, - ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { + ) -> InterpResult<'tcx, Scalar> { let gid = GlobalId { instance, promoted: None }; - // For statics we pick `ParamEnv::reveal_all`, because statics don't have generics - // and thus don't care about the parameter environment. While we could just use - // `self.param_env`, that would mean we invoke the query to evaluate the static - // with different parameter environments, thus causing the static to be evaluated - // multiple times. - let param_env = if self.tcx.is_static(gid.instance.def_id()) { - ty::ParamEnv::reveal_all() + let (alloc_id, alloc) = if self.tcx.is_static(gid.instance.def_id()) { + ( + self.tcx.reserve_and_set_static_alloc(gid.instance.def_id()), + self.ctfe_query(|tcx| tcx.eval_static_initializer(gid.instance.def_id()))?, + ) } else { - self.param_env + let val = self.ctfe_query(|tcx| tcx.eval_to_allocation_raw(self.param_env.and(gid)))?; + (val.alloc_id, self.tcx.global_alloc(val.alloc_id).unwrap_memory()) }; - let val = self.ctfe_query(|tcx| tcx.eval_to_allocation_raw(param_env.and(gid)))?; - self.raw_const_to_mplace(val) + + let ty = instance.ty(self.tcx.tcx, self.param_env); + let layout = self.layout_of(ty)?; + let read_provenance = matches!( + layout.abi, + Abi::Scalar(abi::Scalar::Initialized { value: abi::Primitive::Pointer(..), .. }) + ); + + let scalar = alloc + .inner() + .read_scalar(self, alloc_range(Size::ZERO, layout.size), read_provenance) + .map_err(|err| err.to_interp_error(alloc_id))?; + Ok(match scalar { + Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_base_pointer(ptr)?, size), + Scalar::Int(int) => Scalar::Int(int), + }) } pub fn eval_mir_constant( diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 0dc472bc486b8..91ce1dc68efae 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -141,11 +141,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_ref(); let instance = this.resolve_path(path, Namespace::ValueNS); // We don't give a span -- this isn't actually used directly by the program anyway. - let const_val = this.eval_global(instance).unwrap_or_else(|err| { + this.eval_global_scalar(instance).unwrap_or_else(|err| { panic!("failed to evaluate required Rust item: {path:?}\n{err:?}") - }); - this.read_scalar(&const_val) - .unwrap_or_else(|err| panic!("failed to read required Rust item: {path:?}\n{err:?}")) + }) } /// Helper function to get a `libc` constant as a `Scalar`. From 76869b4accf95d231e4c8d18573be27017d5f34e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 12 Oct 2023 11:10:06 +0000 Subject: [PATCH 7/7] Deduplicate const scalar -> machine scalar conversion --- .../src/interpret/eval_context.rs | 5 +---- .../rustc_const_eval/src/interpret/operand.rs | 18 +++++++++++------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 795aa87dcfbb4..b044a0691c1b9 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -1096,10 +1096,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .inner() .read_scalar(self, alloc_range(Size::ZERO, layout.size), read_provenance) .map_err(|err| err.to_interp_error(alloc_id))?; - Ok(match scalar { - Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_base_pointer(ptr)?, size), - Scalar::Int(int) => Scalar::Int(int), - }) + self.adjust_const_scalar(scalar) } pub fn eval_mir_constant( diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 99424518ad46f..644c4806f7ec0 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -723,6 +723,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(op) } + pub(super) fn adjust_const_scalar( + &self, + scalar: Scalar, + ) -> InterpResult<'tcx, Scalar> { + Ok(match scalar { + Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_base_pointer(ptr)?, size), + Scalar::Int(int) => Scalar::Int(int), + }) + } + pub(crate) fn const_val_to_op( &self, val_val: mir::ConstValue<'tcx>, @@ -730,12 +740,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { // Other cases need layout. - let adjust_scalar = |scalar| -> InterpResult<'tcx, _> { - Ok(match scalar { - Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_base_pointer(ptr)?, size), - Scalar::Int(int) => Scalar::Int(int), - }) - }; let layout = from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty))?; let imm = match val_val { mir::ConstValue::Indirect { alloc_id, offset } => { @@ -744,7 +748,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ptr = self.global_base_pointer(Pointer::new(alloc_id, offset))?; return Ok(self.ptr_to_mplace(ptr.into(), layout).into()); } - mir::ConstValue::Scalar(x) => adjust_scalar(x)?.into(), + mir::ConstValue::Scalar(x) => self.adjust_const_scalar(x)?.into(), mir::ConstValue::ZeroSized => Immediate::Uninit, mir::ConstValue::Slice { data, meta } => { // We rely on mutability being set correctly in `data` to prevent writes