Skip to content

Commit b9f6b97

Browse files
committed
Split error reporting from main eval function
1 parent 71a7b9b commit b9f6b97

File tree

1 file changed

+56
-54
lines changed

1 file changed

+56
-54
lines changed

src/eval.rs

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rand::SeedableRng;
88
use rustc_hir::def_id::DefId;
99
use rustc::ty::layout::{LayoutOf, Size};
1010
use rustc::ty::{self, TyCtxt};
11+
use rustc_mir::interpret::InterpErrorInfo;
1112

1213
use crate::*;
1314

@@ -205,64 +206,65 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) ->
205206
}
206207
return Some(return_code);
207208
}
208-
Err(mut e) => {
209-
// Special treatment for some error kinds
210-
let msg = match e.kind {
211-
InterpError::MachineStop(ref info) => {
212-
let info = info
213-
.downcast_ref::<TerminationInfo>()
214-
.expect("invalid MachineStop payload");
215-
match info {
216-
TerminationInfo::Exit(code) => return Some(*code),
217-
TerminationInfo::PoppedTrackedPointerTag(item) =>
218-
format!("popped tracked tag for item {:?}", item),
219-
TerminationInfo::Abort =>
220-
format!("the evaluated program aborted execution"),
221-
}
222-
}
223-
err_unsup!(NoMirFor(..)) => format!(
224-
"{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`.",
225-
e
226-
),
227-
InterpError::InvalidProgram(_) =>
228-
bug!("This error should be impossible in Miri: {}", e),
229-
_ => e.to_string(),
230-
};
231-
e.print_backtrace();
232-
if let Some(frame) = ecx.stack().last() {
233-
let span = frame.current_source_info().unwrap().span;
209+
Err(e) => report_err(&ecx, e),
210+
}
211+
}
234212

235-
let msg = format!("Miri evaluation error: {}", msg);
236-
let mut err = ecx.tcx.sess.struct_span_err(span, msg.as_str());
237-
let frames = ecx.generate_stacktrace(None);
238-
err.span_label(span, msg);
239-
// We iterate with indices because we need to look at the next frame (the caller).
240-
for idx in 0..frames.len() {
241-
let frame_info = &frames[idx];
242-
let call_site_is_local = frames
243-
.get(idx + 1)
244-
.map_or(false, |caller_info| caller_info.instance.def_id().is_local());
245-
if call_site_is_local {
246-
err.span_note(frame_info.call_site, &frame_info.to_string());
247-
} else {
248-
err.note(&frame_info.to_string());
249-
}
250-
}
251-
err.emit();
252-
} else {
253-
ecx.tcx.sess.err(&msg);
213+
fn report_err<'tcx, 'mir>(
214+
ecx: &InterpCx<'mir, 'tcx, Evaluator<'tcx>>,
215+
mut e: InterpErrorInfo<'tcx>,
216+
) -> Option<i64> {
217+
// Special treatment for some error kinds
218+
let msg = match e.kind {
219+
InterpError::MachineStop(ref info) => {
220+
let info = info.downcast_ref::<TerminationInfo>().expect("invalid MachineStop payload");
221+
match info {
222+
TerminationInfo::Exit(code) => return Some(*code),
223+
TerminationInfo::PoppedTrackedPointerTag(item) =>
224+
format!("popped tracked tag for item {:?}", item),
225+
TerminationInfo::Abort => format!("the evaluated program aborted execution"),
254226
}
227+
}
228+
err_unsup!(NoMirFor(..)) => format!(
229+
"{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`.",
230+
e
231+
),
232+
InterpError::InvalidProgram(_) => bug!("This error should be impossible in Miri: {}", e),
233+
_ => e.to_string(),
234+
};
235+
e.print_backtrace();
236+
if let Some(frame) = ecx.stack().last() {
237+
let span = frame.current_source_info().unwrap().span;
255238

256-
for (i, frame) in ecx.stack().iter().enumerate() {
257-
trace!("-------------------");
258-
trace!("Frame {}", i);
259-
trace!(" return: {:?}", frame.return_place.map(|p| *p));
260-
for (i, local) in frame.locals.iter().enumerate() {
261-
trace!(" local {}: {:?}", i, local.value);
262-
}
239+
let msg = format!("Miri evaluation error: {}", msg);
240+
let mut err = ecx.tcx.sess.struct_span_err(span, msg.as_str());
241+
let frames = ecx.generate_stacktrace(None);
242+
err.span_label(span, msg);
243+
// We iterate with indices because we need to look at the next frame (the caller).
244+
for idx in 0..frames.len() {
245+
let frame_info = &frames[idx];
246+
let call_site_is_local = frames
247+
.get(idx + 1)
248+
.map_or(false, |caller_info| caller_info.instance.def_id().is_local());
249+
if call_site_is_local {
250+
err.span_note(frame_info.call_site, &frame_info.to_string());
251+
} else {
252+
err.note(&frame_info.to_string());
263253
}
264-
// Let the reported error determine the return code.
265-
return None;
254+
}
255+
err.emit();
256+
} else {
257+
ecx.tcx.sess.err(&msg);
258+
}
259+
260+
for (i, frame) in ecx.stack().iter().enumerate() {
261+
trace!("-------------------");
262+
trace!("Frame {}", i);
263+
trace!(" return: {:?}", frame.return_place.map(|p| *p));
264+
for (i, local) in frame.locals.iter().enumerate() {
265+
trace!(" local {}: {:?}", i, local.value);
266266
}
267267
}
268+
// Let the reported error determine the return code.
269+
return None;
268270
}

0 commit comments

Comments
 (0)