use std::error::Error; use std::fmt; use rustc::mir::repr as mir; use memory::Pointer; #[derive(Clone, Debug)] pub enum EvalError { DanglingPointerDeref, InvalidBool, InvalidDiscriminant, PointerOutOfBounds { ptr: Pointer, size: usize, allocation_size: usize, }, ReadPointerAsBytes, ReadBytesAsPointer, InvalidPointerMath, ReadUndefBytes, InvalidBoolOp(mir::BinOp), Unimplemented(String), } pub type EvalResult = Result; impl Error for EvalError { fn description(&self) -> &str { match *self { EvalError::DanglingPointerDeref => "dangling pointer was dereferenced", EvalError::InvalidBool => "invalid boolean value read", EvalError::InvalidDiscriminant => "invalid enum discriminant value read", EvalError::PointerOutOfBounds { .. } => "pointer offset outside bounds of allocation", EvalError::ReadPointerAsBytes => "a raw memory access tried to access part of a pointer value as raw bytes", EvalError::ReadBytesAsPointer => "attempted to interpret some raw bytes as a pointer address", EvalError::InvalidPointerMath => "attempted to do math or a comparison on pointers into different allocations", EvalError::ReadUndefBytes => "attempted to read undefined bytes", EvalError::InvalidBoolOp(_) => "invalid boolean operation", EvalError::Unimplemented(ref msg) => msg, } } fn cause(&self) -> Option<&Error> { None } } impl fmt::Display for EvalError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { EvalError::PointerOutOfBounds { ptr, size, allocation_size } => { write!(f, "memory access of {}..{} outside bounds of allocation {} which has size {}", ptr.offset, ptr.offset + size, ptr.alloc_id, allocation_size) }, _ => write!(f, "{}", self.description()), } } }