diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 397d2ffd565b1..be9babfef7256 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -7,7 +7,7 @@ use rustc_data_structures::sync::Lock; use rustc_errors::{pluralize, struct_span_err, DiagnosticBuilder, ErrorReported}; use rustc_macros::HashStable; use rustc_session::CtfeBacktrace; -use rustc_span::def_id::DefId; +use rustc_span::{def_id::DefId, Symbol}; use rustc_target::abi::{Align, Size}; use std::{any::Any, backtrace::Backtrace, fmt, mem}; @@ -439,6 +439,8 @@ pub enum InterpError<'tcx> { /// The program exhausted the interpreter's resources (stack/heap too big, /// execution takes too long, ...). ResourceExhaustion(ResourceExhaustionInfo), + /// The program terminated immediately from a panic. + Panic(Symbol), /// Stop execution for a machine-controlled reason. This is never raised by /// the core engine itself. MachineStop(Box), @@ -454,6 +456,7 @@ impl fmt::Display for InterpError<'_> { InvalidProgram(ref msg) => write!(f, "{}", msg), UndefinedBehavior(ref msg) => write!(f, "{}", msg), ResourceExhaustion(ref msg) => write!(f, "{}", msg), + Panic(ref msg) => write!(f, "{}", msg), MachineStop(ref msg) => write!(f, "{}", msg), } } diff --git a/compiler/rustc_mir/src/const_eval/error.rs b/compiler/rustc_mir/src/const_eval/error.rs index 39358e03e7590..8cac718c0a5d2 100644 --- a/compiler/rustc_mir/src/const_eval/error.rs +++ b/compiler/rustc_mir/src/const_eval/error.rs @@ -22,12 +22,15 @@ pub enum ConstEvalErrKind { Panic { msg: Symbol, line: u32, col: u32, file: Symbol }, } -// The errors become `MachineStop` with plain strings when being raised. +// Non-panic errors become `MachineStop` with plain strings when being raised. // `ConstEvalErr` (in `librustc_middle/mir/interpret/error.rs`) knows to // handle these. impl<'tcx> Into> for ConstEvalErrKind { fn into(self) -> InterpErrorInfo<'tcx> { - err_machine_stop!(self.to_string()).into() + match self { + ConstEvalErrKind::Panic { msg, .. } => InterpError::Panic(msg).into(), + _ => err_machine_stop!(self.to_string()).into(), + } } } @@ -150,13 +153,14 @@ impl<'tcx> ConstEvalErr<'tcx> { }; trace!("reporting const eval failure at {:?}", self.span); - let err_msg = match &self.error { + let (err_msg, is_panic) = match &self.error { InterpError::MachineStop(msg) => { // A custom error (`ConstEvalErrKind` in `librustc_mir/interp/const_eval/error.rs`). // Should be turned into a string by now. - msg.downcast_ref::().expect("invalid MachineStop payload").clone() + (msg.downcast_ref::().expect("invalid MachineStop payload").clone(), false) } - err => err.to_string(), + InterpError::Panic(msg) => (msg.to_string(), true), + err => (err.to_string(), false), }; let finish = |mut err: DiagnosticBuilder<'_>, span_msg: Option| { @@ -193,7 +197,13 @@ impl<'tcx> ConstEvalErr<'tcx> { rustc_session::lint::builtin::CONST_ERR, hir_id, tcx.span, - |lint| finish(lint.build(message), Some(err_msg)), + |lint| { + if is_panic { + finish(lint.build(&err_msg), None) + } else { + finish(lint.build(message), Some(err_msg)) + } + }, ); ErrorHandled::Linted } else {