2019-12-25 01:04:32 +01:00
|
|
|
use std::error::Error;
|
|
|
|
use std::fmt;
|
|
|
|
|
2020-03-29 16:41:09 +02:00
|
|
|
use rustc_middle::mir::AssertKind;
|
2020-06-19 18:57:15 +02:00
|
|
|
use rustc_middle::ty::ConstInt;
|
2020-06-01 11:17:38 +02:00
|
|
|
use rustc_span::{Span, Symbol};
|
2020-02-09 16:51:36 +01:00
|
|
|
|
2019-12-25 01:06:51 +01:00
|
|
|
use super::InterpCx;
|
2020-03-23 08:48:03 +01:00
|
|
|
use crate::interpret::{ConstEvalErr, InterpErrorInfo, Machine};
|
2020-02-08 22:21:20 +01:00
|
|
|
|
|
|
|
/// The CTFE machine has some custom error kinds.
|
2019-12-25 01:04:32 +01:00
|
|
|
#[derive(Clone, Debug)]
|
2020-02-08 22:21:20 +01:00
|
|
|
pub enum ConstEvalErrKind {
|
2019-12-25 01:04:32 +01:00
|
|
|
NeedsRfc(String),
|
|
|
|
ConstAccessesStatic,
|
2020-03-21 19:19:10 +01:00
|
|
|
ModifiedGlobal,
|
2020-06-19 18:57:15 +02:00
|
|
|
AssertFailure(AssertKind<ConstInt>),
|
2020-02-09 16:51:36 +01:00
|
|
|
Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
|
2019-12-25 01:04:32 +01:00
|
|
|
}
|
|
|
|
|
2020-02-08 22:21:20 +01:00
|
|
|
// The errors become `MachineStop` with plain strings when being raised.
|
2020-03-29 15:24:45 +02:00
|
|
|
// `ConstEvalErr` (in `librustc_middle/mir/interpret/error.rs`) knows to
|
2020-02-08 22:21:20 +01:00
|
|
|
// handle these.
|
|
|
|
impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
|
2019-12-25 01:04:32 +01:00
|
|
|
fn into(self) -> InterpErrorInfo<'tcx> {
|
2020-03-23 08:48:03 +01:00
|
|
|
err_machine_stop!(self.to_string()).into()
|
2019-12-25 01:04:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-08 22:21:20 +01:00
|
|
|
impl fmt::Display for ConstEvalErrKind {
|
2019-12-25 01:04:32 +01:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2020-02-08 22:21:20 +01:00
|
|
|
use self::ConstEvalErrKind::*;
|
2019-12-25 01:04:32 +01:00
|
|
|
match *self {
|
|
|
|
NeedsRfc(ref msg) => {
|
|
|
|
write!(f, "\"{}\" needs an rfc before being allowed inside constants", msg)
|
|
|
|
}
|
|
|
|
ConstAccessesStatic => write!(f, "constant accesses static"),
|
2020-03-22 09:23:19 +01:00
|
|
|
ModifiedGlobal => {
|
|
|
|
write!(f, "modifying a static's initial value from another static's initializer")
|
|
|
|
}
|
2020-02-09 16:51:36 +01:00
|
|
|
AssertFailure(ref msg) => write!(f, "{:?}", msg),
|
|
|
|
Panic { msg, line, col, file } => {
|
|
|
|
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col)
|
|
|
|
}
|
2019-12-25 01:04:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-08 22:21:20 +01:00
|
|
|
impl Error for ConstEvalErrKind {}
|
2019-12-25 01:06:51 +01:00
|
|
|
|
|
|
|
/// Turn an interpreter error into something to report to the user.
|
|
|
|
/// As a side-effect, if RUSTC_CTFE_BACKTRACE is set, this prints the backtrace.
|
|
|
|
/// Should be called only if the error is actually going to to be reported!
|
2020-03-16 15:12:42 -07:00
|
|
|
pub fn error_to_const_error<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>(
|
2019-12-25 01:06:51 +01:00
|
|
|
ecx: &InterpCx<'mir, 'tcx, M>,
|
2020-04-30 18:24:43 +02:00
|
|
|
error: InterpErrorInfo<'tcx>,
|
2020-06-01 11:17:38 +02:00
|
|
|
span: Option<Span>,
|
2019-12-25 01:06:51 +01:00
|
|
|
) -> ConstEvalErr<'tcx> {
|
|
|
|
error.print_backtrace();
|
2020-03-30 23:08:21 +02:00
|
|
|
let stacktrace = ecx.generate_stacktrace();
|
2020-06-01 11:17:38 +02:00
|
|
|
ConstEvalErr { error: error.kind, stacktrace, span: span.unwrap_or_else(|| ecx.cur_span()) }
|
2019-12-25 01:06:51 +01:00
|
|
|
}
|