2018-08-22 16:52:01 -03:00
|
|
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2017-08-04 10:55:35 -07:00
|
|
|
use std::{fmt, env};
|
2017-08-02 16:59:01 +02:00
|
|
|
|
2018-11-14 17:25:06 +01:00
|
|
|
use hir::map::definitions::DefPathData;
|
2017-09-18 16:18:23 +02:00
|
|
|
use mir;
|
2018-11-14 17:25:06 +01:00
|
|
|
use ty::{self, Ty, layout};
|
2018-09-08 22:14:55 +03:00
|
|
|
use ty::layout::{Size, AbiAndPrefAlign, LayoutError};
|
2018-08-27 13:34:35 +02:00
|
|
|
use rustc_target::spec::abi::Abi;
|
2017-07-21 13:39:06 +02:00
|
|
|
|
2018-11-06 14:17:40 +01:00
|
|
|
use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef};
|
2017-07-21 13:39:06 +02:00
|
|
|
|
2017-08-03 12:37:52 +02:00
|
|
|
use backtrace::Backtrace;
|
2016-03-14 21:48:00 -06:00
|
|
|
|
2018-06-25 18:46:02 +02:00
|
|
|
use ty::query::TyCtxtAt;
|
|
|
|
use errors::DiagnosticBuilder;
|
|
|
|
|
2018-11-14 23:14:57 +01:00
|
|
|
use syntax_pos::{Pos, Span};
|
2018-06-25 18:46:02 +02:00
|
|
|
use syntax::ast;
|
2018-08-13 13:48:47 +02:00
|
|
|
use syntax::symbol::Symbol;
|
2018-06-25 18:46:02 +02:00
|
|
|
|
2018-09-20 08:06:57 +02:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
2018-08-26 15:19:34 +02:00
|
|
|
pub enum ErrorHandled {
|
|
|
|
/// Already reported a lint or an error for this evaluation
|
|
|
|
Reported,
|
|
|
|
/// Don't emit an error, the evaluation failed because the MIR was generic
|
|
|
|
/// and the substs didn't fully monomorphize it.
|
|
|
|
TooGeneric,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ErrorHandled {
|
|
|
|
pub fn assert_reported(self) {
|
|
|
|
match self {
|
|
|
|
ErrorHandled::Reported => {},
|
|
|
|
ErrorHandled::TooGeneric => bug!("MIR interpretation failed without reporting an error \
|
|
|
|
even though it was fully monomorphized"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-06 14:17:40 +01:00
|
|
|
pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
|
2018-08-26 15:19:34 +02:00
|
|
|
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
|
2018-06-25 18:46:02 +02:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
|
|
|
pub struct ConstEvalErr<'tcx> {
|
|
|
|
pub span: Span,
|
2018-09-18 11:01:13 +02:00
|
|
|
pub error: ::mir::interpret::EvalErrorKind<'tcx, u64>,
|
2018-11-14 17:25:06 +01:00
|
|
|
pub stacktrace: Vec<FrameInfo<'tcx>>,
|
2018-06-25 18:46:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
2018-11-14 17:25:06 +01:00
|
|
|
pub struct FrameInfo<'tcx> {
|
2018-11-15 08:59:49 +01:00
|
|
|
pub call_site: Span, // this span is in the caller!
|
2018-11-14 17:25:06 +01:00
|
|
|
pub instance: ty::Instance<'tcx>,
|
2018-06-25 18:46:02 +02:00
|
|
|
pub lint_root: Option<ast::NodeId>,
|
|
|
|
}
|
|
|
|
|
2018-11-14 17:25:06 +01:00
|
|
|
impl<'tcx> fmt::Display for FrameInfo<'tcx> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
ty::tls::with(|tcx| {
|
|
|
|
if tcx.def_key(self.instance.def_id()).disambiguated_data.data
|
|
|
|
== DefPathData::ClosureExpr
|
|
|
|
{
|
2018-11-14 23:14:57 +01:00
|
|
|
write!(f, "inside call to closure")?;
|
2018-11-14 17:25:06 +01:00
|
|
|
} else {
|
2018-11-14 23:14:57 +01:00
|
|
|
write!(f, "inside call to `{}`", self.instance)?;
|
2018-11-14 17:25:06 +01:00
|
|
|
}
|
2018-11-15 08:59:49 +01:00
|
|
|
if !self.call_site.is_dummy() {
|
|
|
|
let lo = tcx.sess.source_map().lookup_char_pos_adj(self.call_site.lo());
|
2018-11-14 23:14:57 +01:00
|
|
|
write!(f, " at {}:{}:{}", lo.filename, lo.line, lo.col.to_usize() + 1)?;
|
|
|
|
}
|
|
|
|
Ok(())
|
2018-11-14 17:25:06 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-25 18:46:02 +02:00
|
|
|
impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
|
|
|
pub fn struct_error(&self,
|
|
|
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
|
|
|
message: &str)
|
2018-08-26 15:19:34 +02:00
|
|
|
-> Result<DiagnosticBuilder<'tcx>, ErrorHandled>
|
2018-06-25 18:46:02 +02:00
|
|
|
{
|
|
|
|
self.struct_generic(tcx, message, None)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn report_as_error(&self,
|
|
|
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
|
|
|
message: &str
|
2018-08-26 15:19:34 +02:00
|
|
|
) -> ErrorHandled {
|
2018-06-04 18:32:06 +02:00
|
|
|
let err = self.struct_error(tcx, message);
|
2018-08-26 15:19:34 +02:00
|
|
|
match err {
|
|
|
|
Ok(mut err) => {
|
|
|
|
err.emit();
|
|
|
|
ErrorHandled::Reported
|
|
|
|
},
|
|
|
|
Err(err) => err,
|
2018-06-25 18:46:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn report_as_lint(&self,
|
|
|
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
|
|
|
message: &str,
|
|
|
|
lint_root: ast::NodeId,
|
2018-08-26 15:19:34 +02:00
|
|
|
) -> ErrorHandled {
|
2018-06-25 18:46:02 +02:00
|
|
|
let lint = self.struct_generic(
|
|
|
|
tcx,
|
|
|
|
message,
|
|
|
|
Some(lint_root),
|
|
|
|
);
|
2018-08-26 15:19:34 +02:00
|
|
|
match lint {
|
|
|
|
Ok(mut lint) => {
|
|
|
|
lint.emit();
|
|
|
|
ErrorHandled::Reported
|
|
|
|
},
|
|
|
|
Err(err) => err,
|
2018-06-25 18:46:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn struct_generic(
|
|
|
|
&self,
|
|
|
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
|
|
|
message: &str,
|
|
|
|
lint_root: Option<ast::NodeId>,
|
2018-08-26 15:19:34 +02:00
|
|
|
) -> Result<DiagnosticBuilder<'tcx>, ErrorHandled> {
|
2018-09-18 11:01:13 +02:00
|
|
|
match self.error {
|
2018-08-30 16:30:20 +02:00
|
|
|
EvalErrorKind::Layout(LayoutError::Unknown(_)) |
|
2018-08-26 15:19:34 +02:00
|
|
|
EvalErrorKind::TooGeneric => return Err(ErrorHandled::TooGeneric),
|
2018-08-30 16:30:20 +02:00
|
|
|
EvalErrorKind::Layout(LayoutError::SizeOverflow(_)) |
|
|
|
|
EvalErrorKind::TypeckError => return Err(ErrorHandled::Reported),
|
2018-06-25 18:46:02 +02:00
|
|
|
_ => {},
|
|
|
|
}
|
|
|
|
trace!("reporting const eval failure at {:?}", self.span);
|
|
|
|
let mut err = if let Some(lint_root) = lint_root {
|
|
|
|
let node_id = self.stacktrace
|
|
|
|
.iter()
|
|
|
|
.rev()
|
|
|
|
.filter_map(|frame| frame.lint_root)
|
|
|
|
.next()
|
|
|
|
.unwrap_or(lint_root);
|
|
|
|
tcx.struct_span_lint_node(
|
|
|
|
::rustc::lint::builtin::CONST_ERR,
|
|
|
|
node_id,
|
|
|
|
tcx.span,
|
|
|
|
message,
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
struct_error(tcx, message)
|
|
|
|
};
|
|
|
|
err.span_label(self.span, self.error.to_string());
|
2018-11-14 17:25:06 +01:00
|
|
|
// Skip the last, which is just the environment of the constant. The stacktrace
|
|
|
|
// is sometimes empty because we create "fake" eval contexts in CTFE to do work
|
|
|
|
// on constant values.
|
|
|
|
if self.stacktrace.len() > 0 {
|
|
|
|
for frame_info in &self.stacktrace[..self.stacktrace.len()-1] {
|
2018-11-15 08:59:49 +01:00
|
|
|
err.span_label(frame_info.call_site, frame_info.to_string());
|
2018-11-14 17:25:06 +01:00
|
|
|
}
|
2018-06-25 18:46:02 +02:00
|
|
|
}
|
2018-08-26 15:19:34 +02:00
|
|
|
Ok(err)
|
2018-06-25 18:46:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn struct_error<'a, 'gcx, 'tcx>(
|
|
|
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
|
|
|
msg: &str,
|
|
|
|
) -> DiagnosticBuilder<'tcx> {
|
|
|
|
struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
|
|
|
|
}
|
|
|
|
|
2018-09-18 11:01:13 +02:00
|
|
|
#[derive(Debug, Clone)]
|
2017-08-02 16:59:01 +02:00
|
|
|
pub struct EvalError<'tcx> {
|
2018-04-27 15:21:31 +02:00
|
|
|
pub kind: EvalErrorKind<'tcx, u64>,
|
2018-09-18 11:01:13 +02:00
|
|
|
pub backtrace: Option<Box<Backtrace>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> EvalError<'tcx> {
|
|
|
|
pub fn print_backtrace(&mut self) {
|
|
|
|
if let Some(ref mut backtrace) = self.backtrace {
|
2018-10-09 22:02:15 +02:00
|
|
|
eprintln!("{}", print_backtrace(&mut *backtrace));
|
2018-09-18 11:01:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_backtrace(backtrace: &mut Backtrace) -> String {
|
|
|
|
use std::fmt::Write;
|
|
|
|
|
|
|
|
backtrace.resolve();
|
|
|
|
|
|
|
|
let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
|
|
|
|
write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
|
|
|
|
'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
|
|
|
|
if frame.symbols().is_empty() {
|
2018-11-14 17:48:17 +01:00
|
|
|
write!(trace_text, " {}: no symbols\n", i).unwrap();
|
2018-09-18 11:01:13 +02:00
|
|
|
}
|
2018-11-14 17:48:17 +01:00
|
|
|
let mut first = true;
|
2018-09-18 11:01:13 +02:00
|
|
|
for symbol in frame.symbols() {
|
2018-11-14 17:48:17 +01:00
|
|
|
if first {
|
|
|
|
write!(trace_text, " {}: ", i).unwrap();
|
|
|
|
first = false;
|
|
|
|
} else {
|
|
|
|
let len = i.to_string().len();
|
|
|
|
write!(trace_text, " {} ", " ".repeat(len)).unwrap();
|
|
|
|
}
|
2018-09-18 11:01:13 +02:00
|
|
|
if let Some(name) = symbol.name() {
|
|
|
|
write!(trace_text, "{}\n", name).unwrap();
|
|
|
|
} else {
|
|
|
|
write!(trace_text, "<unknown>\n").unwrap();
|
|
|
|
}
|
2018-11-14 17:48:17 +01:00
|
|
|
write!(trace_text, " at ").unwrap();
|
2018-09-18 11:01:13 +02:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
trace_text
|
2017-08-02 16:59:01 +02:00
|
|
|
}
|
|
|
|
|
2018-06-03 03:01:06 +02:00
|
|
|
impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
|
|
|
|
fn from(kind: EvalErrorKind<'tcx, u64>) -> Self {
|
2018-09-18 11:01:13 +02:00
|
|
|
let backtrace = match env::var("RUST_CTFE_BACKTRACE") {
|
|
|
|
// matching RUST_BACKTRACE, we treat "0" the same as "not present".
|
|
|
|
Ok(ref val) if val != "0" => {
|
|
|
|
let mut backtrace = Backtrace::new_unresolved();
|
2018-06-03 03:01:06 +02:00
|
|
|
|
2018-09-18 11:01:13 +02:00
|
|
|
if val == "immediate" {
|
|
|
|
// Print it now
|
2018-10-09 22:02:15 +02:00
|
|
|
eprintln!("{}", print_backtrace(&mut backtrace));
|
2018-09-18 11:01:13 +02:00
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(Box::new(backtrace))
|
2018-06-02 23:38:57 +02:00
|
|
|
}
|
2018-06-03 03:01:06 +02:00
|
|
|
},
|
2018-09-18 11:01:13 +02:00
|
|
|
_ => None,
|
|
|
|
};
|
2017-08-02 16:59:01 +02:00
|
|
|
EvalError {
|
2018-01-31 10:39:30 +01:00
|
|
|
kind,
|
2018-09-18 11:01:13 +02:00
|
|
|
backtrace,
|
2017-08-02 16:59:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-27 15:21:31 +02:00
|
|
|
pub type AssertMessage<'tcx> = EvalErrorKind<'tcx, mir::Operand<'tcx>>;
|
|
|
|
|
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
|
|
|
pub enum EvalErrorKind<'tcx, O> {
|
2017-07-25 11:32:48 +02:00
|
|
|
/// This variant is used by machines to signal their own errors that do not
|
|
|
|
/// match an existing variant
|
2018-01-16 09:13:50 +01:00
|
|
|
MachineError(String),
|
2018-08-27 13:34:35 +02:00
|
|
|
|
|
|
|
FunctionAbiMismatch(Abi, Abi),
|
|
|
|
FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),
|
2018-10-02 21:16:35 +02:00
|
|
|
FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>),
|
2018-08-27 13:34:35 +02:00
|
|
|
FunctionArgCountMismatch,
|
2016-09-27 17:01:06 +02:00
|
|
|
NoMirFor(String),
|
2018-05-21 00:37:44 +02:00
|
|
|
UnterminatedCString(Pointer),
|
2016-03-14 21:48:00 -06:00
|
|
|
DanglingPointerDeref,
|
2017-07-12 14:51:47 +02:00
|
|
|
DoubleFree,
|
2016-09-22 15:47:16 +02:00
|
|
|
InvalidMemoryAccess,
|
2016-06-08 13:43:34 +02:00
|
|
|
InvalidFunctionPointer,
|
2016-03-14 21:48:00 -06:00
|
|
|
InvalidBool,
|
2018-11-12 10:32:23 +01:00
|
|
|
InvalidDiscriminant(ScalarMaybeUndef),
|
2016-05-31 12:05:25 +02:00
|
|
|
PointerOutOfBounds {
|
2018-05-21 00:37:44 +02:00
|
|
|
ptr: Pointer,
|
2018-11-12 11:22:18 +01:00
|
|
|
check: InboundsCheck,
|
2018-05-19 16:37:29 +02:00
|
|
|
allocation_size: Size,
|
2016-05-31 12:05:25 +02:00
|
|
|
},
|
2017-06-22 18:41:10 -07:00
|
|
|
InvalidNullPointerUsage,
|
2016-03-18 23:03:46 -06:00
|
|
|
ReadPointerAsBytes,
|
2017-06-19 10:58:59 +02:00
|
|
|
ReadBytesAsPointer,
|
2018-05-29 01:38:18 +01:00
|
|
|
ReadForeignStatic,
|
2016-03-18 23:03:46 -06:00
|
|
|
InvalidPointerMath,
|
2018-09-02 17:22:46 +03:00
|
|
|
ReadUndefBytes(Size),
|
2017-05-31 17:41:33 -07:00
|
|
|
DeadLocal,
|
2016-05-30 15:27:52 +02:00
|
|
|
InvalidBoolOp(mir::BinOp),
|
|
|
|
Unimplemented(String),
|
2016-06-13 11:39:15 +02:00
|
|
|
DerefFunctionPointer,
|
|
|
|
ExecuteMemory,
|
2018-04-27 15:21:31 +02:00
|
|
|
BoundsCheck { len: O, index: O },
|
2018-04-26 14:52:59 +02:00
|
|
|
Overflow(mir::BinOp),
|
|
|
|
OverflowNeg,
|
|
|
|
DivisionByZero,
|
|
|
|
RemainderByZero,
|
2017-06-22 00:08:19 -07:00
|
|
|
Intrinsic(String),
|
2017-01-12 08:28:42 +01:00
|
|
|
InvalidChar(u128),
|
2016-07-05 13:23:58 +02:00
|
|
|
StackFrameLimitReached,
|
2017-05-25 16:40:13 -07:00
|
|
|
OutOfTls,
|
|
|
|
TlsOutOfBounds,
|
2017-05-25 22:38:07 -07:00
|
|
|
AbiViolation(String),
|
2016-07-05 14:27:27 +02:00
|
|
|
AlignmentCheckFailed {
|
2018-09-08 22:14:55 +03:00
|
|
|
required: AbiAndPrefAlign,
|
|
|
|
has: AbiAndPrefAlign,
|
2016-07-05 14:27:27 +02:00
|
|
|
},
|
2017-07-13 20:08:35 -07:00
|
|
|
ValidationFailure(String),
|
2016-09-09 12:51:14 +02:00
|
|
|
CalledClosureAsFunction,
|
|
|
|
VtableForArgumentlessMethod,
|
2016-09-09 17:44:04 +02:00
|
|
|
ModifiedConstantMemory,
|
2016-09-13 13:08:57 +02:00
|
|
|
AssumptionNotHeld,
|
2016-09-28 11:48:43 -06:00
|
|
|
InlineAsm,
|
2016-11-03 12:30:41 +01:00
|
|
|
TypeNotPrimitive(Ty<'tcx>),
|
2017-07-28 16:48:43 +02:00
|
|
|
ReallocatedWrongMemoryKind(String, String),
|
|
|
|
DeallocatedWrongMemoryKind(String, String),
|
2017-07-03 16:06:06 -07:00
|
|
|
ReallocateNonBasePtr,
|
|
|
|
DeallocateNonBasePtr,
|
2018-09-08 22:14:55 +03:00
|
|
|
IncorrectAllocationInformation(Size, Size, AbiAndPrefAlign, AbiAndPrefAlign),
|
2016-11-17 17:23:40 +01:00
|
|
|
Layout(layout::LayoutError<'tcx>),
|
2017-06-23 12:55:49 +02:00
|
|
|
HeapAllocZeroBytes,
|
|
|
|
HeapAllocNonPowerOfTwoAlignment(u64),
|
2017-01-12 09:41:36 +01:00
|
|
|
Unreachable,
|
2018-08-13 13:48:47 +02:00
|
|
|
Panic {
|
|
|
|
msg: Symbol,
|
|
|
|
line: u32,
|
|
|
|
col: u32,
|
|
|
|
file: Symbol,
|
|
|
|
},
|
2017-06-28 13:37:23 +02:00
|
|
|
ReadFromReturnPointer,
|
2017-07-12 10:36:14 +02:00
|
|
|
PathNotFound(Vec<String>),
|
2017-12-06 09:25:29 +01:00
|
|
|
UnimplementedTraitSelection,
|
|
|
|
/// Abort in case type errors are reached
|
|
|
|
TypeckError,
|
2018-06-19 16:40:53 +02:00
|
|
|
/// Resolution can fail if we are in a too generic context
|
2018-06-25 15:08:05 +02:00
|
|
|
TooGeneric,
|
2018-01-31 15:06:45 +01:00
|
|
|
/// Cannot compute this constant because it depends on another one
|
|
|
|
/// which already produced an error
|
2018-08-26 15:19:34 +02:00
|
|
|
ReferencedConstant,
|
2018-04-27 15:21:31 +02:00
|
|
|
GeneratorResumedAfterReturn,
|
|
|
|
GeneratorResumedAfterPanic,
|
2018-06-24 01:44:23 -07:00
|
|
|
InfiniteLoop,
|
2016-03-14 21:48:00 -06:00
|
|
|
}
|
|
|
|
|
2017-02-04 13:09:10 -08:00
|
|
|
pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;
|
2016-03-14 21:48:00 -06:00
|
|
|
|
2018-04-27 15:21:31 +02:00
|
|
|
impl<'tcx, O> EvalErrorKind<'tcx, O> {
|
2018-04-26 14:52:59 +02:00
|
|
|
pub fn description(&self) -> &str {
|
2017-08-02 16:59:01 +02:00
|
|
|
use self::EvalErrorKind::*;
|
2018-04-26 14:52:59 +02:00
|
|
|
match *self {
|
2018-01-16 09:13:50 +01:00
|
|
|
MachineError(ref inner) => inner,
|
2018-10-02 21:16:35 +02:00
|
|
|
FunctionAbiMismatch(..) | FunctionArgMismatch(..) | FunctionRetMismatch(..)
|
|
|
|
| FunctionArgCountMismatch =>
|
2018-08-27 13:34:35 +02:00
|
|
|
"tried to call a function through a function pointer of incompatible type",
|
2017-07-03 16:06:06 -07:00
|
|
|
InvalidMemoryAccess =>
|
2016-09-22 15:47:16 +02:00
|
|
|
"tried to access memory through an invalid pointer",
|
2017-07-03 16:06:06 -07:00
|
|
|
DanglingPointerDeref =>
|
2016-03-26 23:56:49 -06:00
|
|
|
"dangling pointer was dereferenced",
|
2017-07-12 14:51:47 +02:00
|
|
|
DoubleFree =>
|
|
|
|
"tried to deallocate dangling pointer",
|
2017-07-03 16:06:06 -07:00
|
|
|
InvalidFunctionPointer =>
|
2017-08-08 13:06:14 +02:00
|
|
|
"tried to use a function pointer after offsetting it",
|
2017-07-03 16:06:06 -07:00
|
|
|
InvalidBool =>
|
2016-03-26 23:56:49 -06:00
|
|
|
"invalid boolean value read",
|
2018-08-26 14:22:59 +02:00
|
|
|
InvalidDiscriminant(..) =>
|
|
|
|
"invalid enum discriminant value read",
|
2017-07-03 16:06:06 -07:00
|
|
|
PointerOutOfBounds { .. } =>
|
2016-03-26 23:56:49 -06:00
|
|
|
"pointer offset outside bounds of allocation",
|
2017-07-03 16:06:06 -07:00
|
|
|
InvalidNullPointerUsage =>
|
2017-06-22 18:41:10 -07:00
|
|
|
"invalid use of NULL pointer",
|
2017-07-13 17:25:38 -07:00
|
|
|
ValidationFailure(..) =>
|
|
|
|
"type validation failed",
|
2017-07-03 16:06:06 -07:00
|
|
|
ReadPointerAsBytes =>
|
2016-03-18 23:03:46 -06:00
|
|
|
"a raw memory access tried to access part of a pointer value as raw bytes",
|
2017-07-03 16:06:06 -07:00
|
|
|
ReadBytesAsPointer =>
|
2017-06-19 10:58:59 +02:00
|
|
|
"a memory access tried to interpret some bytes as a pointer",
|
2018-05-29 01:38:18 +01:00
|
|
|
ReadForeignStatic =>
|
2018-06-25 00:08:36 +01:00
|
|
|
"tried to read from foreign (extern) static",
|
2017-07-03 16:06:06 -07:00
|
|
|
InvalidPointerMath =>
|
2018-08-22 16:54:05 -03:00
|
|
|
"attempted to do invalid arithmetic on pointers that would leak base addresses, \
|
|
|
|
e.g. comparing pointers into different allocations",
|
2018-09-02 17:22:46 +03:00
|
|
|
ReadUndefBytes(_) =>
|
2016-03-26 23:56:49 -06:00
|
|
|
"attempted to read undefined bytes",
|
2017-07-03 16:06:06 -07:00
|
|
|
DeadLocal =>
|
2017-05-31 17:41:33 -07:00
|
|
|
"tried to access a dead local variable",
|
2017-07-03 16:06:06 -07:00
|
|
|
InvalidBoolOp(_) =>
|
2016-05-30 15:27:52 +02:00
|
|
|
"invalid boolean operation",
|
2017-07-03 16:06:06 -07:00
|
|
|
Unimplemented(ref msg) => msg,
|
|
|
|
DerefFunctionPointer =>
|
2016-06-13 11:39:15 +02:00
|
|
|
"tried to dereference a function pointer",
|
2017-07-03 16:06:06 -07:00
|
|
|
ExecuteMemory =>
|
2016-06-13 11:39:15 +02:00
|
|
|
"tried to treat a memory pointer as a function pointer",
|
2018-04-27 15:21:31 +02:00
|
|
|
BoundsCheck{..} =>
|
2016-06-17 13:09:20 +02:00
|
|
|
"array index out of bounds",
|
2017-07-03 16:06:06 -07:00
|
|
|
Intrinsic(..) =>
|
2017-06-22 00:08:19 -07:00
|
|
|
"intrinsic failed",
|
2017-07-03 16:06:06 -07:00
|
|
|
NoMirFor(..) =>
|
2016-09-27 17:01:06 +02:00
|
|
|
"mir not found",
|
2017-07-03 16:06:06 -07:00
|
|
|
InvalidChar(..) =>
|
2016-06-20 12:29:45 +02:00
|
|
|
"tried to interpret an invalid 32-bit value as a char",
|
2017-07-03 16:06:06 -07:00
|
|
|
StackFrameLimitReached =>
|
2016-07-05 13:23:58 +02:00
|
|
|
"reached the configured maximum number of stack frames",
|
2017-07-03 16:06:06 -07:00
|
|
|
OutOfTls =>
|
2017-05-25 16:40:13 -07:00
|
|
|
"reached the maximum number of representable TLS keys",
|
2017-07-03 16:06:06 -07:00
|
|
|
TlsOutOfBounds =>
|
2017-05-25 16:40:13 -07:00
|
|
|
"accessed an invalid (unallocated) TLS key",
|
2017-07-03 16:06:06 -07:00
|
|
|
AbiViolation(ref msg) => msg,
|
|
|
|
AlignmentCheckFailed{..} =>
|
2016-07-05 14:27:27 +02:00
|
|
|
"tried to execute a misaligned read or write",
|
2017-07-03 16:06:06 -07:00
|
|
|
CalledClosureAsFunction =>
|
2016-09-09 12:51:14 +02:00
|
|
|
"tried to call a closure through a function pointer",
|
2017-07-03 16:06:06 -07:00
|
|
|
VtableForArgumentlessMethod =>
|
2016-09-09 12:51:14 +02:00
|
|
|
"tried to call a vtable function without arguments",
|
2017-07-03 16:06:06 -07:00
|
|
|
ModifiedConstantMemory =>
|
2016-09-09 17:44:04 +02:00
|
|
|
"tried to modify constant memory",
|
2017-07-03 16:06:06 -07:00
|
|
|
AssumptionNotHeld =>
|
2016-09-28 18:22:25 +02:00
|
|
|
"`assume` argument was false",
|
2017-07-03 16:06:06 -07:00
|
|
|
InlineAsm =>
|
2017-02-10 05:27:02 -08:00
|
|
|
"miri does not support inline assembly",
|
2017-07-03 16:06:06 -07:00
|
|
|
TypeNotPrimitive(_) =>
|
2016-11-03 12:30:41 +01:00
|
|
|
"expected primitive type, got nonprimitive",
|
2017-07-12 14:51:47 +02:00
|
|
|
ReallocatedWrongMemoryKind(_, _) =>
|
2017-08-03 12:37:24 +02:00
|
|
|
"tried to reallocate memory from one kind to another",
|
2017-07-12 14:51:47 +02:00
|
|
|
DeallocatedWrongMemoryKind(_, _) =>
|
|
|
|
"tried to deallocate memory of the wrong kind",
|
2017-07-03 16:06:06 -07:00
|
|
|
ReallocateNonBasePtr =>
|
|
|
|
"tried to reallocate with a pointer not to the beginning of an existing object",
|
|
|
|
DeallocateNonBasePtr =>
|
|
|
|
"tried to deallocate with a pointer not to the beginning of an existing object",
|
2017-12-06 09:25:29 +01:00
|
|
|
IncorrectAllocationInformation(..) =>
|
2017-07-03 16:06:06 -07:00
|
|
|
"tried to deallocate or reallocate using incorrect alignment or size",
|
|
|
|
Layout(_) =>
|
2016-11-17 17:23:40 +01:00
|
|
|
"rustc layout computation failed",
|
2017-07-03 16:06:06 -07:00
|
|
|
UnterminatedCString(_) =>
|
2018-08-23 08:45:59 -07:00
|
|
|
"attempted to get length of a null terminated string, but no null found before end \
|
2018-08-22 16:54:05 -03:00
|
|
|
of allocation",
|
2017-07-03 16:06:06 -07:00
|
|
|
HeapAllocZeroBytes =>
|
2017-06-23 12:55:49 +02:00
|
|
|
"tried to re-, de- or allocate zero bytes on the heap",
|
2017-07-03 16:06:06 -07:00
|
|
|
HeapAllocNonPowerOfTwoAlignment(_) =>
|
2018-08-23 08:45:59 -07:00
|
|
|
"tried to re-, de-, or allocate heap memory with alignment that is not a power of \
|
2018-08-22 16:54:05 -03:00
|
|
|
two",
|
2017-07-03 16:06:06 -07:00
|
|
|
Unreachable =>
|
2017-01-12 09:41:36 +01:00
|
|
|
"entered unreachable code",
|
2018-08-13 13:48:47 +02:00
|
|
|
Panic { .. } =>
|
2017-02-09 10:34:23 +01:00
|
|
|
"the evaluated program panicked",
|
2017-07-03 16:06:06 -07:00
|
|
|
ReadFromReturnPointer =>
|
2017-06-28 13:37:23 +02:00
|
|
|
"tried to read from the return pointer",
|
2018-04-27 15:21:31 +02:00
|
|
|
PathNotFound(_) =>
|
2017-07-12 10:36:14 +02:00
|
|
|
"a path could not be resolved, maybe the crate is not loaded",
|
2017-12-06 09:25:29 +01:00
|
|
|
UnimplementedTraitSelection =>
|
|
|
|
"there were unresolved type arguments during trait selection",
|
|
|
|
TypeckError =>
|
|
|
|
"encountered constants with type errors, stopping evaluation",
|
2018-06-25 15:08:05 +02:00
|
|
|
TooGeneric =>
|
2018-06-19 16:40:53 +02:00
|
|
|
"encountered overly generic constant",
|
2018-08-26 15:19:34 +02:00
|
|
|
ReferencedConstant =>
|
2018-01-31 15:06:45 +01:00
|
|
|
"referenced constant has errors",
|
2018-04-26 14:52:59 +02:00
|
|
|
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
|
|
|
|
Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
|
|
|
|
Overflow(mir::BinOp::Mul) => "attempt to multiply with overflow",
|
|
|
|
Overflow(mir::BinOp::Div) => "attempt to divide with overflow",
|
|
|
|
Overflow(mir::BinOp::Rem) => "attempt to calculate the remainder with overflow",
|
|
|
|
OverflowNeg => "attempt to negate with overflow",
|
|
|
|
Overflow(mir::BinOp::Shr) => "attempt to shift right with overflow",
|
|
|
|
Overflow(mir::BinOp::Shl) => "attempt to shift left with overflow",
|
|
|
|
Overflow(op) => bug!("{:?} cannot overflow", op),
|
|
|
|
DivisionByZero => "attempt to divide by zero",
|
|
|
|
RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
|
2018-04-27 15:21:31 +02:00
|
|
|
GeneratorResumedAfterReturn => "generator resumed after completion",
|
|
|
|
GeneratorResumedAfterPanic => "generator resumed after panicking",
|
2018-06-26 18:54:59 -07:00
|
|
|
InfiniteLoop =>
|
2018-06-29 13:32:54 -07:00
|
|
|
"duplicate interpreter state observed here, const evaluation will never terminate",
|
2016-03-14 21:48:00 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-14 10:34:54 +02:00
|
|
|
impl<'tcx> fmt::Display for EvalError<'tcx> {
|
2018-08-29 22:02:42 -07:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2018-09-18 11:01:13 +02:00
|
|
|
write!(f, "{}", self.kind)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> fmt::Display for EvalErrorKind<'tcx, u64> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(f, "{:?}", self)
|
2018-04-27 15:21:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
|
2018-08-29 22:02:42 -07:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2017-08-02 16:59:01 +02:00
|
|
|
use self::EvalErrorKind::*;
|
2018-04-27 15:21:31 +02:00
|
|
|
match *self {
|
2018-11-12 11:22:18 +01:00
|
|
|
PointerOutOfBounds { ptr, check, allocation_size } => {
|
|
|
|
write!(f, "Pointer must be in-bounds{} at offset {}, but is outside bounds of \
|
|
|
|
allocation {} which has size {}",
|
|
|
|
match check {
|
|
|
|
InboundsCheck::Live => " and live",
|
|
|
|
InboundsCheck::MaybeDead => "",
|
|
|
|
},
|
2018-05-19 16:37:29 +02:00
|
|
|
ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes())
|
2016-06-01 11:22:37 +02:00
|
|
|
},
|
2017-07-13 17:25:38 -07:00
|
|
|
ValidationFailure(ref err) => {
|
|
|
|
write!(f, "type validation failed: {}", err)
|
|
|
|
}
|
2017-07-03 16:06:06 -07:00
|
|
|
NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
|
2018-08-27 13:34:35 +02:00
|
|
|
FunctionAbiMismatch(caller_abi, callee_abi) =>
|
|
|
|
write!(f, "tried to call a function with ABI {:?} using caller ABI {:?}",
|
|
|
|
callee_abi, caller_abi),
|
|
|
|
FunctionArgMismatch(caller_ty, callee_ty) =>
|
|
|
|
write!(f, "tried to call a function with argument of type {:?} \
|
|
|
|
passing data of type {:?}",
|
|
|
|
callee_ty, caller_ty),
|
2018-10-02 21:16:35 +02:00
|
|
|
FunctionRetMismatch(caller_ty, callee_ty) =>
|
|
|
|
write!(f, "tried to call a function with return type {:?} \
|
|
|
|
passing return place of type {:?}",
|
|
|
|
callee_ty, caller_ty),
|
2018-08-27 13:34:35 +02:00
|
|
|
FunctionArgCountMismatch =>
|
|
|
|
write!(f, "tried to call a function with incorrect number of arguments"),
|
2018-04-27 15:21:31 +02:00
|
|
|
BoundsCheck { ref len, ref index } =>
|
|
|
|
write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
|
2017-07-28 16:48:43 +02:00
|
|
|
ReallocatedWrongMemoryKind(ref old, ref new) =>
|
|
|
|
write!(f, "tried to reallocate memory from {} to {}", old, new),
|
|
|
|
DeallocatedWrongMemoryKind(ref old, ref new) =>
|
|
|
|
write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
|
2017-07-03 16:06:06 -07:00
|
|
|
Intrinsic(ref err) =>
|
2017-06-22 00:08:19 -07:00
|
|
|
write!(f, "{}", err),
|
2017-07-03 16:06:06 -07:00
|
|
|
InvalidChar(c) =>
|
2016-06-21 09:43:27 +02:00
|
|
|
write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c),
|
2017-07-03 16:06:06 -07:00
|
|
|
AlignmentCheckFailed { required, has } =>
|
2016-07-05 14:27:27 +02:00
|
|
|
write!(f, "tried to access memory with alignment {}, but alignment {} is required",
|
2018-05-19 16:37:29 +02:00
|
|
|
has.abi(), required.abi()),
|
2017-07-03 16:06:06 -07:00
|
|
|
TypeNotPrimitive(ty) =>
|
2016-11-03 12:30:41 +01:00
|
|
|
write!(f, "expected primitive type, got {}", ty),
|
2017-07-03 16:06:06 -07:00
|
|
|
Layout(ref err) =>
|
2016-11-17 17:23:40 +01:00
|
|
|
write!(f, "rustc layout computation failed: {:?}", err),
|
2017-07-25 11:32:48 +02:00
|
|
|
PathNotFound(ref path) =>
|
2017-07-12 10:36:14 +02:00
|
|
|
write!(f, "Cannot find path {:?}", path),
|
2017-07-25 11:32:48 +02:00
|
|
|
MachineError(ref inner) =>
|
2018-01-26 15:19:01 +01:00
|
|
|
write!(f, "{}", inner),
|
2017-12-06 09:25:29 +01:00
|
|
|
IncorrectAllocationInformation(size, size2, align, align2) =>
|
2018-08-22 16:54:05 -03:00
|
|
|
write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and \
|
|
|
|
align {}", size.bytes(), align.abi(), size2.bytes(), align2.abi()),
|
2018-08-13 13:48:47 +02:00
|
|
|
Panic { ref msg, line, col, ref file } =>
|
|
|
|
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col),
|
2018-08-26 14:22:59 +02:00
|
|
|
InvalidDiscriminant(val) =>
|
|
|
|
write!(f, "encountered invalid enum discriminant {}", val),
|
2018-04-27 15:21:31 +02:00
|
|
|
_ => write!(f, "{}", self.description()),
|
2018-04-26 11:37:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|