diff --git a/src/diagnostics.rs b/src/diagnostics.rs index a4f40d51a3..e68dfad1b9 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -3,11 +3,13 @@ use std::cell::RefCell; use crate::*; +/// Miri specific diagnostics pub enum NonHaltingDiagnostic { PoppedTrackedPointerTag(Item), } -pub fn report_err<'tcx, 'mir>( +/// Emit a custom diagnostic without going through the miri-engine machinery +pub fn report_diagnostic<'tcx, 'mir>( ecx: &InterpCx<'mir, 'tcx, Evaluator<'tcx>>, mut e: InterpErrorInfo<'tcx>, ) -> Option { @@ -31,6 +33,8 @@ pub fn report_err<'tcx, 'mir>( report_msg(ecx, msg, true) } +/// Report an error or note (depending on the `error` argument) at the current frame's current statement. +/// Also emits a full stacktrace of the interpreter stack. pub fn report_msg<'tcx, 'mir>( ecx: &InterpCx<'mir, 'tcx, Evaluator<'tcx>>, msg: String, @@ -80,12 +84,15 @@ thread_local! { static DIAGNOSTICS: RefCell> = RefCell::new(Vec::new()); } +/// Schedule a diagnostic for emitting. This function works even if you have no `InterpCx` available. +/// The diagnostic will be emitted after the current interpreter step is finished. pub fn register_diagnostic(e: NonHaltingDiagnostic) { DIAGNOSTICS.with(|diagnostics| diagnostics.borrow_mut().push(e)); } impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> { + /// Emit all diagnostics that were registed with `register_diagnostics` fn process_diagnostics(&self) { let this = self.eval_context_ref(); DIAGNOSTICS.with(|diagnostics| { diff --git a/src/eval.rs b/src/eval.rs index e9e74db9b7..7a3945220f 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -206,6 +206,6 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) -> } Some(return_code) } - Err(e) => report_err(&ecx, e), + Err(e) => report_diagnostic(&ecx, e), } } diff --git a/src/lib.rs b/src/lib.rs index 4d2411a669..880a14b98c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,7 @@ pub use crate::shims::tls::{EvalContextExt as TlsEvalContextExt, TlsData}; pub use crate::shims::EvalContextExt as ShimsEvalContextExt; pub use crate::diagnostics::{ - register_diagnostic, report_err, EvalContextExt as DiagnosticsEvalContextExt, NonHaltingDiagnostic, + register_diagnostic, report_diagnostic, EvalContextExt as DiagnosticsEvalContextExt, NonHaltingDiagnostic, }; pub use crate::eval::{create_ecx, eval_main, MiriConfig, TerminationInfo}; pub use crate::helpers::EvalContextExt as HelpersEvalContextExt;