rust/src/librustc_mir/const_eval/error.rs

61 lines
2.1 KiB
Rust
Raw Normal View History

use std::error::Error;
use std::fmt;
2020-02-12 19:40:31 +01:00
use rustc::mir::AssertKind;
use rustc_span::Symbol;
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.
#[derive(Clone, Debug)]
2020-02-08 22:21:20 +01:00
pub enum ConstEvalErrKind {
NeedsRfc(String),
ConstAccessesStatic,
ModifiedGlobal,
2020-02-12 19:40:31 +01:00
AssertFailure(AssertKind<u64>),
Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
}
2020-02-08 22:21:20 +01:00
// The errors become `MachineStop` with plain strings when being raised.
// `ConstEvalErr` (in `librustc/mir/interpret/error.rs`) knows to
// handle these.
impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
fn into(self) -> InterpErrorInfo<'tcx> {
2020-03-23 08:48:03 +01:00
err_machine_stop!(self.to_string()).into()
}
}
2020-02-08 22:21:20 +01:00
impl fmt::Display for ConstEvalErrKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2020-02-08 22:21:20 +01:00
use self::ConstEvalErrKind::*;
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")
}
AssertFailure(ref msg) => write!(f, "{:?}", msg),
Panic { msg, line, col, file } => {
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col)
}
}
}
}
2020-02-08 22:21:20 +01:00
impl Error for ConstEvalErrKind {}
/// 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!
pub fn error_to_const_error<'mir, 'tcx, M: Machine<'mir, 'tcx>>(
ecx: &InterpCx<'mir, 'tcx, M>,
mut error: InterpErrorInfo<'tcx>,
) -> ConstEvalErr<'tcx> {
error.print_backtrace();
let stacktrace = ecx.generate_stacktrace(None);
ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span }
}