print stacktrace when miri can't find the MIR for something
This commit is contained in:
parent
69aeaea01f
commit
db8185e439
4 changed files with 18 additions and 11 deletions
|
@ -9,6 +9,7 @@ use syntax::codemap::Span;
|
|||
#[derive(Clone, Debug)]
|
||||
pub enum EvalError<'tcx> {
|
||||
FunctionPointerTyMismatch(&'tcx BareFnTy<'tcx>, &'tcx BareFnTy<'tcx>),
|
||||
NoMirFor(String),
|
||||
DanglingPointerDeref,
|
||||
InvalidMemoryAccess,
|
||||
InvalidFunctionPointer,
|
||||
|
@ -82,6 +83,8 @@ impl<'tcx> Error for EvalError<'tcx> {
|
|||
"array index out of bounds",
|
||||
EvalError::Math(..) =>
|
||||
"mathematical operation failed",
|
||||
EvalError::NoMirFor(..) =>
|
||||
"mir not found",
|
||||
EvalError::InvalidChar(..) =>
|
||||
"tried to interpret an invalid 32-bit value as a char",
|
||||
EvalError::OutOfMemory{..} =>
|
||||
|
@ -113,6 +116,7 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
|
|||
write!(f, "memory access of {}..{} outside bounds of allocation {} which has size {}",
|
||||
ptr.offset, ptr.offset + size, ptr.alloc_id, allocation_size)
|
||||
},
|
||||
EvalError::NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
|
||||
EvalError::FunctionPointerTyMismatch(expected, got) =>
|
||||
write!(f, "tried to call a function of type {:?} through a function pointer of type {:?}", expected, got),
|
||||
EvalError::ArrayIndexOutOfBounds(span, len, index) =>
|
||||
|
|
|
@ -267,22 +267,25 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
ty.is_sized(self.tcx, &self.tcx.empty_parameter_environment(), DUMMY_SP)
|
||||
}
|
||||
|
||||
pub fn load_mir(&self, def_id: DefId) -> CachedMir<'a, 'tcx> {
|
||||
pub fn load_mir(&self, def_id: DefId) -> EvalResult<'tcx, CachedMir<'a, 'tcx>> {
|
||||
trace!("load mir {:?}", def_id);
|
||||
if def_id.is_local() {
|
||||
CachedMir::Ref(self.mir_map.map.get(&def_id).unwrap())
|
||||
Ok(CachedMir::Ref(self.mir_map.map.get(&def_id).unwrap()))
|
||||
} else {
|
||||
let mut mir_cache = self.mir_cache.borrow_mut();
|
||||
if let Some(mir) = mir_cache.get(&def_id) {
|
||||
return CachedMir::Owned(mir.clone());
|
||||
return Ok(CachedMir::Owned(mir.clone()));
|
||||
}
|
||||
|
||||
let cs = &self.tcx.sess.cstore;
|
||||
let mir = cs.maybe_get_item_mir(self.tcx, def_id).unwrap_or_else(|| {
|
||||
panic!("no mir for `{}`", self.tcx.item_path_str(def_id));
|
||||
});
|
||||
match cs.maybe_get_item_mir(self.tcx, def_id) {
|
||||
Some(mir) => {
|
||||
let cached = Rc::new(mir);
|
||||
mir_cache.insert(def_id, cached.clone());
|
||||
CachedMir::Owned(cached)
|
||||
Ok(CachedMir::Owned(cached))
|
||||
},
|
||||
None => Err(EvalError::NoMirFor(self.tcx.item_path_str(def_id))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -125,8 +125,8 @@ impl<'a, 'b, 'tcx> ConstantExtractor<'a, 'b, 'tcx> {
|
|||
if self.ecx.statics.contains_key(&cid) {
|
||||
return;
|
||||
}
|
||||
let mir = self.ecx.load_mir(def_id);
|
||||
self.try(|this| {
|
||||
let mir = this.ecx.load_mir(def_id)?;
|
||||
let ptr = this.ecx.alloc_ret_ptr(mir.return_ty, substs)?;
|
||||
this.ecx.statics.insert(cid.clone(), ptr);
|
||||
let cleanup = if immutable && !mir.return_ty.type_contents(this.ecx.tcx).interior_unsafe() {
|
||||
|
|
|
@ -184,7 +184,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
(def_id, substs)
|
||||
};
|
||||
|
||||
let mir = self.load_mir(resolved_def_id);
|
||||
let mir = self.load_mir(resolved_def_id)?;
|
||||
let (return_ptr, return_to_block) = match destination {
|
||||
Some((ptr, block)) => (Some(ptr), StackPopCleanup::Goto(block)),
|
||||
None => (None, StackPopCleanup::None),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue