From 871513d02cf4d5c40689052aa7a1f3681fc3fdcc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 1 Jun 2020 08:42:40 +0200 Subject: [PATCH 1/7] make miri memory TyCtxtAt a TyCtxt --- src/librustc_mir/interpret/eval_context.rs | 3 +-- src/librustc_mir/interpret/memory.rs | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 6497e211de3..844f2ea0702 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -301,7 +301,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { machine, tcx, param_env, - memory: Memory::new(tcx, memory_extra), + memory: Memory::new(*tcx, memory_extra), vtables: FxHashMap::default(), } } @@ -309,7 +309,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub fn set_span(&mut self, span: Span) { self.tcx.span = span; - self.memory.tcx.span = span; } #[inline(always)] diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index d7f64542aa7..61dea4d43ce 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -14,7 +14,7 @@ use std::ptr; use rustc_ast::ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_middle::ty::{self, query::TyCtxtAt, Instance, ParamEnv}; +use rustc_middle::ty::{self, TyCtxt, Instance, ParamEnv}; use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout}; use super::{ @@ -115,7 +115,7 @@ pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub extra: M::MemoryExtra, /// Lets us implement `HasDataLayout`, which is awfully convenient. - pub tcx: TyCtxtAt<'tcx>, + pub tcx: TyCtxt<'tcx>, } impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for Memory<'mir, 'tcx, M> { @@ -126,7 +126,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for Memory<'mir, 'tcx, M> } impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { - pub fn new(tcx: TyCtxtAt<'tcx>, extra: M::MemoryExtra) -> Self { + pub fn new(tcx: TyCtxt<'tcx>, extra: M::MemoryExtra) -> Self { Memory { alloc_map: M::MemoryMap::default(), extra_fn_ptr_map: FxHashMap::default(), @@ -425,7 +425,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { /// `M::tag_allocation`. fn get_global_alloc( memory_extra: &M::MemoryExtra, - tcx: TyCtxtAt<'tcx>, + tcx: TyCtxt<'tcx>, id: AllocId, is_write: bool, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { @@ -455,7 +455,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { throw_unsup!(ReadForeignStatic(def_id)) } trace!("get_global_alloc: Need to compute {:?}", def_id); - let instance = Instance::mono(tcx.tcx, def_id); + let instance = Instance::mono(tcx, def_id); let gid = GlobalId { instance, promoted: None }; // Use the raw query here to break validation cycles. Later uses of the static // will call the full query anyway. @@ -664,14 +664,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn dump_allocs(&self, mut allocs: Vec) { // Cannot be a closure because it is generic in `Tag`, `Extra`. fn write_allocation_track_relocs<'tcx, Tag: Copy + fmt::Debug, Extra>( - tcx: TyCtxtAt<'tcx>, + tcx: TyCtxt<'tcx>, allocs_to_print: &mut VecDeque, alloc: &Allocation, ) { for &(_, target_id) in alloc.relocations().values() { allocs_to_print.push_back(target_id); } - pretty::write_allocation(tcx.tcx, alloc, &mut std::io::stderr()).unwrap(); + pretty::write_allocation(tcx, alloc, &mut std::io::stderr()).unwrap(); } allocs.sort(); @@ -820,7 +820,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { return Ok(()); } }; - let tcx = self.tcx.tcx; + let tcx = self.tcx; self.get_raw_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src) } @@ -846,7 +846,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { return Ok(()); } }; - let tcx = self.tcx.tcx; + let tcx = self.tcx; let allocation = self.get_raw_mut(ptr.alloc_id)?; for idx in 0..len { @@ -888,7 +888,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { let relocations = self.get_raw(src.alloc_id)?.prepare_relocation_copy(self, src, size, dest, length); - let tcx = self.tcx.tcx; + let tcx = self.tcx; // This checks relocation edges on the src. let src_bytes = From dc6ffaebd5b56793f86443a0a50c06f025321198 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 1 Jun 2020 10:15:17 +0200 Subject: [PATCH 2/7] make miri InterpCx TyCtxtAt a TyCtxt, and separately remember the root span of the evaluation --- src/librustc_middle/ty/util.rs | 1 + src/librustc_mir/const_eval/error.rs | 2 +- src/librustc_mir/const_eval/eval_queries.rs | 21 +++---- src/librustc_mir/interpret/cast.rs | 8 +-- src/librustc_mir/interpret/eval_context.rs | 60 ++++++++++++------- src/librustc_mir/interpret/intern.rs | 18 +++--- src/librustc_mir/interpret/intrinsics.rs | 4 +- .../interpret/intrinsics/caller_location.rs | 4 +- src/librustc_mir/interpret/memory.rs | 2 +- src/librustc_mir/interpret/operand.rs | 16 ++--- src/librustc_mir/interpret/place.rs | 39 ++++++------ src/librustc_mir/interpret/step.rs | 2 - src/librustc_mir/interpret/terminator.rs | 8 +-- src/librustc_mir/interpret/traits.rs | 32 +++++----- src/librustc_mir/transform/const_prop.rs | 15 ++--- 15 files changed, 123 insertions(+), 109 deletions(-) diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs index c2b794ca4bd..29da7ff0850 100644 --- a/src/librustc_middle/ty/util.rs +++ b/src/librustc_middle/ty/util.rs @@ -705,6 +705,7 @@ impl<'tcx> ty::TyS<'tcx> { /// optimization as well as the rules around static values. Note /// that the `Freeze` trait is not exposed to end users and is /// effectively an implementation detail. + // FIXME: use `TyCtxtAt` instead of separate `Span`. pub fn is_freeze( &'tcx self, tcx: TyCtxt<'tcx>, diff --git a/src/librustc_mir/const_eval/error.rs b/src/librustc_mir/const_eval/error.rs index b165a69433d..2aafafd8205 100644 --- a/src/librustc_mir/const_eval/error.rs +++ b/src/librustc_mir/const_eval/error.rs @@ -56,5 +56,5 @@ pub fn error_to_const_error<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>( ) -> ConstEvalErr<'tcx> { error.print_backtrace(); let stacktrace = ecx.generate_stacktrace(); - ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span } + ConstEvalErr { error: error.kind, stacktrace, span: ecx.cur_span() } } diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 2c0a40b4c54..4101ea77c90 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -27,7 +27,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( body: &'mir mir::Body<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx>> { debug!("eval_body_using_ecx: {:?}, {:?}", cid, ecx.param_env); - let tcx = ecx.tcx.tcx; + let tcx = ecx.tcx; let layout = ecx.layout_of(body.return_ty().subst(tcx, cid.instance.substs))?; assert!(!layout.is_unsized()); let ret = ecx.allocate(layout, MemoryKind::Stack); @@ -81,13 +81,14 @@ fn eval_body_using_ecx<'mir, 'tcx>( /// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument. pub(super) fn mk_eval_cx<'mir, 'tcx>( tcx: TyCtxt<'tcx>, - span: Span, + root_span: Span, param_env: ty::ParamEnv<'tcx>, can_access_statics: bool, ) -> CompileTimeEvalContext<'mir, 'tcx> { debug!("mk_eval_cx: {:?}", param_env); InterpCx::new( - tcx.at(span), + tcx, + root_span, param_env, CompileTimeInterpreter::new(tcx.sess.const_eval_limit()), MemoryExtra { can_access_statics }, @@ -163,7 +164,7 @@ pub(super) fn op_to_const<'tcx>( 0, ), }; - let len = b.to_machine_usize(&ecx.tcx.tcx).unwrap(); + let len = b.to_machine_usize(ecx).unwrap(); let start = start.try_into().unwrap(); let len: usize = len.try_into().unwrap(); ConstValue::Slice { data, start, end: start + len } @@ -213,7 +214,7 @@ fn validate_and_turn_into_const<'tcx>( val.map_err(|error| { let err = error_to_const_error(&ecx, error); - err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| { + err.struct_error(ecx.tcx_at(), "it is undefined behavior to use this value", |mut diag| { diag.note(note_on_undefined_behavior_error()); diag.emit(); }) @@ -299,9 +300,9 @@ pub fn const_eval_raw_provider<'tcx>( let is_static = tcx.is_static(def_id); - let span = tcx.def_span(cid.instance.def_id()); let mut ecx = InterpCx::new( - tcx.at(span), + tcx, + tcx.def_span(cid.instance.def_id()), key.param_env, CompileTimeInterpreter::new(tcx.sess.const_eval_limit()), MemoryExtra { can_access_statics: is_static }, @@ -316,7 +317,7 @@ pub fn const_eval_raw_provider<'tcx>( if is_static { // Ensure that if the above error was either `TooGeneric` or `Reported` // an error must be reported. - let v = err.report_as_error(ecx.tcx, "could not evaluate static initializer"); + let v = err.report_as_error(ecx.tcx_at(), "could not evaluate static initializer"); // If this is `Reveal:All`, then we need to make sure an error is reported but if // this is `Reveal::UserFacing`, then it's expected that we could get a @@ -372,13 +373,13 @@ pub fn const_eval_raw_provider<'tcx>( // anything else (array lengths, enum initializers, constant patterns) are // reported as hard errors } else { - err.report_as_error(ecx.tcx, "evaluation of constant value failed") + err.report_as_error(ecx.tcx_at(), "evaluation of constant value failed") } } } } else { // use of broken constant from other crate - err.report_as_error(ecx.tcx, "could not evaluate constant") + err.report_as_error(ecx.tcx_at(), "could not evaluate constant") } }) } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 0fd695586eb..287b43ac50f 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -56,7 +56,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } let instance = ty::Instance::resolve_for_fn_ptr( - *self.tcx, + self.tcx, self.param_env, def_id, substs, @@ -91,7 +91,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } let instance = ty::Instance::resolve_closure( - *self.tcx, + self.tcx, def_id, substs, ty::ClosureKind::FnOnce, @@ -140,7 +140,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Handle cast from a univariant (ZST) enum. match src.layout.variants { Variants::Single { index } => { - if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) { + if let Some(discr) = src.layout.ty.discriminant_for_variant(self.tcx, index) { assert!(src.layout.is_zst()); let discr_layout = self.layout_of(discr.ty)?; return Ok(self.cast_from_scalar(discr.val, discr_layout, cast_ty).into()); @@ -270,7 +270,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // u64 cast is from usize to u64, which is always good let val = Immediate::new_slice( ptr, - length.eval_usize(self.tcx.tcx, self.param_env), + length.eval_usize(self.tcx, self.param_env), self, ); self.write_immediate(val, dest) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 844f2ea0702..1715b6fede9 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -33,7 +33,11 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub machine: M, /// The results of the type checker, from rustc. - pub tcx: TyCtxtAt<'tcx>, + pub tcx: TyCtxt<'tcx>, + + /// The span of the "root" of the evaluation, i.e., the const + /// we are evaluating (if this is CTFE). + pub(super) root_span: Span, /// Bounds in scope for polymorphic evaluations. pub(crate) param_env: ty::ParamEnv<'tcx>, @@ -196,7 +200,7 @@ where { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { - *self.tcx + self.tcx } } @@ -209,13 +213,13 @@ where } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { +impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { type Ty = Ty<'tcx>; type TyAndLayout = InterpResult<'tcx, TyAndLayout<'tcx>>; #[inline] fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.tcx + self.tcx_at() .layout_of(self.param_env.and(ty)) .map_err(|layout| err_inval!(Layout(layout)).into()) } @@ -292,7 +296,8 @@ pub(super) fn from_known_layout<'tcx>( impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn new( - tcx: TyCtxtAt<'tcx>, + tcx: TyCtxt<'tcx>, + root_span: Span, param_env: ty::ParamEnv<'tcx>, machine: M, memory_extra: M::MemoryExtra, @@ -300,15 +305,26 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { InterpCx { machine, tcx, + root_span, param_env, - memory: Memory::new(*tcx, memory_extra), + memory: Memory::new(tcx, memory_extra), vtables: FxHashMap::default(), } } #[inline(always)] - pub fn set_span(&mut self, span: Span) { - self.tcx.span = span; + pub fn cur_span(&self) -> Span { + self + .stack() + .last() + .and_then(|f| f.current_source_info()) + .map(|si| si.span) + .unwrap_or(self.root_span) + } + + #[inline(always)] + pub fn tcx_at(&self) -> TyCtxtAt<'tcx> { + self.tcx.at(self.cur_span()) } #[inline(always)] @@ -386,12 +402,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline] pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - ty.is_sized(self.tcx, self.param_env) + ty.is_sized(self.tcx_at(), self.param_env) } #[inline] pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - ty.is_freeze(*self.tcx, self.param_env, DUMMY_SP) + ty.is_freeze(self.tcx, self.param_env, self.cur_span()) } pub fn load_mir( @@ -402,20 +418,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // do not continue if typeck errors occurred (can only occur in local crate) let did = instance.def_id(); if let Some(did) = did.as_local() { - if self.tcx.has_typeck_tables(did) { - if let Some(error_reported) = self.tcx.typeck_tables_of(did).tainted_by_errors { + if self.tcx_at().has_typeck_tables(did) { + if let Some(error_reported) = self.tcx_at().typeck_tables_of(did).tainted_by_errors { throw_inval!(TypeckError(error_reported)) } } } trace!("load mir(instance={:?}, promoted={:?})", instance, promoted); if let Some(promoted) = promoted { - return Ok(&self.tcx.promoted_mir(did)[promoted]); + return Ok(&self.tcx_at().promoted_mir(did)[promoted]); } match instance { ty::InstanceDef::Item(def_id) => { - if self.tcx.is_mir_available(did) { - Ok(self.tcx.optimized_mir(did)) + if self.tcx_at().is_mir_available(did) { + Ok(self.tcx_at().optimized_mir(did)) } else { throw_unsup!(NoMirFor(def_id)) } @@ -456,7 +472,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("resolve: {:?}, {:#?}", def_id, substs); trace!("param_env: {:#?}", self.param_env); trace!("substs: {:#?}", substs); - match ty::Instance::resolve(*self.tcx, self.param_env, def_id, substs) { + match ty::Instance::resolve(self.tcx, self.param_env, def_id, substs) { Ok(Some(instance)) => Ok(instance), Ok(None) => throw_inval!(TooGeneric), @@ -475,7 +491,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // have to support that case (mostly by skipping all caching). match frame.locals.get(local).and_then(|state| state.layout.get()) { None => { - let layout = from_known_layout(self.tcx, layout, || { + let layout = from_known_layout(self.tcx_at(), layout, || { let local_ty = frame.body.local_decls[local].ty; let local_ty = self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty); @@ -560,7 +576,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let size = size.align_to(align); // Check if this brought us over the size limit. - if size.bytes() >= self.tcx.data_layout().obj_size_bound() { + if size.bytes() >= self.tcx.data_layout.obj_size_bound() { throw_ub!(InvalidMeta("total size is bigger than largest supported object")); } Ok(Some((size, align))) @@ -576,7 +592,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let elem = layout.field(self, 0)?; // Make sure the slice is not too big. - let size = elem.size.checked_mul(len, &*self.tcx).ok_or_else(|| { + let size = elem.size.checked_mul(len, self).ok_or_else(|| { err_ub!(InvalidMeta("slice is bigger than largest supported object")) })?; Ok(Some((size, elem.align.abi))) @@ -627,7 +643,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let mut locals = IndexVec::from_elem(dummy, &body.local_decls); // Now mark those locals as dead that we do not want to initialize - match self.tcx.def_kind(instance.def_id()) { + match self.tcx_at().def_kind(instance.def_id()) { // statics and constants don't have `Storage*` statements, no need to look for them // // FIXME: The above is likely untrue. See @@ -842,7 +858,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.param_env }; - let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.tcx.span))?; + let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.cur_span()))?; // Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a // recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not @@ -873,7 +889,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME: We can hit delay_span_bug if this is an invalid const, interning finds // that problem, but we never run validation to show an error. Can we ensure // this does not happen? - let val = self.tcx.const_eval_raw(param_env.and(gid))?; + let val = self.tcx_at().const_eval_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) } diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 02a7f24a1e3..284a1d5ea61 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -93,7 +93,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>( // in the value the dangling reference lies. // The `delay_span_bug` ensures that we don't forget such a check in validation. if tcx.get_global_alloc(alloc_id).is_none() { - tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer"); + tcx.sess.delay_span_bug(ecx.root_span, "tried to intern dangling pointer"); } // treat dangling pointers like other statics // just to stop trying to recurse into them @@ -111,7 +111,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>( if let InternMode::Static(mutability) = mode { // For this, we need to take into account `UnsafeCell`. When `ty` is `None`, we assume // no interior mutability. - let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx.tcx, ecx.param_env, ecx.tcx.span)); + let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx, ecx.param_env, ecx.root_span)); // For statics, allocation mutability is the combination of the place mutability and // the type mutability. // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere. @@ -174,7 +174,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir // they caused. It also helps us to find cases where const-checking // failed to prevent an `UnsafeCell` (but as `ignore_interior_mut_in_const` // shows that part is not airtight). - mutable_memory_in_const(self.ecx.tcx, "`UnsafeCell`"); + mutable_memory_in_const(self.ecx.tcx_at(), "`UnsafeCell`"); } // We are crossing over an `UnsafeCell`, we can mutate again. This means that // References we encounter inside here are interned as pointing to mutable @@ -192,7 +192,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir fn visit_value(&mut self, mplace: MPlaceTy<'tcx>) -> InterpResult<'tcx> { // Handle Reference types, as these are the only relocations supported by const eval. // Raw pointers (and boxes) are handled by the `leftover_relocations` logic. - let tcx = self.ecx.tcx; + let tcx = self.ecx.tcx.at(self.ecx.root_span); let ty = mplace.layout.ty; if let ty::Ref(_, referenced_ty, ref_mutability) = ty.kind { let value = self.ecx.read_immediate(mplace.into())?; @@ -254,7 +254,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir if ref_mutability == Mutability::Mut { match referenced_ty.kind { ty::Array(_, n) - if n.eval_usize(tcx.tcx, self.ecx.param_env) == 0 => {} + if n.eval_usize(self.ecx.tcx, self.ecx.param_env) == 0 => {} ty::Slice(_) if mplace.meta.unwrap_meta().to_machine_usize(self.ecx)? == 0 => {} @@ -358,7 +358,7 @@ pub fn intern_const_alloc_recursive>( Ok(()) => {} Err(error) => { ecx.tcx.sess.delay_span_bug( - ecx.tcx.span, + ecx.root_span, "error during interning should later cause validation failure", ); // Some errors shouldn't come up because creating them causes @@ -407,7 +407,7 @@ pub fn intern_const_alloc_recursive>( // such as `const CONST_RAW: *const Vec = &Vec::new() as *const _;`. ecx.tcx .sess - .span_err(ecx.tcx.span, "untyped pointers are not allowed in constant"); + .span_err(ecx.root_span, "untyped pointers are not allowed in constant"); // For better errors later, mark the allocation as immutable. alloc.mutability = Mutability::Not; } @@ -422,11 +422,11 @@ pub fn intern_const_alloc_recursive>( } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) { // Codegen does not like dangling pointers, and generally `tcx` assumes that // all allocations referenced anywhere actually exist. So, make sure we error here. - ecx.tcx.sess.span_err(ecx.tcx.span, "encountered dangling pointer in final constant"); + ecx.tcx.sess.span_err(ecx.root_span, "encountered dangling pointer in final constant"); } else if ecx.tcx.get_global_alloc(alloc_id).is_none() { // We have hit an `AllocId` that is neither in local or global memory and isn't // marked as dangling by local memory. That should be impossible. - span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); + span_bug!(ecx.root_span, "encountered unknown alloc id {:?}", alloc_id); } } } diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 115a472cabe..c62fd316dc5 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -347,7 +347,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let index = u64::from(self.read_scalar(args[1])?.to_u32()?); let elem = args[2]; let input = args[0]; - let (len, e_ty) = input.layout.ty.simd_size_and_type(self.tcx.tcx); + let (len, e_ty) = input.layout.ty.simd_size_and_type(self.tcx); assert!( index < len, "Index `{}` must be in bounds of vector type `{}`: `[0, {})`", @@ -374,7 +374,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } sym::simd_extract => { let index = u64::from(self.read_scalar(args[1])?.to_u32()?); - let (len, e_ty) = args[0].layout.ty.simd_size_and_type(self.tcx.tcx); + let (len, e_ty) = args[0].layout.ty.simd_size_and_type(self.tcx); assert!( index < len, "index `{}` is out-of-bounds of vector type `{}` with length `{}`", diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/src/librustc_mir/interpret/intrinsics/caller_location.rs index ddeed92f851..193d38dc552 100644 --- a/src/librustc_mir/interpret/intrinsics/caller_location.rs +++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs @@ -25,7 +25,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { "find_closest_untracked_caller_location: checking frame {:?}", frame.instance ); - !frame.instance.def.requires_caller_location(*self.tcx) + !frame.instance.def.requires_caller_location(self.tcx) }) // Assert that there is always such a frame. .unwrap(); @@ -58,7 +58,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let loc_ty = self .tcx .type_of(self.tcx.require_lang_item(PanicLocationLangItem, None)) - .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); + .subst(self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); let loc_layout = self.layout_of(loc_ty).unwrap(); let location = self.allocate(loc_layout, MemoryKind::CallerLocation); diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 61dea4d43ce..8af1a8ac608 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -14,7 +14,7 @@ use std::ptr; use rustc_ast::ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_middle::ty::{self, TyCtxt, Instance, ParamEnv}; +use rustc_middle::ty::{self, Instance, ParamEnv, TyCtxt}; use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout}; use super::{ diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index db4473154c4..c9250098fed 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -471,9 +471,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("eval_place_to_op: got {:?}", *op); // Sanity-check the type we ended up with. debug_assert!(mir_assign_valid_types( - *self.tcx, + self.tcx, self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions( - place.ty(&self.frame().body.local_decls, *self.tcx).ty + place.ty(&self.frame().body.local_decls, self.tcx).ty ))?, op.layout, )); @@ -554,7 +554,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // documentation). let val_val = M::adjust_global_const(self, val_val)?; // Other cases need layout. - let layout = from_known_layout(self.tcx, layout, || self.layout_of(val.ty))?; + let layout = from_known_layout(self.tcx_at(), layout, || self.layout_of(val.ty))?; let op = match val_val { ConstValue::ByRef { alloc, offset } => { let id = self.tcx.create_memory_alloc(alloc); @@ -589,7 +589,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("read_discriminant_value {:#?}", op.layout); // Get type and layout of the discriminant. - let discr_layout = self.layout_of(op.layout.ty.discriminant_ty(*self.tcx))?; + let discr_layout = self.layout_of(op.layout.ty.discriminant_ty(self.tcx))?; trace!("discriminant type: {:?}", discr_layout.ty); // We use "discriminant" to refer to the value associated with a particular enum variant. @@ -601,7 +601,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // rather confusing. let (tag_scalar_layout, tag_kind, tag_index) = match op.layout.variants { Variants::Single { index } => { - let discr = match op.layout.ty.discriminant_for_variant(*self.tcx, index) { + let discr = match op.layout.ty.discriminant_for_variant(self.tcx, index) { Some(discr) => { // This type actually has discriminants. assert_eq!(discr.ty, discr_layout.ty); @@ -630,7 +630,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // may be a pointer. This is `tag_val.layout`; we just use it for sanity checks. // Get layout for tag. - let tag_layout = self.layout_of(tag_scalar_layout.value.to_int_ty(*self.tcx))?; + let tag_layout = self.layout_of(tag_scalar_layout.value.to_int_ty(self.tcx))?; // Read tag and sanity-check `tag_layout`. let tag_val = self.read_immediate(self.operand_field(op, tag_index)?)?; @@ -651,12 +651,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Convert discriminant to variant index, and catch invalid discriminants. let index = match op.layout.ty.kind { ty::Adt(adt, _) => { - adt.discriminants(self.tcx.tcx).find(|(_, var)| var.val == discr_bits) + adt.discriminants(self.tcx).find(|(_, var)| var.val == discr_bits) } ty::Generator(def_id, substs, _) => { let substs = substs.as_generator(); substs - .discriminants(def_id, self.tcx.tcx) + .discriminants(def_id, self.tcx) .find(|(_, var)| var.val == discr_bits) } _ => bug!("tagged layout for non-adt non-generator"), diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 3f0800b12b5..0b4e92574a0 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -404,7 +404,7 @@ where // to get some code to work that probably ought to work. field_layout.align.abi } - None => bug!("Cannot compute offset for extern type field at non-0 offset"), + None => span_bug!(self.cur_span(), "cannot compute offset for extern type field at non-0 offset"), }; (base.meta, offset.align_to(align)) } else { @@ -440,7 +440,7 @@ where assert!(!field_layout.is_unsized()); base.offset(offset, MemPlaceMeta::None, field_layout, self) } - _ => bug!("`mplace_index` called on non-array type {:?}", base.layout.ty), + _ => span_bug!(self.cur_span(), "`mplace_index` called on non-array type {:?}", base.layout.ty), } } @@ -454,7 +454,7 @@ where let len = base.len(self)?; // also asserts that we have a type where this makes sense let stride = match base.layout.fields { FieldsShape::Array { stride, .. } => stride, - _ => bug!("mplace_array_fields: expected an array layout"), + _ => span_bug!(self.cur_span(), "mplace_array_fields: expected an array layout"), }; let layout = base.layout.field(self, 0)?; let dl = &self.tcx.data_layout; @@ -484,7 +484,7 @@ where // (that have count 0 in their layout). let from_offset = match base.layout.fields { FieldsShape::Array { stride, .. } => stride * from, // `Size` multiplication is checked - _ => bug!("Unexpected layout of index access: {:#?}", base.layout), + _ => span_bug!(self.cur_span(), "unexpected layout of index access: {:#?}", base.layout), }; // Compute meta and new layout @@ -497,7 +497,7 @@ where let len = Scalar::from_machine_usize(inner_len, self); (MemPlaceMeta::Meta(len), base.layout.ty) } - _ => bug!("cannot subslice non-array type: `{:?}`", base.layout.ty), + _ => span_bug!(self.cur_span(), "cannot subslice non-array type: `{:?}`", base.layout.ty), }; let layout = self.layout_of(ty)?; base.offset(from_offset, meta, layout, self) @@ -640,9 +640,9 @@ where self.dump_place(place_ty.place); // Sanity-check the type we ended up with. debug_assert!(mir_assign_valid_types( - *self.tcx, + self.tcx, self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions( - place.ty(&self.frame().body.local_decls, *self.tcx).ty + place.ty(&self.frame().body.local_decls, self.tcx).ty ))?, place_ty.layout, )); @@ -768,7 +768,7 @@ where None => return Ok(()), // zero-sized access }; - let tcx = &*self.tcx; + let tcx = self.tcx; // FIXME: We should check that there are dest.layout.size many bytes available in // memory. The code below is not sufficient, with enough padding it might not // cover all the bytes! @@ -777,11 +777,11 @@ where match dest.layout.abi { Abi::Scalar(_) => {} // fine _ => { - bug!("write_immediate_to_mplace: invalid Scalar layout: {:#?}", dest.layout) + span_bug!(self.cur_span(), "write_immediate_to_mplace: invalid Scalar layout: {:#?}", dest.layout) } } self.memory.get_raw_mut(ptr.alloc_id)?.write_scalar( - tcx, + &tcx, ptr, scalar, dest.layout.size, @@ -793,7 +793,8 @@ where // which `ptr.offset(b_offset)` cannot possibly fail to satisfy. let (a, b) = match dest.layout.abi { Abi::ScalarPair(ref a, ref b) => (&a.value, &b.value), - _ => bug!( + _ => span_bug!( + self.cur_span(), "write_immediate_to_mplace: invalid ScalarPair layout: {:#?}", dest.layout ), @@ -806,8 +807,8 @@ where // but that does not work: We could be a newtype around a pair, then the // fields do not match the `ScalarPair` components. - self.memory.get_raw_mut(ptr.alloc_id)?.write_scalar(tcx, ptr, a_val, a_size)?; - self.memory.get_raw_mut(b_ptr.alloc_id)?.write_scalar(tcx, b_ptr, b_val, b_size) + self.memory.get_raw_mut(ptr.alloc_id)?.write_scalar(&tcx, ptr, a_val, a_size)?; + self.memory.get_raw_mut(b_ptr.alloc_id)?.write_scalar(&tcx, b_ptr, b_val, b_size) } } } @@ -841,9 +842,9 @@ where ) -> InterpResult<'tcx> { // We do NOT compare the types for equality, because well-typed code can // actually "transmute" `&mut T` to `&T` in an assignment without a cast. - if !mir_assign_valid_types(self.tcx.tcx, src.layout, dest.layout) { + if !mir_assign_valid_types(self.tcx, src.layout, dest.layout) { span_bug!( - self.tcx.span, + self.cur_span(), "type mismatch when copying!\nsrc: {:?},\ndest: {:?}", src.layout.ty, dest.layout.ty, @@ -898,7 +899,7 @@ where src: OpTy<'tcx, M::PointerTag>, dest: PlaceTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx> { - if mir_assign_valid_types(self.tcx.tcx, src.layout, dest.layout) { + if mir_assign_valid_types(self.tcx, src.layout, dest.layout) { // Fast path: Just use normal `copy_op` return self.copy_op(src, dest); } @@ -910,7 +911,7 @@ where // on `typeck_tables().has_errors` at all const eval entry points. debug!("Size mismatch when transmuting!\nsrc: {:#?}\ndest: {:#?}", src, dest); self.tcx.sess.delay_span_bug( - self.tcx.span, + self.cur_span(), "size-changing transmute, should have been caught by transmute checking", ); throw_inval!(TransmuteSizeDiff(src.layout.ty, dest.layout.ty)); @@ -1056,7 +1057,7 @@ where // `TyAndLayout::for_variant()` call earlier already checks the variant is valid. let discr_val = - dest.layout.ty.discriminant_for_variant(*self.tcx, variant_index).unwrap().val; + dest.layout.ty.discriminant_for_variant(self.tcx, variant_index).unwrap().val; // raw discriminants for enums are isize or bigger during // their computation, but the in-memory tag is the smallest possible @@ -1085,7 +1086,7 @@ where .expect("overflow computing relative variant idx"); // We need to use machine arithmetic when taking into account `niche_start`: // discr_val = variant_index_relative + niche_start_val - let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?; + let discr_layout = self.layout_of(discr_layout.value.to_int_ty(self.tcx))?; let niche_start_val = ImmTy::from_uint(niche_start, discr_layout); let variant_index_relative_val = ImmTy::from_uint(variant_index_relative, discr_layout); diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 02a709ab1a1..16c6396799e 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -76,7 +76,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> InterpResult<'tcx> { info!("{:?}", stmt); - self.set_span(stmt.source_info.span); use rustc_middle::mir::StatementKind::*; @@ -279,7 +278,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> InterpResult<'tcx> { info!("{:?}", terminator.kind); - self.set_span(terminator.source_info.span); self.eval_terminator(terminator)?; if !self.stack().is_empty() { diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index cd7621ea975..9a4dd0a5204 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -69,7 +69,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (fn_val, caller_abi) } ty::FnDef(def_id, substs) => { - let sig = func.layout.ty.fn_sig(*self.tcx); + let sig = func.layout.ty.fn_sig(self.tcx); (FnVal::Instance(self.resolve(def_id, substs)?), sig.abi()) } _ => span_bug!( @@ -96,7 +96,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ty = place.layout.ty; trace!("TerminatorKind::drop: {:?}, type {}", location, ty); - let instance = Instance::resolve_drop_in_place(*self.tcx, ty); + let instance = Instance::resolve_drop_in_place(self.tcx, ty); self.drop_in_place(place, instance, target, unwind)?; } @@ -227,9 +227,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // ABI check { let callee_abi = { - let instance_ty = instance.ty_env(*self.tcx, self.param_env); + let instance_ty = instance.ty_env(self.tcx, self.param_env); match instance_ty.kind { - ty::FnDef(..) => instance_ty.fn_sig(*self.tcx).abi(), + ty::FnDef(..) => instance_ty.fn_sig(self.tcx).abi(), ty::Closure(..) => Abi::RustCall, ty::Generator(..) => Abi::Rust, _ => bug!("unexpected callee ty: {:?}", instance_ty), diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index b9f9d37df76..87493a8d383 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -2,7 +2,7 @@ use std::convert::TryFrom; use rustc_middle::mir::interpret::{InterpResult, Pointer, PointerArithmetic, Scalar}; use rustc_middle::ty::{self, Instance, Ty, TypeFoldable}; -use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size}; +use rustc_target::abi::{Align, LayoutOf, Size}; use super::{FnVal, InterpCx, Machine, MemoryKind}; @@ -36,10 +36,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } let methods = if let Some(poly_trait_ref) = poly_trait_ref { - let trait_ref = poly_trait_ref.with_self_ty(*self.tcx, ty); + let trait_ref = poly_trait_ref.with_self_ty(self.tcx, ty); let trait_ref = self.tcx.erase_regions(&trait_ref); - self.tcx.vtable_methods(trait_ref) + self.tcx_at().vtable_methods(trait_ref) } else { &[] }; @@ -49,8 +49,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let size = layout.size.bytes(); let align = layout.align.abi.bytes(); + let tcx = self.tcx; let ptr_size = self.pointer_size(); - let ptr_align = self.tcx.data_layout.pointer_align.abi; + let ptr_align = tcx.data_layout.pointer_align.abi; // ///////////////////////////////////////////////////////////////////////////////////////// // If you touch this code, be sure to also make the corresponding changes to // `get_vtable` in `rust_codegen_llvm/meth.rs`. @@ -60,33 +61,32 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ptr_align, MemoryKind::Vtable, ); - let tcx = &*self.tcx; - let drop = Instance::resolve_drop_in_place(*tcx, ty); + let drop = Instance::resolve_drop_in_place(tcx, ty); let drop = self.memory.create_fn_alloc(FnVal::Instance(drop)); // No need to do any alignment checks on the memory accesses below, because we know the // allocation is correctly aligned as we created it above. Also we're only offsetting by // multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`. let vtable_alloc = self.memory.get_raw_mut(vtable.alloc_id)?; - vtable_alloc.write_ptr_sized(tcx, vtable, drop.into())?; + vtable_alloc.write_ptr_sized(&tcx, vtable, drop.into())?; - let size_ptr = vtable.offset(ptr_size, tcx)?; - vtable_alloc.write_ptr_sized(tcx, size_ptr, Scalar::from_uint(size, ptr_size).into())?; - let align_ptr = vtable.offset(ptr_size * 2, tcx)?; - vtable_alloc.write_ptr_sized(tcx, align_ptr, Scalar::from_uint(align, ptr_size).into())?; + let size_ptr = vtable.offset(ptr_size, &tcx)?; + vtable_alloc.write_ptr_sized(&tcx, size_ptr, Scalar::from_uint(size, ptr_size).into())?; + let align_ptr = vtable.offset(ptr_size * 2, &tcx)?; + vtable_alloc.write_ptr_sized(&tcx, align_ptr, Scalar::from_uint(align, ptr_size).into())?; for (i, method) in methods.iter().enumerate() { if let Some((def_id, substs)) = *method { // resolve for vtable: insert shims where needed let instance = - ty::Instance::resolve_for_vtable(*tcx, self.param_env, def_id, substs) + ty::Instance::resolve_for_vtable(tcx, self.param_env, def_id, substs) .ok_or_else(|| err_inval!(TooGeneric))?; let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); // We cannot use `vtable_allic` as we are creating fn ptrs in this loop. - let method_ptr = vtable.offset(ptr_size * (3 + i as u64), tcx)?; + let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &tcx)?; self.memory.get_raw_mut(vtable.alloc_id)?.write_ptr_sized( - tcx, + &tcx, method_ptr, fn_ptr.into(), )?; @@ -142,7 +142,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // to determine the type. let drop_instance = self.memory.get_fn(drop_fn)?.as_instance()?; trace!("Found drop fn: {:?}", drop_instance); - let fn_sig = drop_instance.ty_env(*self.tcx, self.param_env).fn_sig(*self.tcx); + let fn_sig = drop_instance.ty_env(self.tcx, self.param_env).fn_sig(self.tcx); let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, &fn_sig); // The drop function takes `*mut T` where `T` is the type being dropped, so get that. let args = fn_sig.inputs(); @@ -171,7 +171,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { alloc.read_ptr_sized(self, vtable.offset(pointer_size * 2, self)?)?.not_undef()?; let align = u64::try_from(self.force_bits(align, pointer_size)?).unwrap(); - if size >= self.tcx.data_layout().obj_size_bound() { + if size >= self.tcx.data_layout.obj_size_bound() { throw_ub_format!( "invalid vtable: \ size is bigger than largest supported object" diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 0ff60cbd55d..133c05fc2f9 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -313,7 +313,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let param_env = tcx.param_env(def_id).with_reveal_all(); let span = tcx.def_span(def_id); - let mut ecx = InterpCx::new(tcx.at(span), param_env, ConstPropMachine::new(), ()); + let mut ecx = InterpCx::new(tcx, span, param_env, ConstPropMachine::new(), ()); let can_const_prop = CanConstProp::check(body); let ret = ecx @@ -404,8 +404,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { match self.ecx.eval_const_to_op(c.literal, None) { Ok(op) => Some(op), Err(error) => { - // Make sure errors point at the constant. - self.ecx.set_span(c.span); + let tcx = self.ecx.tcx.at(c.span); let err = error_to_const_error(&self.ecx, error); if let Some(lint_root) = self.lint_root(source_info) { let lint_only = match c.literal.val { @@ -419,16 +418,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Out of backwards compatibility we cannot report hard errors in unused // generic functions using associated constants of the generic parameters. err.report_as_lint( - self.ecx.tcx, + tcx, "erroneous constant used", lint_root, Some(c.span), ); } else { - err.report_as_error(self.ecx.tcx, "erroneous constant used"); + err.report_as_error(tcx, "erroneous constant used"); } } else { - err.report_as_error(self.ecx.tcx, "erroneous constant used"); + err.report_as_error(tcx, "erroneous constant used"); } None } @@ -851,7 +850,6 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { trace!("visit_statement: {:?}", statement); let source_info = statement.source_info; - self.ecx.set_span(source_info.span); self.source_info = Some(source_info); if let StatementKind::Assign(box (place, ref mut rval)) = statement.kind { let place_ty: Ty<'tcx> = place.ty(&self.local_decls, self.tcx).ty; @@ -864,7 +862,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { if let Some(value) = self.get_const(place) { if self.should_const_prop(value) { trace!("replacing {:?} with {:?}", rval, value); - self.replace_with_const(rval, value, statement.source_info); + self.replace_with_const(rval, value, source_info); if can_const_prop == ConstPropMode::FullConstProp || can_const_prop == ConstPropMode::OnlyInsideOwnBlock { @@ -927,7 +925,6 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { let source_info = terminator.source_info; - self.ecx.set_span(source_info.span); self.source_info = Some(source_info); self.super_terminator(terminator, location); match &mut terminator.kind { From 0ac6fd0405c2f3defa9ad8ee3d4026469fbda018 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 1 Jun 2020 11:17:38 +0200 Subject: [PATCH 3/7] fix const_prop spans and re-bless tests --- src/librustc_mir/const_eval/error.rs | 5 ++-- src/librustc_mir/const_eval/eval_queries.rs | 4 +-- src/librustc_mir/interpret/cast.rs | 7 ++--- src/librustc_mir/interpret/eval_context.rs | 6 ++--- src/librustc_mir/interpret/place.rs | 27 ++++++++++++++----- src/librustc_mir/transform/const_prop.rs | 9 ++----- .../ui/consts/const-eval/infinite_loop.stderr | 4 +-- .../const_eval_limit_reached.stderr | 23 +++++++++------- .../recursive-zst-static.default.stderr | 4 +-- .../recursive-zst-static.unleash.stderr | 4 +-- .../consts/uninhabited-const-issue-61744.rs | 4 +-- .../uninhabited-const-issue-61744.stderr | 8 +++--- .../recursive-static-definition.stderr | 4 +-- .../ui/write-to-static-mut-in-static.stderr | 4 +-- 14 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/librustc_mir/const_eval/error.rs b/src/librustc_mir/const_eval/error.rs index 2aafafd8205..5deae94fe0c 100644 --- a/src/librustc_mir/const_eval/error.rs +++ b/src/librustc_mir/const_eval/error.rs @@ -2,7 +2,7 @@ use std::error::Error; use std::fmt; use rustc_middle::mir::AssertKind; -use rustc_span::Symbol; +use rustc_span::{Span, Symbol}; use super::InterpCx; use crate::interpret::{ConstEvalErr, InterpErrorInfo, Machine}; @@ -53,8 +53,9 @@ impl Error for ConstEvalErrKind {} pub fn error_to_const_error<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>( ecx: &InterpCx<'mir, 'tcx, M>, error: InterpErrorInfo<'tcx>, + span: Option, ) -> ConstEvalErr<'tcx> { error.print_backtrace(); let stacktrace = ecx.generate_stacktrace(); - ConstEvalErr { error: error.kind, stacktrace, span: ecx.cur_span() } + ConstEvalErr { error: error.kind, stacktrace, span: span.unwrap_or_else(|| ecx.cur_span()) } } diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 4101ea77c90..28e77bb57cd 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -213,7 +213,7 @@ fn validate_and_turn_into_const<'tcx>( })(); val.map_err(|error| { - let err = error_to_const_error(&ecx, error); + let err = error_to_const_error(&ecx, error, None); err.struct_error(ecx.tcx_at(), "it is undefined behavior to use this value", |mut diag| { diag.note(note_on_undefined_behavior_error()); diag.emit(); @@ -312,7 +312,7 @@ pub fn const_eval_raw_provider<'tcx>( res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body)) .map(|place| RawConst { alloc_id: place.ptr.assert_ptr().alloc_id, ty: place.layout.ty }) .map_err(|error| { - let err = error_to_const_error(&ecx, error); + let err = error_to_const_error(&ecx, error, None); // errors in statics are always emitted as fatal errors if is_static { // Ensure that if the above error was either `TooGeneric` or `Reported` diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 287b43ac50f..793a67d804c 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -268,11 +268,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (&ty::Array(_, length), &ty::Slice(_)) => { let ptr = self.read_immediate(src)?.to_scalar()?; // u64 cast is from usize to u64, which is always good - let val = Immediate::new_slice( - ptr, - length.eval_usize(self.tcx, self.param_env), - self, - ); + let val = + Immediate::new_slice(ptr, length.eval_usize(self.tcx, self.param_env), self); self.write_immediate(val, dest) } (&ty::Dynamic(..), &ty::Dynamic(..)) => { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 1715b6fede9..47e791854df 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -314,8 +314,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub fn cur_span(&self) -> Span { - self - .stack() + self.stack() .last() .and_then(|f| f.current_source_info()) .map(|si| si.span) @@ -419,7 +418,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let did = instance.def_id(); if let Some(did) = did.as_local() { if self.tcx_at().has_typeck_tables(did) { - if let Some(error_reported) = self.tcx_at().typeck_tables_of(did).tainted_by_errors { + if let Some(error_reported) = self.tcx_at().typeck_tables_of(did).tainted_by_errors + { throw_inval!(TypeckError(error_reported)) } } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 0b4e92574a0..2477100eb8a 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -404,7 +404,10 @@ where // to get some code to work that probably ought to work. field_layout.align.abi } - None => span_bug!(self.cur_span(), "cannot compute offset for extern type field at non-0 offset"), + None => span_bug!( + self.cur_span(), + "cannot compute offset for extern type field at non-0 offset" + ), }; (base.meta, offset.align_to(align)) } else { @@ -440,7 +443,11 @@ where assert!(!field_layout.is_unsized()); base.offset(offset, MemPlaceMeta::None, field_layout, self) } - _ => span_bug!(self.cur_span(), "`mplace_index` called on non-array type {:?}", base.layout.ty), + _ => span_bug!( + self.cur_span(), + "`mplace_index` called on non-array type {:?}", + base.layout.ty + ), } } @@ -484,7 +491,9 @@ where // (that have count 0 in their layout). let from_offset = match base.layout.fields { FieldsShape::Array { stride, .. } => stride * from, // `Size` multiplication is checked - _ => span_bug!(self.cur_span(), "unexpected layout of index access: {:#?}", base.layout), + _ => { + span_bug!(self.cur_span(), "unexpected layout of index access: {:#?}", base.layout) + } }; // Compute meta and new layout @@ -497,7 +506,9 @@ where let len = Scalar::from_machine_usize(inner_len, self); (MemPlaceMeta::Meta(len), base.layout.ty) } - _ => span_bug!(self.cur_span(), "cannot subslice non-array type: `{:?}`", base.layout.ty), + _ => { + span_bug!(self.cur_span(), "cannot subslice non-array type: `{:?}`", base.layout.ty) + } }; let layout = self.layout_of(ty)?; base.offset(from_offset, meta, layout, self) @@ -776,9 +787,11 @@ where Immediate::Scalar(scalar) => { match dest.layout.abi { Abi::Scalar(_) => {} // fine - _ => { - span_bug!(self.cur_span(), "write_immediate_to_mplace: invalid Scalar layout: {:#?}", dest.layout) - } + _ => span_bug!( + self.cur_span(), + "write_immediate_to_mplace: invalid Scalar layout: {:#?}", + dest.layout + ), } self.memory.get_raw_mut(ptr.alloc_id)?.write_scalar( &tcx, diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 133c05fc2f9..d50f052d405 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -405,7 +405,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Ok(op) => Some(op), Err(error) => { let tcx = self.ecx.tcx.at(c.span); - let err = error_to_const_error(&self.ecx, error); + let err = error_to_const_error(&self.ecx, error, Some(c.span)); if let Some(lint_root) = self.lint_root(source_info) { let lint_only = match c.literal.val { // Promoteds must lint and not error as the user didn't ask for them @@ -417,12 +417,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { if lint_only { // Out of backwards compatibility we cannot report hard errors in unused // generic functions using associated constants of the generic parameters. - err.report_as_lint( - tcx, - "erroneous constant used", - lint_root, - Some(c.span), - ); + err.report_as_lint(tcx, "erroneous constant used", lint_root, Some(c.span)); } else { err.report_as_error(tcx, "erroneous constant used"); } diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index ebdb73c4467..3386e6e588e 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -23,10 +23,10 @@ LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; = help: add `#![feature(const_if_match)]` to the crate attributes to enable error[E0080]: evaluation of constant value failed - --> $DIR/infinite_loop.rs:8:20 + --> $DIR/infinite_loop.rs:8:17 | LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; - | ^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr index be522dd6d5d..8c2190b4e59 100644 --- a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr +++ b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr @@ -1,15 +1,18 @@ error: any use of this value will cause an error - --> $DIR/const_eval_limit_reached.rs:8:11 + --> $DIR/const_eval_limit_reached.rs:8:5 | -LL | / const X: usize = { -LL | | let mut x = 0; -LL | | while x != 1000 { - | | ^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) -LL | | -... | -LL | | x -LL | | }; - | |__- +LL | / const X: usize = { +LL | | let mut x = 0; +LL | | while x != 1000 { + | |_____^ +LL | || +LL | || x += 1; +LL | || } + | ||_____^ exceeded interpreter step limit (see `#[const_eval_limit]`) +LL | | +LL | | x +LL | | }; + | |__- | = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/recursive-zst-static.default.stderr b/src/test/ui/consts/recursive-zst-static.default.stderr index d424b22f000..9042c6f6be1 100644 --- a/src/test/ui/consts/recursive-zst-static.default.stderr +++ b/src/test/ui/consts/recursive-zst-static.default.stderr @@ -1,8 +1,8 @@ error[E0391]: cycle detected when const-evaluating `FOO` - --> $DIR/recursive-zst-static.rs:10:18 + --> $DIR/recursive-zst-static.rs:10:1 | LL | static FOO: () = FOO; - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires const-evaluating `FOO`... --> $DIR/recursive-zst-static.rs:10:1 diff --git a/src/test/ui/consts/recursive-zst-static.unleash.stderr b/src/test/ui/consts/recursive-zst-static.unleash.stderr index d424b22f000..9042c6f6be1 100644 --- a/src/test/ui/consts/recursive-zst-static.unleash.stderr +++ b/src/test/ui/consts/recursive-zst-static.unleash.stderr @@ -1,8 +1,8 @@ error[E0391]: cycle detected when const-evaluating `FOO` - --> $DIR/recursive-zst-static.rs:10:18 + --> $DIR/recursive-zst-static.rs:10:1 | LL | static FOO: () = FOO; - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires const-evaluating `FOO`... --> $DIR/recursive-zst-static.rs:10:1 diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.rs b/src/test/ui/consts/uninhabited-const-issue-61744.rs index 15436f9c1b2..55f42d84f9c 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.rs +++ b/src/test/ui/consts/uninhabited-const-issue-61744.rs @@ -1,11 +1,11 @@ // build-fail pub const unsafe fn fake_type() -> T { - hint_unreachable() + hint_unreachable() //~ ERROR evaluation of constant value failed } pub const unsafe fn hint_unreachable() -> ! { - fake_type() //~ ERROR evaluation of constant value failed + fake_type() } trait Const { diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr index ca232380897..fc908b2b222 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr +++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr @@ -1,9 +1,10 @@ error[E0080]: evaluation of constant value failed - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:4:5 | LL | hint_unreachable() - | ------------------ + | ^^^^^^^^^^^^^^^^^^ | | + | reached the configured maximum number of stack frames | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 @@ -71,9 +72,8 @@ LL | hint_unreachable() | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 ... LL | fake_type() - | ^^^^^^^^^^^ + | ----------- | | - | reached the configured maximum number of stack frames | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 diff --git a/src/test/ui/recursion/recursive-static-definition.stderr b/src/test/ui/recursion/recursive-static-definition.stderr index b724c261a7c..093606e100c 100644 --- a/src/test/ui/recursion/recursive-static-definition.stderr +++ b/src/test/ui/recursion/recursive-static-definition.stderr @@ -1,8 +1,8 @@ error[E0391]: cycle detected when const-evaluating `FOO` - --> $DIR/recursive-static-definition.rs:1:23 + --> $DIR/recursive-static-definition.rs:1:1 | LL | pub static FOO: u32 = FOO; - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires const-evaluating `FOO`... --> $DIR/recursive-static-definition.rs:1:1 diff --git a/src/test/ui/write-to-static-mut-in-static.stderr b/src/test/ui/write-to-static-mut-in-static.stderr index 6c2bd13d433..50dfce3448c 100644 --- a/src/test/ui/write-to-static-mut-in-static.stderr +++ b/src/test/ui/write-to-static-mut-in-static.stderr @@ -5,10 +5,10 @@ LL | pub static mut B: () = unsafe { A = 1; }; | ^^^^^ modifying a static's initial value from another static's initializer error[E0391]: cycle detected when const-evaluating `C` - --> $DIR/write-to-static-mut-in-static.rs:5:34 + --> $DIR/write-to-static-mut-in-static.rs:5:1 | LL | pub static mut C: u32 = unsafe { C = 1; 0 }; - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires const-evaluating `C`... --> $DIR/write-to-static-mut-in-static.rs:5:1 From 32b01c78d0502c8a4cc36abbe8dc3c000436df98 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 11 Jun 2020 09:53:38 +0200 Subject: [PATCH 4/7] avoid computing cur_span all the time --- src/librustc_mir/const_eval/eval_queries.rs | 12 +++++++++--- src/librustc_mir/interpret/eval_context.rs | 8 +++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 28e77bb57cd..310b09f7163 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -317,7 +317,10 @@ pub fn const_eval_raw_provider<'tcx>( if is_static { // Ensure that if the above error was either `TooGeneric` or `Reported` // an error must be reported. - let v = err.report_as_error(ecx.tcx_at(), "could not evaluate static initializer"); + let v = err.report_as_error( + ecx.tcx.at(ecx.cur_span()), + "could not evaluate static initializer", + ); // If this is `Reveal:All`, then we need to make sure an error is reported but if // this is `Reveal::UserFacing`, then it's expected that we could get a @@ -373,13 +376,16 @@ pub fn const_eval_raw_provider<'tcx>( // anything else (array lengths, enum initializers, constant patterns) are // reported as hard errors } else { - err.report_as_error(ecx.tcx_at(), "evaluation of constant value failed") + err.report_as_error( + ecx.tcx.at(ecx.cur_span()), + "evaluation of constant value failed", + ) } } } } else { // use of broken constant from other crate - err.report_as_error(ecx.tcx_at(), "could not evaluate constant") + err.report_as_error(ecx.tcx.at(ecx.cur_span()), "could not evaluate constant") } }) } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 47e791854df..866cdce7b77 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -323,7 +323,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub fn tcx_at(&self) -> TyCtxtAt<'tcx> { - self.tcx.at(self.cur_span()) + // Computing the current span has a non-trivial cost, and for cycle errors + // the "root span" is good enough. + self.tcx.at(self.root_span) } #[inline(always)] @@ -406,7 +408,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline] pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - ty.is_freeze(self.tcx, self.param_env, self.cur_span()) + ty.is_freeze(self.tcx, self.param_env, self.root_span) } pub fn load_mir( @@ -889,7 +891,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME: We can hit delay_span_bug if this is an invalid const, interning finds // that problem, but we never run validation to show an error. Can we ensure // this does not happen? - let val = self.tcx_at().const_eval_raw(param_env.and(gid))?; + let val = self.tcx.at(self.cur_span()).const_eval_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) } From 60496504ac635b3f805e8afed5eb6130b620f790 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 13 Jun 2020 13:47:37 +0200 Subject: [PATCH 5/7] avoid computing precise span for const_eval query --- src/librustc_mir/interpret/eval_context.rs | 2 +- src/test/ui/consts/const-size_of-cycle.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 866cdce7b77..4a0981a95a6 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -860,7 +860,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.param_env }; - let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.cur_span()))?; + let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.root_span))?; // Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a // recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr index 5fd7fe4480e..0aa30665f59 100644 --- a/src/test/ui/consts/const-size_of-cycle.stderr +++ b/src/test/ui/consts/const-size_of-cycle.stderr @@ -17,8 +17,8 @@ LL | bytes: [u8; std::mem::size_of::()] note: ...which requires const-evaluating `std::mem::size_of`... --> $SRC_DIR/libcore/mem/mod.rs:LL:COL | -LL | intrinsics::size_of::() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub const fn size_of() -> usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `std::intrinsics::size_of`... --> $SRC_DIR/libcore/intrinsics.rs:LL:COL | From c6512fd4e959d1c19ee7b428a78696a53ab28bc6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 13 Jun 2020 13:55:01 +0200 Subject: [PATCH 6/7] run const_eval_raw with root_span --- src/librustc_mir/interpret/eval_context.rs | 2 +- src/test/ui/infinite/infinite-recursion-const-fn.stderr | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 4a0981a95a6..5d344e9b372 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -891,7 +891,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME: We can hit delay_span_bug if this is an invalid const, interning finds // that problem, but we never run validation to show an error. Can we ensure // this does not happen? - let val = self.tcx.at(self.cur_span()).const_eval_raw(param_env.and(gid))?; + let val = self.tcx_at().const_eval_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) } diff --git a/src/test/ui/infinite/infinite-recursion-const-fn.stderr b/src/test/ui/infinite/infinite-recursion-const-fn.stderr index 6bd5e035f57..de0c579f630 100644 --- a/src/test/ui/infinite/infinite-recursion-const-fn.stderr +++ b/src/test/ui/infinite/infinite-recursion-const-fn.stderr @@ -1,14 +1,14 @@ error[E0391]: cycle detected when const-evaluating `a` - --> $DIR/infinite-recursion-const-fn.rs:3:25 + --> $DIR/infinite-recursion-const-fn.rs:3:1 | LL | const fn a() -> usize { b() } - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires const-evaluating `b`... - --> $DIR/infinite-recursion-const-fn.rs:4:25 + --> $DIR/infinite-recursion-const-fn.rs:4:1 | LL | const fn b() -> usize { a() } - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires const-evaluating `a`, completing the cycle note: cycle used when const-evaluating `ARR::{{constant}}#0` --> $DIR/infinite-recursion-const-fn.rs:5:18 From 2210abea71270867fe2c69782f282c654e106fac Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 14 Jun 2020 15:02:51 +0200 Subject: [PATCH 7/7] keep root_span and tcx together --- src/librustc_mir/const_eval/eval_queries.rs | 4 +- src/librustc_mir/interpret/cast.rs | 8 ++-- src/librustc_mir/interpret/eval_context.rs | 47 +++++++------------ src/librustc_mir/interpret/intern.rs | 19 ++++---- src/librustc_mir/interpret/intrinsics.rs | 4 +- .../interpret/intrinsics/caller_location.rs | 4 +- src/librustc_mir/interpret/operand.rs | 16 +++---- src/librustc_mir/interpret/place.rs | 14 +++--- src/librustc_mir/interpret/terminator.rs | 8 ++-- src/librustc_mir/interpret/traits.rs | 8 ++-- 10 files changed, 60 insertions(+), 72 deletions(-) diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 310b09f7163..d62300b3f55 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -27,7 +27,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( body: &'mir mir::Body<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx>> { debug!("eval_body_using_ecx: {:?}, {:?}", cid, ecx.param_env); - let tcx = ecx.tcx; + let tcx = *ecx.tcx; let layout = ecx.layout_of(body.return_ty().subst(tcx, cid.instance.substs))?; assert!(!layout.is_unsized()); let ret = ecx.allocate(layout, MemoryKind::Stack); @@ -214,7 +214,7 @@ fn validate_and_turn_into_const<'tcx>( val.map_err(|error| { let err = error_to_const_error(&ecx, error, None); - err.struct_error(ecx.tcx_at(), "it is undefined behavior to use this value", |mut diag| { + err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| { diag.note(note_on_undefined_behavior_error()); diag.emit(); }) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 793a67d804c..cfe856abe36 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -56,7 +56,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } let instance = ty::Instance::resolve_for_fn_ptr( - self.tcx, + *self.tcx, self.param_env, def_id, substs, @@ -91,7 +91,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } let instance = ty::Instance::resolve_closure( - self.tcx, + *self.tcx, def_id, substs, ty::ClosureKind::FnOnce, @@ -140,7 +140,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Handle cast from a univariant (ZST) enum. match src.layout.variants { Variants::Single { index } => { - if let Some(discr) = src.layout.ty.discriminant_for_variant(self.tcx, index) { + if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) { assert!(src.layout.is_zst()); let discr_layout = self.layout_of(discr.ty)?; return Ok(self.cast_from_scalar(discr.val, discr_layout, cast_ty).into()); @@ -269,7 +269,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ptr = self.read_immediate(src)?.to_scalar()?; // u64 cast is from usize to u64, which is always good let val = - Immediate::new_slice(ptr, length.eval_usize(self.tcx, self.param_env), self); + Immediate::new_slice(ptr, length.eval_usize(*self.tcx, self.param_env), self); self.write_immediate(val, dest) } (&ty::Dynamic(..), &ty::Dynamic(..)) => { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 5d344e9b372..519dfd5b54e 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -33,11 +33,9 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub machine: M, /// The results of the type checker, from rustc. - pub tcx: TyCtxt<'tcx>, - - /// The span of the "root" of the evaluation, i.e., the const + /// The span in this is the "root" of the evaluation, i.e., the const /// we are evaluating (if this is CTFE). - pub(super) root_span: Span, + pub tcx: TyCtxtAt<'tcx>, /// Bounds in scope for polymorphic evaluations. pub(crate) param_env: ty::ParamEnv<'tcx>, @@ -200,7 +198,7 @@ where { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx + *self.tcx } } @@ -219,7 +217,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, #[inline] fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.tcx_at() + self.tcx .layout_of(self.param_env.and(ty)) .map_err(|layout| err_inval!(Layout(layout)).into()) } @@ -304,8 +302,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> Self { InterpCx { machine, - tcx, - root_span, + tcx: tcx.at(root_span), param_env, memory: Memory::new(tcx, memory_extra), vtables: FxHashMap::default(), @@ -318,14 +315,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .last() .and_then(|f| f.current_source_info()) .map(|si| si.span) - .unwrap_or(self.root_span) - } - - #[inline(always)] - pub fn tcx_at(&self) -> TyCtxtAt<'tcx> { - // Computing the current span has a non-trivial cost, and for cycle errors - // the "root span" is good enough. - self.tcx.at(self.root_span) + .unwrap_or(self.tcx.span) } #[inline(always)] @@ -403,12 +393,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline] pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - ty.is_sized(self.tcx_at(), self.param_env) + ty.is_sized(self.tcx, self.param_env) } #[inline] pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - ty.is_freeze(self.tcx, self.param_env, self.root_span) + ty.is_freeze(*self.tcx, self.param_env, self.tcx.span) } pub fn load_mir( @@ -419,21 +409,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // do not continue if typeck errors occurred (can only occur in local crate) let did = instance.def_id(); if let Some(did) = did.as_local() { - if self.tcx_at().has_typeck_tables(did) { - if let Some(error_reported) = self.tcx_at().typeck_tables_of(did).tainted_by_errors - { + if self.tcx.has_typeck_tables(did) { + if let Some(error_reported) = self.tcx.typeck_tables_of(did).tainted_by_errors { throw_inval!(TypeckError(error_reported)) } } } trace!("load mir(instance={:?}, promoted={:?})", instance, promoted); if let Some(promoted) = promoted { - return Ok(&self.tcx_at().promoted_mir(did)[promoted]); + return Ok(&self.tcx.promoted_mir(did)[promoted]); } match instance { ty::InstanceDef::Item(def_id) => { - if self.tcx_at().is_mir_available(did) { - Ok(self.tcx_at().optimized_mir(did)) + if self.tcx.is_mir_available(did) { + Ok(self.tcx.optimized_mir(did)) } else { throw_unsup!(NoMirFor(def_id)) } @@ -474,7 +463,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("resolve: {:?}, {:#?}", def_id, substs); trace!("param_env: {:#?}", self.param_env); trace!("substs: {:#?}", substs); - match ty::Instance::resolve(self.tcx, self.param_env, def_id, substs) { + match ty::Instance::resolve(*self.tcx, self.param_env, def_id, substs) { Ok(Some(instance)) => Ok(instance), Ok(None) => throw_inval!(TooGeneric), @@ -493,7 +482,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // have to support that case (mostly by skipping all caching). match frame.locals.get(local).and_then(|state| state.layout.get()) { None => { - let layout = from_known_layout(self.tcx_at(), layout, || { + let layout = from_known_layout(self.tcx, layout, || { let local_ty = frame.body.local_decls[local].ty; let local_ty = self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty); @@ -645,7 +634,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let mut locals = IndexVec::from_elem(dummy, &body.local_decls); // Now mark those locals as dead that we do not want to initialize - match self.tcx_at().def_kind(instance.def_id()) { + match self.tcx.def_kind(instance.def_id()) { // statics and constants don't have `Storage*` statements, no need to look for them // // FIXME: The above is likely untrue. See @@ -860,7 +849,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { self.param_env }; - let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.root_span))?; + let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.tcx.span))?; // Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a // recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not @@ -891,7 +880,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME: We can hit delay_span_bug if this is an invalid const, interning finds // that problem, but we never run validation to show an error. Can we ensure // this does not happen? - let val = self.tcx_at().const_eval_raw(param_env.and(gid))?; + let val = self.tcx.const_eval_raw(param_env.and(gid))?; self.raw_const_to_mplace(val) } diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 284a1d5ea61..3c724c79b40 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -93,7 +93,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>( // in the value the dangling reference lies. // The `delay_span_bug` ensures that we don't forget such a check in validation. if tcx.get_global_alloc(alloc_id).is_none() { - tcx.sess.delay_span_bug(ecx.root_span, "tried to intern dangling pointer"); + tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer"); } // treat dangling pointers like other statics // just to stop trying to recurse into them @@ -111,7 +111,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>( if let InternMode::Static(mutability) = mode { // For this, we need to take into account `UnsafeCell`. When `ty` is `None`, we assume // no interior mutability. - let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx, ecx.param_env, ecx.root_span)); + let frozen = ty.map_or(true, |ty| ty.is_freeze(*ecx.tcx, ecx.param_env, ecx.tcx.span)); // For statics, allocation mutability is the combination of the place mutability and // the type mutability. // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere. @@ -174,7 +174,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir // they caused. It also helps us to find cases where const-checking // failed to prevent an `UnsafeCell` (but as `ignore_interior_mut_in_const` // shows that part is not airtight). - mutable_memory_in_const(self.ecx.tcx_at(), "`UnsafeCell`"); + mutable_memory_in_const(self.ecx.tcx, "`UnsafeCell`"); } // We are crossing over an `UnsafeCell`, we can mutate again. This means that // References we encounter inside here are interned as pointing to mutable @@ -192,7 +192,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir fn visit_value(&mut self, mplace: MPlaceTy<'tcx>) -> InterpResult<'tcx> { // Handle Reference types, as these are the only relocations supported by const eval. // Raw pointers (and boxes) are handled by the `leftover_relocations` logic. - let tcx = self.ecx.tcx.at(self.ecx.root_span); + let tcx = self.ecx.tcx; let ty = mplace.layout.ty; if let ty::Ref(_, referenced_ty, ref_mutability) = ty.kind { let value = self.ecx.read_immediate(mplace.into())?; @@ -253,8 +253,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir // caused (by somehow getting a mutable reference in a `const`). if ref_mutability == Mutability::Mut { match referenced_ty.kind { - ty::Array(_, n) - if n.eval_usize(self.ecx.tcx, self.ecx.param_env) == 0 => {} + ty::Array(_, n) if n.eval_usize(*tcx, self.ecx.param_env) == 0 => {} ty::Slice(_) if mplace.meta.unwrap_meta().to_machine_usize(self.ecx)? == 0 => {} @@ -358,7 +357,7 @@ pub fn intern_const_alloc_recursive>( Ok(()) => {} Err(error) => { ecx.tcx.sess.delay_span_bug( - ecx.root_span, + ecx.tcx.span, "error during interning should later cause validation failure", ); // Some errors shouldn't come up because creating them causes @@ -407,7 +406,7 @@ pub fn intern_const_alloc_recursive>( // such as `const CONST_RAW: *const Vec = &Vec::new() as *const _;`. ecx.tcx .sess - .span_err(ecx.root_span, "untyped pointers are not allowed in constant"); + .span_err(ecx.tcx.span, "untyped pointers are not allowed in constant"); // For better errors later, mark the allocation as immutable. alloc.mutability = Mutability::Not; } @@ -422,11 +421,11 @@ pub fn intern_const_alloc_recursive>( } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) { // Codegen does not like dangling pointers, and generally `tcx` assumes that // all allocations referenced anywhere actually exist. So, make sure we error here. - ecx.tcx.sess.span_err(ecx.root_span, "encountered dangling pointer in final constant"); + ecx.tcx.sess.span_err(ecx.tcx.span, "encountered dangling pointer in final constant"); } else if ecx.tcx.get_global_alloc(alloc_id).is_none() { // We have hit an `AllocId` that is neither in local or global memory and isn't // marked as dangling by local memory. That should be impossible. - span_bug!(ecx.root_span, "encountered unknown alloc id {:?}", alloc_id); + span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); } } } diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index c62fd316dc5..47e5b8b4fce 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -347,7 +347,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let index = u64::from(self.read_scalar(args[1])?.to_u32()?); let elem = args[2]; let input = args[0]; - let (len, e_ty) = input.layout.ty.simd_size_and_type(self.tcx); + let (len, e_ty) = input.layout.ty.simd_size_and_type(*self.tcx); assert!( index < len, "Index `{}` must be in bounds of vector type `{}`: `[0, {})`", @@ -374,7 +374,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } sym::simd_extract => { let index = u64::from(self.read_scalar(args[1])?.to_u32()?); - let (len, e_ty) = args[0].layout.ty.simd_size_and_type(self.tcx); + let (len, e_ty) = args[0].layout.ty.simd_size_and_type(*self.tcx); assert!( index < len, "index `{}` is out-of-bounds of vector type `{}` with length `{}`", diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/src/librustc_mir/interpret/intrinsics/caller_location.rs index 193d38dc552..ddeed92f851 100644 --- a/src/librustc_mir/interpret/intrinsics/caller_location.rs +++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs @@ -25,7 +25,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { "find_closest_untracked_caller_location: checking frame {:?}", frame.instance ); - !frame.instance.def.requires_caller_location(self.tcx) + !frame.instance.def.requires_caller_location(*self.tcx) }) // Assert that there is always such a frame. .unwrap(); @@ -58,7 +58,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let loc_ty = self .tcx .type_of(self.tcx.require_lang_item(PanicLocationLangItem, None)) - .subst(self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); + .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); let loc_layout = self.layout_of(loc_ty).unwrap(); let location = self.allocate(loc_layout, MemoryKind::CallerLocation); diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index c9250098fed..38f5988d0eb 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -471,9 +471,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("eval_place_to_op: got {:?}", *op); // Sanity-check the type we ended up with. debug_assert!(mir_assign_valid_types( - self.tcx, + *self.tcx, self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions( - place.ty(&self.frame().body.local_decls, self.tcx).ty + place.ty(&self.frame().body.local_decls, *self.tcx).ty ))?, op.layout, )); @@ -554,7 +554,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // documentation). let val_val = M::adjust_global_const(self, val_val)?; // Other cases need layout. - let layout = from_known_layout(self.tcx_at(), layout, || self.layout_of(val.ty))?; + let layout = from_known_layout(self.tcx, layout, || self.layout_of(val.ty))?; let op = match val_val { ConstValue::ByRef { alloc, offset } => { let id = self.tcx.create_memory_alloc(alloc); @@ -589,7 +589,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("read_discriminant_value {:#?}", op.layout); // Get type and layout of the discriminant. - let discr_layout = self.layout_of(op.layout.ty.discriminant_ty(self.tcx))?; + let discr_layout = self.layout_of(op.layout.ty.discriminant_ty(*self.tcx))?; trace!("discriminant type: {:?}", discr_layout.ty); // We use "discriminant" to refer to the value associated with a particular enum variant. @@ -601,7 +601,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // rather confusing. let (tag_scalar_layout, tag_kind, tag_index) = match op.layout.variants { Variants::Single { index } => { - let discr = match op.layout.ty.discriminant_for_variant(self.tcx, index) { + let discr = match op.layout.ty.discriminant_for_variant(*self.tcx, index) { Some(discr) => { // This type actually has discriminants. assert_eq!(discr.ty, discr_layout.ty); @@ -630,7 +630,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // may be a pointer. This is `tag_val.layout`; we just use it for sanity checks. // Get layout for tag. - let tag_layout = self.layout_of(tag_scalar_layout.value.to_int_ty(self.tcx))?; + let tag_layout = self.layout_of(tag_scalar_layout.value.to_int_ty(*self.tcx))?; // Read tag and sanity-check `tag_layout`. let tag_val = self.read_immediate(self.operand_field(op, tag_index)?)?; @@ -651,12 +651,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Convert discriminant to variant index, and catch invalid discriminants. let index = match op.layout.ty.kind { ty::Adt(adt, _) => { - adt.discriminants(self.tcx).find(|(_, var)| var.val == discr_bits) + adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits) } ty::Generator(def_id, substs, _) => { let substs = substs.as_generator(); substs - .discriminants(def_id, self.tcx) + .discriminants(def_id, *self.tcx) .find(|(_, var)| var.val == discr_bits) } _ => bug!("tagged layout for non-adt non-generator"), diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 2477100eb8a..24b191e9b53 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -651,9 +651,9 @@ where self.dump_place(place_ty.place); // Sanity-check the type we ended up with. debug_assert!(mir_assign_valid_types( - self.tcx, + *self.tcx, self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions( - place.ty(&self.frame().body.local_decls, self.tcx).ty + place.ty(&self.frame().body.local_decls, *self.tcx).ty ))?, place_ty.layout, )); @@ -779,7 +779,7 @@ where None => return Ok(()), // zero-sized access }; - let tcx = self.tcx; + let tcx = *self.tcx; // FIXME: We should check that there are dest.layout.size many bytes available in // memory. The code below is not sufficient, with enough padding it might not // cover all the bytes! @@ -855,7 +855,7 @@ where ) -> InterpResult<'tcx> { // We do NOT compare the types for equality, because well-typed code can // actually "transmute" `&mut T` to `&T` in an assignment without a cast. - if !mir_assign_valid_types(self.tcx, src.layout, dest.layout) { + if !mir_assign_valid_types(*self.tcx, src.layout, dest.layout) { span_bug!( self.cur_span(), "type mismatch when copying!\nsrc: {:?},\ndest: {:?}", @@ -912,7 +912,7 @@ where src: OpTy<'tcx, M::PointerTag>, dest: PlaceTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx> { - if mir_assign_valid_types(self.tcx, src.layout, dest.layout) { + if mir_assign_valid_types(*self.tcx, src.layout, dest.layout) { // Fast path: Just use normal `copy_op` return self.copy_op(src, dest); } @@ -1070,7 +1070,7 @@ where // `TyAndLayout::for_variant()` call earlier already checks the variant is valid. let discr_val = - dest.layout.ty.discriminant_for_variant(self.tcx, variant_index).unwrap().val; + dest.layout.ty.discriminant_for_variant(*self.tcx, variant_index).unwrap().val; // raw discriminants for enums are isize or bigger during // their computation, but the in-memory tag is the smallest possible @@ -1099,7 +1099,7 @@ where .expect("overflow computing relative variant idx"); // We need to use machine arithmetic when taking into account `niche_start`: // discr_val = variant_index_relative + niche_start_val - let discr_layout = self.layout_of(discr_layout.value.to_int_ty(self.tcx))?; + let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?; let niche_start_val = ImmTy::from_uint(niche_start, discr_layout); let variant_index_relative_val = ImmTy::from_uint(variant_index_relative, discr_layout); diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 9a4dd0a5204..cd7621ea975 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -69,7 +69,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (fn_val, caller_abi) } ty::FnDef(def_id, substs) => { - let sig = func.layout.ty.fn_sig(self.tcx); + let sig = func.layout.ty.fn_sig(*self.tcx); (FnVal::Instance(self.resolve(def_id, substs)?), sig.abi()) } _ => span_bug!( @@ -96,7 +96,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ty = place.layout.ty; trace!("TerminatorKind::drop: {:?}, type {}", location, ty); - let instance = Instance::resolve_drop_in_place(self.tcx, ty); + let instance = Instance::resolve_drop_in_place(*self.tcx, ty); self.drop_in_place(place, instance, target, unwind)?; } @@ -227,9 +227,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // ABI check { let callee_abi = { - let instance_ty = instance.ty_env(self.tcx, self.param_env); + let instance_ty = instance.ty_env(*self.tcx, self.param_env); match instance_ty.kind { - ty::FnDef(..) => instance_ty.fn_sig(self.tcx).abi(), + ty::FnDef(..) => instance_ty.fn_sig(*self.tcx).abi(), ty::Closure(..) => Abi::RustCall, ty::Generator(..) => Abi::Rust, _ => bug!("unexpected callee ty: {:?}", instance_ty), diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 87493a8d383..a1d124bb760 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -36,10 +36,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } let methods = if let Some(poly_trait_ref) = poly_trait_ref { - let trait_ref = poly_trait_ref.with_self_ty(self.tcx, ty); + let trait_ref = poly_trait_ref.with_self_ty(*self.tcx, ty); let trait_ref = self.tcx.erase_regions(&trait_ref); - self.tcx_at().vtable_methods(trait_ref) + self.tcx.vtable_methods(trait_ref) } else { &[] }; @@ -49,7 +49,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let size = layout.size.bytes(); let align = layout.align.abi.bytes(); - let tcx = self.tcx; + let tcx = *self.tcx; let ptr_size = self.pointer_size(); let ptr_align = tcx.data_layout.pointer_align.abi; // ///////////////////////////////////////////////////////////////////////////////////////// @@ -142,7 +142,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // to determine the type. let drop_instance = self.memory.get_fn(drop_fn)?.as_instance()?; trace!("Found drop fn: {:?}", drop_instance); - let fn_sig = drop_instance.ty_env(self.tcx, self.param_env).fn_sig(self.tcx); + let fn_sig = drop_instance.ty_env(*self.tcx, self.param_env).fn_sig(*self.tcx); let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, &fn_sig); // The drop function takes `*mut T` where `T` is the type being dropped, so get that. let args = fn_sig.inputs();