about summary refs log tree commit diff
path: root/src/librustc_mir/interpret
diff options
context:
space:
mode:
authorOliver Schneider <github35764891676564198441@oli-obk.de>2018-06-02 23:38:57 +0200
committerOliver Schneider <github35764891676564198441@oli-obk.de>2018-06-05 20:49:46 +0200
commit5c0d1355f261efd624e0f7755a87e46d954771d3 (patch)
treeb933114434c3ff23dc0e30d29ef10e5badb21028 /src/librustc_mir/interpret
parent4a9c58c6bd0e609538053a35685e206f66019820 (diff)
downloadrust-5c0d1355f261efd624e0f7755a87e46d954771d3.tar.gz
rust-5c0d1355f261efd624e0f7755a87e46d954771d3.zip
Refactor the const eval diagnostic API
Diffstat (limited to 'src/librustc_mir/interpret')
-rw-r--r--src/librustc_mir/interpret/const_eval.rs50
-rw-r--r--src/librustc_mir/interpret/eval_context.rs88
-rw-r--r--src/librustc_mir/interpret/mod.rs1
3 files changed, 32 insertions, 107 deletions
diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs
index 44832df8240..17df184920c 100644
--- a/src/librustc_mir/interpret/const_eval.rs
+++ b/src/librustc_mir/interpret/const_eval.rs
@@ -65,34 +65,12 @@ pub fn eval_promoted<'a, 'mir, 'tcx>(
     cid: GlobalId<'tcx>,
     mir: &'mir mir::Mir<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-) -> Option<(Value, Scalar, Ty<'tcx>)> {
+) -> EvalResult<'tcx, (Value, Scalar, Ty<'tcx>)> {
     ecx.with_fresh_body(|ecx| {
-        let res = eval_body_using_ecx(ecx, cid, Some(mir), param_env);
-        match res {
-            Ok(val) => Some(val),
-            Err(mut err) => {
-                ecx.report(&mut err, false, None);
-                None
-            }
-        }
+        eval_body_using_ecx(ecx, cid, Some(mir), param_env)
     })
 }
 
-pub fn eval_body<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    cid: GlobalId<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-) -> Option<(Value, Scalar, Ty<'tcx>)> {
-    let (res, ecx) = eval_body_and_ecx(tcx, cid, None, param_env);
-    match res {
-        Ok(val) => Some(val),
-        Err(mut err) => {
-            ecx.report(&mut err, true, None);
-            None
-        }
-    }
-}
-
 pub fn value_to_const_value<'tcx>(
     ecx: &EvalContext<'_, '_, 'tcx, CompileTimeEvaluator>,
     val: Value,
@@ -124,9 +102,17 @@ pub fn value_to_const_value<'tcx>(
     })();
     match val {
         Ok(val) => ty::Const::from_const_value(ecx.tcx.tcx, val, ty),
-        Err(mut err) => {
-            ecx.report(&mut err, true, None);
-            bug!("miri error occured when converting Value to ConstValue")
+        Err(err) => {
+            let (frames, span) = ecx.generate_stacktrace(None);
+            let err = ConstEvalErr {
+                span,
+                kind: ErrKind::Miri(err, frames).into(),
+            };
+            err.report_as_error(
+                ecx.tcx,
+                "failed to convert Value to ConstValue, this is a bug",
+            );
+            span_bug!(span, "miri error occured when converting Value to ConstValue")
         }
     }
 }
@@ -579,15 +565,17 @@ pub fn const_eval_provider<'a, 'tcx>(
         }
         Ok(value_to_const_value(&ecx, val, miri_ty))
     }).map_err(|mut err| {
-        if tcx.is_static(def_id).is_some() {
-            ecx.report(&mut err, true, None);
-        }
+        err.print_backtrace();
         let (trace, span) = ecx.generate_stacktrace(None);
         let err = ErrKind::Miri(err, trace);
-        ConstEvalErr {
+        let err = ConstEvalErr {
             kind: err.into(),
             span,
+        };
+        if tcx.is_static(def_id).is_some() {
+            err.report_as_error(ecx.tcx, "could not evaluate static initializer");
         }
+        err
     })
 }
 
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 632f7abfdb4..4c03046f7b1 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -15,7 +15,7 @@ use syntax::codemap::{self, Span};
 use syntax::ast::Mutability;
 use rustc::mir::interpret::{
     GlobalId, Value, Scalar,
-    EvalError, EvalResult, EvalErrorKind, Pointer, ConstValue,
+    EvalResult, EvalErrorKind, Pointer, ConstValue,
 };
 use std::mem;
 
@@ -1626,7 +1626,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
         let mut last_span = None;
         let mut frames = Vec::new();
         // skip 1 because the last frame is just the environment of the constant
-        for &Frame { instance, span, .. } in self.stack().iter().skip(1).rev() {
+        for &Frame { instance, span, mir, block, stmt, .. } in self.stack().iter().skip(1).rev() {
             // make sure we don't emit frames that are duplicates of the previous
             if explicit_span == Some(span) {
                 last_span = Some(span);
@@ -1644,82 +1644,20 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
             } else {
                 instance.to_string()
             };
-            frames.push(FrameInfo { span, location });
-        }
-        trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
-        (frames, self.tcx.span)
-    }
-
-    pub fn report(&self, e: &mut EvalError, as_err: bool, explicit_span: Option<Span>) {
-        match e.kind {
-            EvalErrorKind::Layout(_) |
-            EvalErrorKind::TypeckError => return,
-            _ => {},
-        }
-        if let Some(ref mut backtrace) = e.backtrace {
-            let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
-            backtrace.resolve();
-            write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
-            'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
-                if frame.symbols().is_empty() {
-                    write!(trace_text, "{}: no symbols\n", i).unwrap();
-                }
-                for symbol in frame.symbols() {
-                    write!(trace_text, "{}: ", i).unwrap();
-                    if let Some(name) = symbol.name() {
-                        write!(trace_text, "{}\n", name).unwrap();
-                    } else {
-                        write!(trace_text, "<unknown>\n").unwrap();
-                    }
-                    write!(trace_text, "\tat ").unwrap();
-                    if let Some(file_path) = symbol.filename() {
-                        write!(trace_text, "{}", file_path.display()).unwrap();
-                    } else {
-                        write!(trace_text, "<unknown_file>").unwrap();
-                    }
-                    if let Some(line) = symbol.lineno() {
-                        write!(trace_text, ":{}\n", line).unwrap();
-                    } else {
-                        write!(trace_text, "\n").unwrap();
-                    }
-                }
-            }
-            error!("{}", trace_text);
-        }
-        if let Some(frame) = self.stack().last() {
-            let block = &frame.mir.basic_blocks()[frame.block];
-            let span = explicit_span.unwrap_or_else(|| if frame.stmt < block.statements.len() {
-                block.statements[frame.stmt].source_info.span
-            } else {
-                block.terminator().source_info.span
-            });
-            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")
+            let block = &mir.basic_blocks()[block];
+            let source_info = if stmt < block.statements.len() {
+                block.statements[stmt].source_info
             } else {
-                let node_id = self
-                    .stack()
-                    .iter()
-                    .rev()
-                    .filter_map(|frame| self.tcx.hir.as_local_node_id(frame.instance.def_id()))
-                    .next()
-                    .expect("some part of a failing const eval must be local");
-                self.tcx.struct_span_lint_node(
-                    ::rustc::lint::builtin::CONST_ERR,
-                    node_id,
-                    span,
-                    "constant evaluation error",
-                )
+                block.terminator().source_info
             };
-            let (frames, span) = self.generate_stacktrace(explicit_span);
-            err.span_label(span, e.to_string());
-            for FrameInfo { span, location } in frames {
-                err.span_note(span, &format!("inside call to `{}`", location));
-            }
-            err.emit();
-        } else {
-            self.tcx.sess.err(&e.to_string());
+            let lint_root = match mir.source_scope_local_data {
+                mir::ClearCrossCrate::Set(ref ivs) => Some(ivs[source_info.scope].lint_root),
+                mir::ClearCrossCrate::Clear => None,
+            };
+            frames.push(FrameInfo { span, location, lint_root });
         }
+        trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
+        (frames, self.tcx.span)
     }
 
     pub fn sign_extend(&self, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs
index b5b4ac6df6b..3afcd6f2d9b 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -21,7 +21,6 @@ pub use self::memory::{Memory, MemoryKind, HasMemory};
 pub use self::const_eval::{
     eval_promoted,
     mk_borrowck_eval_cx,
-    eval_body,
     CompileTimeEvaluator,
     const_value_to_allocation_provider,
     const_eval_provider,