<commit_before>use std::cell::RefCell;
use std::fmt;

use log::trace;

use rustc_middle::ty::{self, TyCtxt};
use rustc_span::{source_map::DUMMY_SP, Span};

use crate::*;

/// Details of premature program termination.
pub enum TerminationInfo {
    Exit(i64),
    Abort(Option<String>),
    UnsupportedInIsolation(String),
    ExperimentalUb { msg: String, url: String },
    Deadlock,
}

impl fmt::Display for TerminationInfo {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use TerminationInfo::*;
        match self {
            Exit(code) =>
                write!(f, "the evaluated program completed with exit code {}", code),
            Abort(None) =>
                write!(f, "the evaluated program aborted execution"),
            Abort(Some(msg)) =>
                write!(f, "the evaluated program aborted execution: {}", msg),
            UnsupportedInIsolation(msg) =>
                write!(f, "{}", msg),
            ExperimentalUb { msg, .. } =>
                write!(f, "{}", msg),
            Deadlock =>
                write!(f, "the evaluated program deadlocked"),
        }
    }
}

impl MachineStopType for TerminationInfo {}

/// Miri specific diagnostics
pub enum NonHaltingDiagnostic {
    PoppedPointerTag(Item),
    CreatedCallId(CallId),
    CreatedAlloc(AllocId),
    FreedAlloc(AllocId),
}

/// Emit a custom diagnostic without going through the miri-engine machinery
pub fn report_error<'tcx, 'mir>(
    ecx: &InterpCx<'mir, 'tcx, Evaluator<'mir, 'tcx>>,
    e: InterpErrorInfo<'tcx>,
) -> Option<i64> {
    use InterpError::*;

    let (title, helps) = match &e.kind {
        MachineStop(info) => {
            let info = info.downcast_ref::<TerminationInfo>().expect("invalid MachineStop payload");
            use TerminationInfo::*;
            let title = match info {
                Exit(code) => return Some(*code),
                Abort(_) =>
                    "abnormal termination",
                UnsupportedInIsolation(_) =>
                    "unsupported operation",
                ExperimentalUb { .. } =>
                    "Undefined Behavior",
                Deadlock => "deadlock",
            };
            let helps = match info {
                UnsupportedInIsolation(_) =>
                    vec![format!("pass the flag `-Zmiri-disable-isolation` to disable isolation")],
                ExperimentalUb { url, .. } =>
                    vec![
                        format!("this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental"),
                        format!("see {} for further information", url),
                    ],
                _ => vec![],
            };
            (title, helps)
        }
        _ => {
            let title = match e.kind {
                Unsupported(_) =>
                    "unsupported operation",
                UndefinedBehavior(_) =>
                    "Undefined Behavior",
                ResourceExhaustion(_) =>
                    "resource exhaustion",
                _ =>
                    bug!("This error should be impossible in Miri: {}", e),
            };
            let helps = match e.kind {
                Unsupported(UnsupportedOpInfo::NoMirFor(..)) =>
                    vec![format!("make sure to use a Miri sysroot, which you can prepare with `cargo miri setup`")],
                Unsupported(UnsupportedOpInfo::ReadBytesAsPointer | UnsupportedOpInfo::ThreadLocalStatic(_) | UnsupportedOpInfo::ReadExternStatic(_)) =>
                    panic!("Error should never be raised by Miri: {:?}", e.kind),<commit_msg>Auto merge of #1503 - RalfJung:post-mono, r=RalfJung<commit_after>use std::cell::RefCell;
use std::fmt;

use log::trace;

use rustc_middle::ty::{self, TyCtxt};
use rustc_span::{source_map::DUMMY_SP, Span};

use crate::*;

/// Details of premature program termination.
pub enum TerminationInfo {
    Exit(i64),
    Abort(Option<String>),
    UnsupportedInIsolation(String),
    ExperimentalUb { msg: String, url: String },
    Deadlock,
}

impl fmt::Display for TerminationInfo {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use TerminationInfo::*;
        match self {
            Exit(code) =>
                write!(f, "the evaluated program completed with exit code {}", code),
            Abort(None) =>
                write!(f, "the evaluated program aborted execution"),
            Abort(Some(msg)) =>
                write!(f, "the evaluated program aborted execution: {}", msg),
            UnsupportedInIsolation(msg) =>
                write!(f, "{}", msg),
            ExperimentalUb { msg, .. } =>
                write!(f, "{}", msg),
            Deadlock =>
                write!(f, "the evaluated program deadlocked"),
        }
    }
}

impl MachineStopType for TerminationInfo {}

/// Miri specific diagnostics
pub enum NonHaltingDiagnostic {
    PoppedPointerTag(Item),
    CreatedCallId(CallId),
    CreatedAlloc(AllocId),
    FreedAlloc(AllocId),
}

/// Emit a custom diagnostic without going through the miri-engine machinery
pub fn report_error<'tcx, 'mir>(
    ecx: &InterpCx<'mir, 'tcx, Evaluator<'mir, 'tcx>>,
    e: InterpErrorInfo<'tcx>,
) -> Option<i64> {
    use InterpError::*;

    let (title, helps) = match &e.kind {
        MachineStop(info) => {
            let info = info.downcast_ref::<TerminationInfo>().expect("invalid MachineStop payload");
            use TerminationInfo::*;
            let title = match info {
                Exit(code) => return Some(*code),
                Abort(_) =>
                    "abnormal termination",
                UnsupportedInIsolation(_) =>
                    "unsupported operation",
                ExperimentalUb { .. } =>
                    "Undefined Behavior",
                Deadlock => "deadlock",
            };
            let helps = match info {
                UnsupportedInIsolation(_) =>
                    vec![format!("pass the flag `-Zmiri-disable-isolation` to disable isolation")],
                ExperimentalUb { url, .. } =>
                    vec![
                        format!("this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental"),
                        format!("see {} for further information", url),
                    ],
                _ => vec![],
            };
            (title, helps)
        }
        _ => {
            let title = match e.kind {
                Unsupported(_) =>
                    "unsupported operation",
                UndefinedBehavior(_) =>
                    "Undefined Behavior",
                ResourceExhaustion(_) =>
                    "resource exhaustion",
                InvalidProgram(InvalidProgramInfo::ReferencedConstant) =>
                    "post-monomorphization error",
                _ =>
                    bug!("This error should be impossible in Miri: {}", e),
            };
            let helps = match e.kind {
                Unsupported(UnsupportedOpInfo::NoMirFor(..)) =>
                    vec![format!("make sure to use a Miri sysroot, which you can prepare with `cargo miri setup`")],
                Unsupported(UnsupportedOpInfo::ReadBytesAsPointer | UnsupportedOpInfo::ThreadLocalStatic(_) | UnsupportedOpInfo::ReadExternStatic(_)) =>
                    panic!("Error should never be raised by Miri: {:?}", e.kind),
{'fraction_non_alphanumeric': 0.12249264509227066, 'fraction_numerical': 0.0016047071409467772, 'mean_word_length': 1.8765384615384615, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 68, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '306868', 'n_tokens_mistral': 2004, 'n_tokens_neox': 1952, 'n_words': 503}