diff options
| author | Oliver Schneider <github35764891676564198441@oli-obk.de> | 2018-06-02 23:38:57 +0200 |
|---|---|---|
| committer | Oliver Schneider <github35764891676564198441@oli-obk.de> | 2018-06-05 20:49:46 +0200 |
| commit | 5c0d1355f261efd624e0f7755a87e46d954771d3 (patch) | |
| tree | b933114434c3ff23dc0e30d29ef10e5badb21028 /src/librustc_mir/interpret | |
| parent | 4a9c58c6bd0e609538053a35685e206f66019820 (diff) | |
| download | rust-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.rs | 50 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/eval_context.rs | 88 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/mod.rs | 1 |
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, |
