about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2018-02-06 18:33:59 +0100
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2018-03-08 08:34:17 +0100
commit2f0e07730088b7656c244030f360406758f788ea (patch)
tree89709339baf13a5e24e1e08b478f24f324ccb239 /src
parent1e653aa96b392a04ed489eadc4cd040bc2859b4b (diff)
Report tcx errors with the span of the currently evaluating statement
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/interpret/const_eval.rs9
-rw-r--r--src/librustc_mir/interpret/eval_context.rs62
-rw-r--r--src/librustc_mir/interpret/memory.rs7
-rw-r--r--src/librustc_mir/interpret/place.rs4
-rw-r--r--src/librustc_mir/interpret/step.rs4
-rw-r--r--src/librustc_mir/interpret/terminator/mod.rs11
-rw-r--r--src/librustc_mir/interpret/traits.rs5
-rw-r--r--src/test/ui/infinite-recursion-const-fn.rs4
8 files changed, 41 insertions, 65 deletions
diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs
index b44e91d7b74..ee5874be9d7 100644
--- a/src/librustc_mir/interpret/const_eval.rs
+++ b/src/librustc_mir/interpret/const_eval.rs
@@ -24,7 +24,7 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
 ) -> EvalResult<'tcx, EvalContext<'a, 'mir, 'tcx, CompileTimeEvaluator>> {
     debug!("mk_borrowck_eval_cx: {:?}", instance);
     let param_env = tcx.param_env(instance.def_id());
-    let mut ecx = EvalContext::new(tcx, param_env, CompileTimeEvaluator, (), span);
+    let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeEvaluator, ());
     // insert a stack frame so any queries have the correct substs
     ecx.push_stack_frame(
         instance,
@@ -43,7 +43,7 @@ pub fn mk_eval_cx<'a, 'tcx>(
 ) -> EvalResult<'tcx, EvalContext<'a, 'tcx, 'tcx, CompileTimeEvaluator>> {
     debug!("mk_eval_cx: {:?}, {:?}", instance, param_env);
     let span = tcx.def_span(instance.def_id());
-    let mut ecx = EvalContext::new(tcx, param_env, CompileTimeEvaluator, (), span);
+    let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeEvaluator, ());
     let mir = ecx.load_mir(instance.def)?;
     // insert a stack frame so any queries have the correct substs
     ecx.push_stack_frame(
@@ -96,8 +96,9 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
     debug!("eval_body: {:?}, {:?}", cid, param_env);
     // we start out with the best span we have
     // and try improving it down the road when more information is available
-    let mut span = tcx.def_span(cid.instance.def_id());
-    let mut ecx = EvalContext::new(tcx, param_env, CompileTimeEvaluator, (), mir.map(|mir| mir.span).unwrap_or(span));
+    let span = tcx.def_span(cid.instance.def_id());
+    let mut span = mir.map(|mir| mir.span).unwrap_or(span);
+    let mut ecx = EvalContext::new(tcx.at(span), param_env, CompileTimeEvaluator, ());
     let res = (|| {
         let mut mir = match mir {
             Some(mir) => mir,
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 23ab6be1b46..f46d5631060 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -5,13 +5,13 @@ use rustc::hir::def_id::DefId;
 use rustc::hir::map::definitions::DefPathData;
 use rustc::middle::const_val::{ConstVal, ErrKind};
 use rustc::mir;
-use rustc::traits::Reveal;
 use rustc::ty::layout::{self, Size, Align, HasDataLayout, LayoutOf, TyLayout};
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::maps::TyCtxtAt;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc::middle::const_val::FrameInfo;
-use syntax::codemap::{self, DUMMY_SP, Span};
+use syntax::codemap::{self, Span};
 use syntax::ast::Mutability;
 use rustc::mir::interpret::{
     GlobalId, Value, Pointer, PrimVal, PrimValKind,
@@ -27,7 +27,7 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     pub machine: M,
 
     /// The results of the type checker, from rustc.
-    pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    pub tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
 
     /// Bounds in scope for polymorphic evaluations.
     pub param_env: ty::ParamEnv<'tcx>,
@@ -45,11 +45,6 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     /// This prevents infinite loops and huge computations from freezing up const eval.
     /// Remove once halting problem is solved.
     pub(crate) steps_remaining: usize,
-
-    /// The span that is used if no more stack frames are available
-    ///
-    /// This happens after successful evaluation when the result is inspected
-    root_span: codemap::Span,
 }
 
 /// A stack frame.
@@ -154,7 +149,7 @@ impl<'c, 'b, 'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> layout::HasTyCtxt<'tcx> for &'a EvalContext<'a, 'mir, 'tcx, M> {
     #[inline]
     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
-        self.tcx
+        *self.tcx
     }
 }
 
@@ -162,7 +157,7 @@ impl<'c, 'b, 'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> layout::HasTyCtxt<'tcx>
     for &'c &'b mut EvalContext<'a, 'mir, 'tcx, M> {
     #[inline]
     fn tcx<'d>(&'d self) -> TyCtxt<'d, 'tcx, 'tcx> {
-        self.tcx
+        *self.tcx
     }
 }
 
@@ -187,11 +182,10 @@ impl<'c, 'b, 'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf<Ty<'tcx>>
 
 impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
     pub fn new(
-        tcx: TyCtxt<'a, 'tcx, 'tcx>,
+        tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         machine: M,
         memory_data: M::MemoryData,
-        root_span: codemap::Span,
     ) -> Self {
         EvalContext {
             machine,
@@ -201,7 +195,6 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
             stack: Vec::new(),
             stack_limit: tcx.sess.const_eval_stack_frame_limit.get(),
             steps_remaining: tcx.sess.const_eval_step_limit.get(),
-            root_span,
         }
     }
 
@@ -255,7 +248,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
     pub(super) fn resolve(&self, def_id: DefId, substs: &'tcx Substs<'tcx>) -> EvalResult<'tcx, ty::Instance<'tcx>> {
         let substs = self.tcx.trans_apply_param_substs(self.substs(), &substs);
         ty::Instance::resolve(
-            self.tcx,
+            *self.tcx,
             self.param_env,
             def_id,
             substs,
@@ -263,7 +256,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
     }
 
     pub(super) fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env)
+        ty.is_sized(self.tcx, self.param_env)
     }
 
     pub fn load_mir(
@@ -290,7 +283,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
         // miri doesn't care about lifetimes, and will choke on some crazy ones
         // let's simply get rid of them
         let without_lifetimes = self.tcx.erase_regions(&ty);
-        let substituted = without_lifetimes.subst(self.tcx, substs);
+        let substituted = without_lifetimes.subst(*self.tcx, substs);
         let substituted = self.tcx.fully_normalize_monormophic_ty(&substituted);
         substituted
     }
@@ -725,7 +718,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
                             ty::TyClosure(def_id, substs) => {
                                 let substs = self.tcx.trans_apply_param_substs(self.substs(), &substs);
                                 let instance = ty::Instance::resolve_closure(
-                                    self.tcx,
+                                    *self.tcx,
                                     def_id,
                                     substs,
                                     ty::ClosureKind::FnOnce,
@@ -748,8 +741,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
                 let place = self.eval_place(place)?;
                 let discr_val = self.read_discriminant_value(place, ty)?;
                 if let ty::TyAdt(adt_def, _) = ty.sty {
-                    trace!("Read discriminant {}, valid discriminants {:?}", discr_val, adt_def.discriminants(self.tcx).collect::<Vec<_>>());
-                    if adt_def.discriminants(self.tcx).all(|v| {
+                    trace!("Read discriminant {}, valid discriminants {:?}", discr_val, adt_def.discriminants(*self.tcx).collect::<Vec<_>>());
+                    if adt_def.discriminants(*self.tcx).all(|v| {
                         discr_val != v.val
                     })
                     {
@@ -797,7 +790,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
 
     pub fn eval_operand(&mut self, op: &mir::Operand<'tcx>) -> EvalResult<'tcx, ValTy<'tcx>> {
         use rustc::mir::Operand::*;
-        let ty = self.monomorphize(op.ty(self.mir(), self.tcx), self.substs());
+        let ty = self.monomorphize(op.ty(self.mir(), *self.tcx), self.substs());
         match *op {
             // FIXME: do some more logic on `move` to invalidate the old location
             Copy(ref place) |
@@ -905,7 +898,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
             }
             layout::Variants::Tagged { .. } => {
                 let discr_val = dest_ty.ty_adt_def().unwrap()
-                    .discriminant_for_variant(self.tcx, variant_index)
+                    .discriminant_for_variant(*self.tcx, variant_index)
                     .val;
 
                 let (discr_dest, discr) = self.place_field(dest, mir::Field::new(0), layout)?;
@@ -1412,7 +1405,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
             }
             (_, &ty::TyDynamic(ref data, _)) => {
                 let trait_ref = data.principal().unwrap().with_self_ty(
-                    self.tcx,
+                    *self.tcx,
                     src_pointee_ty,
                 );
                 let trait_ref = self.tcx.erase_regions(&trait_ref);
@@ -1601,18 +1594,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
             };
             frames.push(FrameInfo { span, location });
         }
-        let span = if let Some(frame) = self.stack().last() {
-            let bb = &frame.mir.basic_blocks()[frame.block];
-            if let Some(stmt) = bb.statements.get(frame.stmt) {
-                stmt.source_info.span
-            } else {
-                bb.terminator().source_info.span
-            }
-        } else {
-            self.root_span
-        };
         trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
-        (frames, span)
+        (frames, self.tcx.span)
     }
 
     pub fn report(&self, e: &mut EvalError, as_err: bool, explicit_span: Option<Span>) {
@@ -1660,7 +1643,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
             });
             trace!("reporting const eval failure at {:?}", span);
             let mut err = if as_err {
-                ::rustc::middle::const_val::struct_error(self.tcx, span, "constant evaluation error")
+                ::rustc::middle::const_val::struct_error(*self.tcx, span, "constant evaluation error")
             } else {
                 let node_id = self
                     .stack()
@@ -1722,14 +1705,3 @@ impl<'mir, 'tcx> Frame<'mir, 'tcx> {
         return Ok(old);
     }
 }
-
-// TODO(solson): Upstream these methods into rustc::ty::layout.
-
-pub fn resolve_drop_in_place<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    ty: Ty<'tcx>,
-) -> ty::Instance<'tcx> {
-    let def_id = tcx.require_lang_item(::rustc::middle::lang_items::DropInPlaceFnLangItem);
-    let substs = tcx.intern_substs(&[ty.into()]);
-    ty::Instance::resolve(tcx, ty::ParamEnv::empty(Reveal::All), def_id, substs).unwrap()
-}
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index da8ff11e3d0..7dceacabb29 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -2,7 +2,8 @@ use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian, BigEndian};
 use std::collections::{btree_map, BTreeMap, HashMap, HashSet, VecDeque};
 use std::{ptr, io};
 
-use rustc::ty::{Instance, TyCtxt};
+use rustc::ty::Instance;
+use rustc::ty::maps::TyCtxtAt;
 use rustc::ty::layout::{self, Align, TargetDataLayout};
 use syntax::ast::Mutability;
 
@@ -51,11 +52,11 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
     /// The current stack frame.  Used to check accesses against locks.
     pub cur_frame: usize,
 
-    pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    pub tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
 }
 
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
-    pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, data: M::MemoryData) -> Self {
+    pub fn new(tcx: TyCtxtAt<'a, 'tcx, 'tcx>, data: M::MemoryData) -> Self {
         Memory {
             data,
             alloc_kind: HashMap::new(),
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 4ca68068728..d27de3ef6bf 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -209,7 +209,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                         extra: PlaceExtra::None,
                     }
                 } else {
-                    let instance = ty::Instance::mono(self.tcx, static_.def_id);
+                    let instance = ty::Instance::mono(*self.tcx, static_.def_id);
                     let cid = GlobalId {
                         instance,
                         promoted: None
@@ -445,7 +445,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
 
     pub fn place_ty(&self, place: &mir::Place<'tcx>) -> Ty<'tcx> {
         self.monomorphize(
-            place.ty(self.mir(), self.tcx).to_ty(self.tcx),
+            place.ty(self.mir(), *self.tcx).to_ty(*self.tcx),
             self.substs(),
         )
     }
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 94fe3d1c67b..54fd364d3f8 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -51,6 +51,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
         // Some statements (e.g. box) push new stack frames.  We have to record the stack frame number
         // *before* executing the statement.
         let frame_idx = self.cur_frame();
+        self.tcx.span = stmt.source_info.span;
+        self.memory.tcx.span = stmt.source_info.span;
 
         match stmt.kind {
             Assign(ref place, ref rvalue) => self.eval_rvalue_into_place(rvalue, place)?,
@@ -99,6 +101,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
 
     fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> EvalResult<'tcx> {
         trace!("{:?}", terminator.kind);
+        self.tcx.span = terminator.source_info.span;
+        self.memory.tcx.span = terminator.source_info.span;
         self.eval_terminator(terminator)?;
         if !self.stack.is_empty() {
             trace!("// {:?}", self.frame().block);
diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs
index b1b5f77a2e6..51dee0aaff4 100644
--- a/src/librustc_mir/interpret/terminator/mod.rs
+++ b/src/librustc_mir/interpret/terminator/mod.rs
@@ -5,8 +5,7 @@ use syntax::codemap::Span;
 use syntax::abi::Abi;
 
 use rustc::mir::interpret::{EvalResult, PrimVal, Value};
-use super::{EvalContext, eval_context,
-            Place, Machine, ValTy};
+use super::{EvalContext, Place, Machine, ValTy};
 
 use rustc_data_structures::indexed_vec::Idx;
 use interpret::memory::HasMemory;
@@ -72,10 +71,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                     ty::TyFnPtr(sig) => {
                         let fn_ptr = self.value_to_primval(func)?.to_ptr()?;
                         let instance = self.memory.get_fn(fn_ptr)?;
-                        let instance_ty = instance.ty(self.tcx);
+                        let instance_ty = instance.ty(*self.tcx);
                         match instance_ty.sty {
                             ty::TyFnDef(..) => {
-                                let real_sig = instance_ty.fn_sig(self.tcx);
+                                let real_sig = instance_ty.fn_sig(*self.tcx);
                                 let sig = self.tcx.erase_late_bound_regions_and_normalize(&sig);
                                 let real_sig = self.tcx.erase_late_bound_regions_and_normalize(&real_sig);
                                 if !self.check_sig_compat(sig, real_sig)? {
@@ -88,7 +87,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                     }
                     ty::TyFnDef(def_id, substs) => (
                         self.resolve(def_id, substs)?,
-                        func.ty.fn_sig(self.tcx),
+                        func.ty.fn_sig(*self.tcx),
                     ),
                     _ => {
                         let msg = format!("can't handle callee of type {:?}", func.ty);
@@ -117,7 +116,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                 let ty = self.tcx.trans_apply_param_substs(self.substs(), &ty);
                 trace!("TerminatorKind::drop: {:?}, type {}", location, ty);
 
-                let instance = eval_context::resolve_drop_in_place(self.tcx, ty);
+                let instance = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
                 self.drop_place(
                     place,
                     instance,
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index 03b215fa0b8..c67cf1c84bf 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/src/librustc_mir/interpret/traits.rs
@@ -3,8 +3,7 @@ use rustc::ty::layout::{Size, Align, LayoutOf};
 use syntax::ast::Mutability;
 
 use rustc::mir::interpret::{PrimVal, Value, MemoryPointer, EvalResult};
-use super::{EvalContext, eval_context,
-            Machine};
+use super::{EvalContext, Machine};
 
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
     /// Creates a dynamic vtable for the given type and vtable origin. This is used only for
@@ -34,7 +33,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
             None,
         )?;
 
-        let drop = eval_context::resolve_drop_in_place(self.tcx, ty);
+        let drop = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
         let drop = self.memory.create_fn_alloc(drop);
         self.memory.write_ptr_sized_unsigned(vtable, ptr_align, PrimVal::Ptr(drop))?;
 
diff --git a/src/test/ui/infinite-recursion-const-fn.rs b/src/test/ui/infinite-recursion-const-fn.rs
index 51de304405a..f98074bc554 100644
--- a/src/test/ui/infinite-recursion-const-fn.rs
+++ b/src/test/ui/infinite-recursion-const-fn.rs
@@ -11,8 +11,8 @@
 //https://github.com/rust-lang/rust/issues/31364
 
 #![feature(const_fn)]
-const fn a() -> usize { b() }
-const fn b() -> usize { a() } //~ ERROR constant evaluation error
+const fn a() -> usize { b() } //~ ERROR constant evaluation error
+const fn b() -> usize { a() }
 const ARR: [i32; a()] = [5; 6];
 
 fn main(){}