use std::borrow::{Borrow, Cow};
use std::fmt;
use std::hash::Hash;

use rustc_abi::{Align, Size};
use rustc_ast::Mutability;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem};
use rustc_middle::mir::AssertMessage;
use rustc_middle::mir::interpret::ReportedErrorInfo;
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout, ValidityRequirement};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_span::{Span, Symbol, sym};
use rustc_target::callconv::FnAbi;
use tracing::debug;

use super::error::*;
use crate::errors::{LongRunning, LongRunningWarn};
use crate::fluent_generated as fluent;
use crate::interpret::{
    self, AllocId, AllocInit, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame,
    GlobalAlloc, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, Pointer, RangeSet, Scalar,
    compile_time_machine, err_inval, interp_ok, throw_exhaust, throw_inval, throw_ub,
    throw_ub_custom, throw_unsup, throw_unsup_format,
};

/// When hitting this many interpreted terminators we emit a deny by default lint
/// that notfies the user that their constant takes a long time to evaluate. If that's
/// what they intended, they can just allow the lint.
const LINT_TERMINATOR_LIMIT: usize = 2_000_000;
/// The limit used by `-Z tiny-const-eval-limit`. This smaller limit is useful for internal
/// tests not needing to run 30s or more to show some behaviour.
const TINY_LINT_TERMINATOR_LIMIT: usize = 20;
/// After this many interpreted terminators, we start emitting progress indicators at every
/// power of two of interpreted terminators.
const PROGRESS_INDICATOR_START: usize = 4_000_000;

/// Extra machine state for CTFE, and the Machine instance.
//
// Should be public because out-of-tree rustc consumers need this
// if they want to interact with constant values.
pub struct CompileTimeMachine<'tcx> {
    /// The number of terminators that have been evaluated.
    ///
    /// This is used to produce lints informing the user that the compiler is not stuck.
    /// Set to `usize::MAX` to never report anything.
    pub(super) num_evaluated_steps: usize,

    /// The virtual call stack.
    pub(super) stack: Vec<Frame<'tcx>>,

    /// Pattern matching on consts with references would be unsound if those references
    /// could point to anything mutable. Therefore, when evaluating consts and when constructing valtrees,
    /// we ensure that only immutable global memory can be accessed.
    pub(super) can_access_mut_global: CanAccessMutGlobal,

    /// Whether to check alignment during evaluation.
    pub(super) check_alignment: CheckAlignment,

    /// If `Some`, we are evaluating the initializer of the static with the given `LocalDefId`,
    /// storing the result in the given `AllocId`.
    /// Used to prevent accesses to a static's base allocation, as that may allow for self-initialization loops.
    pub(crate) static_root_ids: Option<(AllocId, LocalDefId)>,

    /// A cache of "data range" computations for unions (i.e., the offsets of non-padding bytes).
    union_data_ranges: FxHashMap<Ty<'tcx>, RangeSet>,
}

#[derive(Copy, Clone)]
pub enum CheckAlignment {
    /// Ignore all alignment requirements.
    /// This is mainly used in interning.
    No,
    /// Hard error when dereferencing a misaligned pointer.
    Error,
}

#[derive(Copy, Clone, PartialEq)]
pub(crate) enum CanAccessMutGlobal {
    No,
    Yes,
}

impl From<bool> for CanAccessMutGlobal {
    fn from(value: bool) -> Self {
        if value { Self::Yes } else { Self::No }
    }
}

impl<'tcx> CompileTimeMachine<'tcx> {
    pub(crate) fn new(
        can_access_mut_global: CanAccessMutGlobal,
        check_alignment: CheckAlignment,
    ) -> Self {
        CompileTimeMachine {
            num_evaluated_steps: 0,
            stack: Vec::new(),
            can_access_mut_global,
            check_alignment,
            static_root_ids: None,
            union_data_ranges: FxHashMap::default(),
        }
    }
}

impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxIndexMap<K, V> {
    #[inline(always)]
    fn contains_key<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> bool
    where
        K: Borrow<Q>,
    {
        FxIndexMap::contains_key(self, k)
    }

    #[inline(always)]
    fn contains_key_ref<Q: ?Sized + Hash + Eq>(&self, k: &Q) -> bool
    where
        K: Borrow<Q>,
    {
        FxIndexMap::contains_key(self, k)
    }

    #[inline(always)]
    fn insert(&mut self, k: K, v: V) -> Option<V> {
        FxIndexMap::insert(self, k, v)
    }

    #[inline(always)]
    fn remove<Q: ?Sized + Hash + Eq>(&mut self, k: &Q) -> Option<V>
    where
        K: Borrow<Q>,
    {
        // FIXME(#120456) - is `swap_remove` correct?
        FxIndexMap::swap_remove(self, k)
    }

    #[inline(always)]
    fn filter_map_collect<T>(&self, mut f: impl FnMut(&K, &V) -> Option<T>) -> Vec<T> {
        self.iter().filter_map(move |(k, v)| f(k, v)).collect()
    }

    #[inline(always)]
    fn get_or<E>(&self, k: K, vacant: impl FnOnce() -> Result<V, E>) -> Result<&V, E> {
        match self.get(&k) {
            Some(v) => Ok(v),
            None => {
                vacant()?;
                bug!("The CTFE machine shouldn't ever need to extend the alloc_map when reading")
            }
        }
    }

    #[inline(always)]
    fn get_mut_or<E>(&mut self, k: K, vacant: impl FnOnce() -> Result<V, E>) -> Result<&mut V, E> {
        match self.entry(k) {
            IndexEntry::Occupied(e) => Ok(e.into_mut()),
            IndexEntry::Vacant(e) => {
                let v = vacant()?;
                Ok(e.insert(v))
            }
        }
    }
}

pub type CompileTimeInterpCx<'tcx> = InterpCx<'tcx, CompileTimeMachine<'tcx>>;

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum MemoryKind {
    Heap {
        /// Indicates whether `make_global` was called on this allocation.
        /// If this is `true`, the allocation must be immutable.
        was_made_global: bool,
    },
}

impl fmt::Display for MemoryKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            MemoryKind::Heap { was_made_global } => {
                write!(f, "heap allocation{}", if *was_made_global { " (made global)" } else { "" })
            }
        }
    }
}

impl interpret::MayLeak for MemoryKind {
    #[inline(always)]
    fn may_leak(self) -> bool {
        match self {
            MemoryKind::Heap { was_made_global } => was_made_global,
        }
    }
}

impl interpret::MayLeak for ! {
    #[inline(always)]
    fn may_leak(self) -> bool {
        // `self` is uninhabited
        self
    }
}

impl<'tcx> CompileTimeInterpCx<'tcx> {
    fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
        let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
        let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());

        use rustc_session::RemapFileNameExt;
        use rustc_session::config::RemapPathScopeComponents;
        (
            Symbol::intern(
                &caller
                    .file
                    .name
                    .for_scope(self.tcx.sess, RemapPathScopeComponents::DIAGNOSTICS)
                    .to_string_lossy(),
            ),
            u32::try_from(caller.line).unwrap(),
            u32::try_from(caller.col_display).unwrap().checked_add(1).unwrap(),
        )
    }

    /// "Intercept" a function call, because we have something special to do for it.
    /// All `#[rustc_do_not_const_check]` functions MUST be hooked here.
    /// If this returns `Some` function, which may be `instance` or a different function with
    /// compatible arguments, then evaluation should continue with that function.
    /// If this returns `None`, the function call has been handled and the function has returned.
    fn hook_special_const_fn(
        &mut self,
        instance: ty::Instance<'tcx>,
        args: &[FnArg<'tcx>],
        _dest: &PlaceTy<'tcx>,
        _ret: Option<mir::BasicBlock>,
    ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
        let def_id = instance.def_id();

        if self.tcx.is_lang_item(def_id, LangItem::PanicDisplay)
            || self.tcx.is_lang_item(def_id, LangItem::BeginPanic)
        {
            let args = self.copy_fn_args(args);
            // &str or &&str
            assert!(args.len() == 1);

            let mut msg_place = self.deref_pointer(&args[0])?;
            while msg_place.layout.ty.is_ref() {
                msg_place = self.deref_pointer(&msg_place)?;
            }

            let msg = Symbol::intern(self.read_str(&msg_place)?);
            let span = self.find_closest_untracked_caller_location();
            let (file, line, col) = self.location_triple_for_span(span);
            return Err(ConstEvalErrKind::Panic { msg, file, line, col }).into();
        } else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) {
            // For panic_fmt, call const_panic_fmt instead.
            let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, self.tcx.span);
            let new_instance = ty::Instance::expect_resolve(
                *self.tcx,
                self.typing_env(),
                const_def_id,
                instance.args,
                self.cur_span(),
            );

            return interp_ok(Some(new_instance));
        }
        interp_ok(Some(instance))
    }

    /// See documentation on the `ptr_guaranteed_cmp` intrinsic.
    /// Returns `2` if the result is unknown.
    /// Returns `1` if the pointers are guaranteed equal.
    /// Returns `0` if the pointers are guaranteed inequal.
    ///
    /// Note that this intrinsic is exposed on stable for comparison with null. In other words, any
    /// change to this function that affects comparison with null is insta-stable!
    fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
        interp_ok(match (a, b) {
            // Comparisons between integers are always known.
            (Scalar::Int(a), Scalar::Int(b)) => (a == b) as u8,
            // Comparing a pointer `ptr` with an integer `int` is equivalent to comparing
            // `ptr-int` with null, so we can reduce this case to a `scalar_may_be_null` test.
            (Scalar::Int(int), Scalar::Ptr(ptr, _)) | (Scalar::Ptr(ptr, _), Scalar::Int(int)) => {
                let int = int.to_target_usize(*self.tcx);
                // The `wrapping_neg` here may produce a value that is not
                // a valid target usize any more... but `wrapping_offset` handles that correctly.
                let offset_ptr = ptr.wrapping_offset(Size::from_bytes(int.wrapping_neg()), self);
                if !self.scalar_may_be_null(Scalar::from_pointer(offset_ptr, self))? {
                    // `ptr.wrapping_sub(int)` is definitely not equal to `0`, so `ptr != int`
                    0
                } else {
                    // `ptr.wrapping_sub(int)` could be equal to `0`, but might not be,
                    // so we cannot know for sure if `ptr == int` or not
                    2
                }
            }
            (Scalar::Ptr(a, _), Scalar::Ptr(b, _)) => {
                let (a_prov, a_offset) = a.prov_and_relative_offset();
                let (b_prov, b_offset) = b.prov_and_relative_offset();
                let a_allocid = a_prov.alloc_id();
                let b_allocid = b_prov.alloc_id();
                let a_info = self.get_alloc_info(a_allocid);
                let b_info = self.get_alloc_info(b_allocid);

                // Check if the pointers cannot be equal due to alignment
                if a_info.align > Align::ONE && b_info.align > Align::ONE {
                    let min_align = Ord::min(a_info.align.bytes(), b_info.align.bytes());
                    let a_residue = a_offset.bytes() % min_align;
                    let b_residue = b_offset.bytes() % min_align;
                    if a_residue != b_residue {
                        // If the two pointers have a different residue modulo their
                        // common alignment, they cannot be equal.
                        return interp_ok(0);
                    }
                    // The pointers have the same residue modulo their common alignment,
                    // so they could be equal. Try the other checks.
                }

                if let (Some(GlobalAlloc::Static(a_did)), Some(GlobalAlloc::Static(b_did))) = (
                    self.tcx.try_get_global_alloc(a_allocid),
                    self.tcx.try_get_global_alloc(b_allocid),
                ) {
                    if a_allocid == b_allocid {
                        debug_assert_eq!(
                            a_did, b_did,
                            "different static item DefIds had same AllocId? {a_allocid:?} == {b_allocid:?}, {a_did:?} != {b_did:?}"
                        );
                        // Comparing two pointers into the same static. As per
                        // https://doc.rust-lang.org/nightly/reference/items/static-items.html#r-items.static.intro
                        // a static cannot be duplicated, so if two pointers are into the same
                        // static, they are equal if and only if their offsets are equal.
                        (a_offset == b_offset) as u8
                    } else {
                        debug_assert_ne!(
                            a_did, b_did,
                            "same static item DefId had two different AllocIds? {a_allocid:?} != {b_allocid:?}, {a_did:?} == {b_did:?}"
                        );
                        // Comparing two pointers into the different statics.
                        // We can never determine for sure that two pointers into different statics
                        // are *equal*, but we can know that they are *inequal* if they are both
                        // strictly in-bounds (i.e. in-bounds and not one-past-the-end) of
                        // their respective static, as different non-zero-sized statics cannot
                        // overlap or be deduplicated as per
                        // https://doc.rust-lang.org/nightly/reference/items/static-items.html#r-items.static.intro
                        // (non-deduplication), and
                        // https://doc.rust-lang.org/nightly/reference/items/static-items.html#r-items.static.storage-disjointness
                        // (non-overlapping).
                        if a_offset < a_info.size && b_offset < b_info.size {
                            0
                        } else {
                            // Otherwise, conservatively say we don't know.
                            // There are some cases we could still return `0` for, e.g.
                            // if the pointers being equal would require their statics to overlap
                            // one or more bytes, but for simplicity we currently only check
                            // strictly in-bounds pointers.
                            2
                        }
                    }
                } else {
                    // All other cases we conservatively say we don't know.
                    //
                    // For comparing statics to non-statics, as per https://doc.rust-lang.org/nightly/reference/items/static-items.html#r-items.static.storage-disjointness
                    // immutable statics can overlap with other kinds of allocations sometimes.
                    //
                    // FIXME: We could be more decisive for (non-zero-sized) mutable statics,
                    // which cannot overlap with other kinds of allocations.
                    //
                    // Functions and vtables can be duplicated and deduplicated, so we
                    // cannot be sure of runtime equality of pointers to the same one, or the
                    // runtime inequality of pointers to different ones (see e.g. #73722),
                    // so comparing those should return 2, whether they are the same allocation
                    // or not.
                    //
                    // `GlobalAlloc::TypeId` exists mostly to prevent consteval from comparing
                    // `TypeId`s, so comparing those should always return 2, whether they are the
                    // same allocation or not.
                    //
                    // FIXME: We could revisit comparing pointers into the same
                    // `GlobalAlloc::Memory` once https://github.com/rust-lang/rust/issues/128775
                    // is fixed (but they can be deduplicated, so comparing pointers into different
                    // ones should return 2).
                    2
                }
            }
        })
    }
}

impl<'tcx> CompileTimeMachine<'tcx> {
    #[inline(always)]
    /// Find the first stack frame that is within the current crate, if any.
    /// Otherwise, return the crate's HirId
    pub fn best_lint_scope(&self, tcx: TyCtxt<'tcx>) -> hir::HirId {
        self.stack.iter().find_map(|frame| frame.lint_root(tcx)).unwrap_or(CRATE_HIR_ID)
    }
}

impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
    compile_time_machine!(<'tcx>);

    const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error

    #[inline(always)]
    fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool {
        matches!(ecx.machine.check_alignment, CheckAlignment::Error)
    }

    #[inline(always)]
    fn enforce_validity(ecx: &InterpCx<'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool {
        ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks || layout.is_uninhabited()
    }

    fn load_mir(
        ecx: &InterpCx<'tcx, Self>,
        instance: ty::InstanceKind<'tcx>,
    ) -> &'tcx mir::Body<'tcx> {
        match instance {
            ty::InstanceKind::Item(def) => ecx.tcx.mir_for_ctfe(def),
            _ => ecx.tcx.instance_mir(instance),
        }
    }

    fn find_mir_or_eval_fn(
        ecx: &mut InterpCx<'tcx, Self>,
        orig_instance: ty::Instance<'tcx>,
        _abi: &FnAbi<'tcx, Ty<'tcx>>,
        args: &[FnArg<'tcx>],
        dest: &PlaceTy<'tcx>,
        ret: Option<mir::BasicBlock>,
        _unwind: mir::UnwindAction, // unwinding is not supported in consts
    ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> {
        debug!("find_mir_or_eval_fn: {:?}", orig_instance);

        // Replace some functions.
        let Some(instance) = ecx.hook_special_const_fn(orig_instance, args, dest, ret)? else {
            // Call has already been handled.
            return interp_ok(None);
        };

        // Only check non-glue functions
        if let ty::InstanceKind::Item(def) = instance.def {
            // Execution might have wandered off into other crates, so we cannot do a stability-
            // sensitive check here. But we can at least rule out functions that are not const at
            // all. That said, we have to allow calling functions inside a `const trait`. These
            // *are* const-checked!
            if !ecx.tcx.is_const_fn(def) || ecx.tcx.has_attr(def, sym::rustc_do_not_const_check) {
                // We certainly do *not* want to actually call the fn
                // though, so be sure we return here.
                throw_unsup_format!("calling non-const function `{}`", instance)
            }
        }

        // This is a const fn. Call it.
        // In case of replacement, we return the *original* instance to make backtraces work out
        // (and we hope this does not confuse the FnAbi checks too much).
        interp_ok(Some((ecx.load_mir(instance.def, None)?, orig_instance)))
    }

    fn panic_nounwind(ecx: &mut InterpCx<'tcx, Self>, msg: &str) -> InterpResult<'tcx> {
        let msg = Symbol::intern(msg);
        let span = ecx.find_closest_untracked_caller_location();
        let (file, line, col) = ecx.location_triple_for_span(span);
        Err(ConstEvalErrKind::Panic { msg, file, line, col }).into()
    }

    fn call_intrinsic(
        ecx: &mut InterpCx<'tcx, Self>,
        instance: ty::Instance<'tcx>,
        args: &[OpTy<'tcx>],
        dest: &PlaceTy<'tcx, Self::Provenance>,
        target: Option<mir::BasicBlock>,
        _unwind: mir::UnwindAction,
    ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
        // Shared intrinsics.
        if ecx.eval_intrinsic(instance, args, dest, target)? {
            return interp_ok(None);
        }
        let intrinsic_name = ecx.tcx.item_name(instance.def_id());

        // CTFE-specific intrinsics.
        match intrinsic_name {
            sym::ptr_guaranteed_cmp => {
                let a = ecx.read_scalar(&args[0])?;
                let b = ecx.read_scalar(&args[1])?;
                let cmp = ecx.guaranteed_cmp(a, b)?;
                ecx.write_scalar(Scalar::from_u8(cmp), dest)?;
            }
            sym::const_allocate => {
                let size = ecx.read_scalar(&args[0])?.to_target_usize(ecx)?;
                let align = ecx.read_scalar(&args[1])?.to_target_usize(ecx)?;

                let align = match Align::from_bytes(align) {
                    Ok(a) => a,
                    Err(err) => throw_ub_custom!(
                        fluent::const_eval_invalid_align_details,
                        name = "const_allocate",
                        err_kind = err.diag_ident(),
                        align = err.align()
                    ),
                };

                let ptr = ecx.allocate_ptr(
                    Size::from_bytes(size),
                    align,
                    interpret::MemoryKind::Machine(MemoryKind::Heap { was_made_global: false }),
                    AllocInit::Uninit,
                )?;
                ecx.write_pointer(ptr, dest)?;
            }
            sym::const_deallocate => {
                let ptr = ecx.read_pointer(&args[0])?;
                let size = ecx.read_scalar(&args[1])?.to_target_usize(ecx)?;
                let align = ecx.read_scalar(&args[2])?.to_target_usize(ecx)?;

                let size = Size::from_bytes(size);
                let align = match Align::from_bytes(align) {
                    Ok(a) => a,
                    Err(err) => throw_ub_custom!(
                        fluent::const_eval_invalid_align_details,
                        name = "const_deallocate",
                        err_kind = err.diag_ident(),
                        align = err.align()
                    ),
                };

                // If an allocation is created in an another const,
                // we don't deallocate it.
                let (alloc_id, _, _) = ecx.ptr_get_alloc_id(ptr, 0)?;
                let is_allocated_in_another_const = matches!(
                    ecx.tcx.try_get_global_alloc(alloc_id),
                    Some(interpret::GlobalAlloc::Memory(_))
                );

                if !is_allocated_in_another_const {
                    ecx.deallocate_ptr(
                        ptr,
                        Some((size, align)),
                        interpret::MemoryKind::Machine(MemoryKind::Heap { was_made_global: false }),
                    )?;
                }
            }

            sym::const_make_global => {
                let ptr = ecx.read_pointer(&args[0])?;
                ecx.make_const_heap_ptr_global(ptr)?;
                ecx.write_pointer(ptr, dest)?;
            }

            // The intrinsic represents whether the value is known to the optimizer (LLVM).
            // We're not doing any optimizations here, so there is no optimizer that could know the value.
            // (We know the value here in the machine of course, but this is the runtime of that code,
            // not the optimization stage.)
            sym::is_val_statically_known => ecx.write_scalar(Scalar::from_bool(false), dest)?,

            // We handle these here since Miri does not want to have them.
            sym::assert_inhabited
            | sym::assert_zero_valid
            | sym::assert_mem_uninitialized_valid => {
                let ty = instance.args.type_at(0);
                let requirement = ValidityRequirement::from_intrinsic(intrinsic_name).unwrap();

                let should_panic = !ecx
                    .tcx
                    .check_validity_requirement((requirement, ecx.typing_env().as_query_input(ty)))
                    .map_err(|_| err_inval!(TooGeneric))?;

                if should_panic {
                    let layout = ecx.layout_of(ty)?;

                    let msg = match requirement {
                        // For *all* intrinsics we first check `is_uninhabited` to give a more specific
                        // error message.
                        _ if layout.is_uninhabited() => format!(
                            "aborted execution: attempted to instantiate uninhabited type `{ty}`"
                        ),
                        ValidityRequirement::Inhabited => bug!("handled earlier"),
                        ValidityRequirement::Zero => format!(
                            "aborted execution: attempted to zero-initialize type `{ty}`, which is invalid"
                        ),
                        ValidityRequirement::UninitMitigated0x01Fill => format!(
                            "aborted execution: attempted to leave type `{ty}` uninitialized, which is invalid"
                        ),
                        ValidityRequirement::Uninit => bug!("assert_uninit_valid doesn't exist"),
                    };

                    Self::panic_nounwind(ecx, &msg)?;
                    // Skip the `return_to_block` at the end (we panicked, we do not return).
                    return interp_ok(None);
                }
            }

            _ => {
                // We haven't handled the intrinsic, let's see if we can use a fallback body.
                if ecx.tcx.intrinsic(instance.def_id()).unwrap().must_be_overridden {
                    throw_unsup_format!(
                        "intrinsic `{intrinsic_name}` is not supported at compile-time"
                    );
                }
                return interp_ok(Some(ty::Instance {
                    def: ty::InstanceKind::Item(instance.def_id()),
                    args: instance.args,
                }));
            }
        }

        // Intrinsic is done, jump to next block.
        ecx.return_to_block(target)?;
        interp_ok(None)
    }

    fn assert_panic(
        ecx: &mut InterpCx<'tcx, Self>,
        msg: &AssertMessage<'tcx>,
        _unwind: mir::UnwindAction,
    ) -> InterpResult<'tcx> {
        use rustc_middle::mir::AssertKind::*;
        // Convert `AssertKind<Operand>` to `AssertKind<Scalar>`.
        let eval_to_int =
            |op| ecx.read_immediate(&ecx.eval_operand(op, None)?).map(|x| x.to_const_int());
        let err = match msg {
            BoundsCheck { len, index } => {
                let len = eval_to_int(len)?;
                let index = eval_to_int(index)?;
                BoundsCheck { len, index }
            }
            Overflow(op, l, r) => Overflow(*op, eval_to_int(l)?, eval_to_int(r)?),
            OverflowNeg(op) => OverflowNeg(eval_to_int(op)?),
            DivisionByZero(op) => DivisionByZero(eval_to_int(op)?),
            RemainderByZero(op) => RemainderByZero(eval_to_int(op)?),
            ResumedAfterReturn(coroutine_kind) => ResumedAfterReturn(*coroutine_kind),
            ResumedAfterPanic(coroutine_kind) => ResumedAfterPanic(*coroutine_kind),
            ResumedAfterDrop(coroutine_kind) => ResumedAfterDrop(*coroutine_kind),
            MisalignedPointerDereference { required, found } => MisalignedPointerDereference {
                required: eval_to_int(required)?,
                found: eval_to_int(found)?,
            },
            NullPointerDereference => NullPointerDereference,
            InvalidEnumConstruction(source) => InvalidEnumConstruction(eval_to_int(source)?),
        };
        Err(ConstEvalErrKind::AssertFailure(err)).into()
    }

    fn binary_ptr_op(
        _ecx: &InterpCx<'tcx, Self>,
        _bin_op: mir::BinOp,
        _left: &ImmTy<'tcx>,
        _right: &ImmTy<'tcx>,
    ) -> InterpResult<'tcx, ImmTy<'tcx>> {
        throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time");
    }

    fn increment_const_eval_counter(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
        // The step limit has already been hit in a previous call to `increment_const_eval_counter`.

        if let Some(new_steps) = ecx.machine.num_evaluated_steps.checked_add(1) {
            let (limit, start) = if ecx.tcx.sess.opts.unstable_opts.tiny_const_eval_limit {
                (TINY_LINT_TERMINATOR_LIMIT, TINY_LINT_TERMINATOR_LIMIT)
            } else {
                (LINT_TERMINATOR_LIMIT, PROGRESS_INDICATOR_START)
            };

            ecx.machine.num_evaluated_steps = new_steps;
            // By default, we have a *deny* lint kicking in after some time
            // to ensure `loop {}` doesn't just go forever.
            // In case that lint got reduced, in particular for `--cap-lint` situations, we also
            // have a hard warning shown every now and then for really long executions.
            if new_steps == limit {
                // By default, we stop after a million steps, but the user can disable this lint
                // to be able to run until the heat death of the universe or power loss, whichever
                // comes first.
                let hir_id = ecx.machine.best_lint_scope(*ecx.tcx);
                let is_error = ecx
                    .tcx
                    .lint_level_at_node(
                        rustc_session::lint::builtin::LONG_RUNNING_CONST_EVAL,
                        hir_id,
                    )
                    .level
                    .is_error();
                let span = ecx.cur_span();
                ecx.tcx.emit_node_span_lint(
                    rustc_session::lint::builtin::LONG_RUNNING_CONST_EVAL,
                    hir_id,
                    span,
                    LongRunning { item_span: ecx.tcx.span },
                );
                // If this was a hard error, don't bother continuing evaluation.
                if is_error {
                    let guard = ecx
                        .tcx
                        .dcx()
                        .span_delayed_bug(span, "The deny lint should have already errored");
                    throw_inval!(AlreadyReported(ReportedErrorInfo::allowed_in_infallible(guard)));
                }
            } else if new_steps > start && new_steps.is_power_of_two() {
                // Only report after a certain number of terminators have been evaluated and the
                // current number of evaluated terminators is a power of 2. The latter gives us a cheap
                // way to implement exponential backoff.
                let span = ecx.cur_span();
                // We store a unique number in `force_duplicate` to evade `-Z deduplicate-diagnostics`.
                // `new_steps` is guaranteed to be unique because `ecx.machine.num_evaluated_steps` is
                // always increasing.
                ecx.tcx.dcx().emit_warn(LongRunningWarn {
                    span,
                    item_span: ecx.tcx.span,
                    force_duplicate: new_steps,
                });
            }
        }

        interp_ok(())
    }

    #[inline(always)]
    fn expose_provenance(
        _ecx: &InterpCx<'tcx, Self>,
        _provenance: Self::Provenance,
    ) -> InterpResult<'tcx> {
        // This is only reachable with -Zunleash-the-miri-inside-of-you.
        throw_unsup_format!("exposing pointers is not possible at compile-time")
    }

    #[inline(always)]
    fn init_frame(
        ecx: &mut InterpCx<'tcx, Self>,
        frame: Frame<'tcx>,
    ) -> InterpResult<'tcx, Frame<'tcx>> {
        // Enforce stack size limit. Add 1 because this is run before the new frame is pushed.
        if !ecx.recursion_limit.value_within_limit(ecx.stack().len() + 1) {
            throw_exhaust!(StackFrameLimitReached)
        } else {
            interp_ok(frame)
        }
    }

    #[inline(always)]
    fn stack<'a>(
        ecx: &'a InterpCx<'tcx, Self>,
    ) -> &'a [Frame<'tcx, Self::Provenance, Self::FrameExtra>] {
        &ecx.machine.stack
    }

    #[inline(always)]
    fn stack_mut<'a>(
        ecx: &'a mut InterpCx<'tcx, Self>,
    ) -> &'a mut Vec<Frame<'tcx, Self::Provenance, Self::FrameExtra>> {
        &mut ecx.machine.stack
    }

    fn before_access_global(
        _tcx: TyCtxtAt<'tcx>,
        machine: &Self,
        alloc_id: AllocId,
        alloc: ConstAllocation<'tcx>,
        _static_def_id: Option<DefId>,
        is_write: bool,
    ) -> InterpResult<'tcx> {
        let alloc = alloc.inner();
        if is_write {
            // Write access. These are never allowed, but we give a targeted error message.
            match alloc.mutability {
                Mutability::Not => throw_ub!(WriteToReadOnly(alloc_id)),
                Mutability::Mut => Err(ConstEvalErrKind::ModifiedGlobal).into(),
            }
        } else {
            // Read access. These are usually allowed, with some exceptions.
            if machine.can_access_mut_global == CanAccessMutGlobal::Yes {
                // Machine configuration allows us read from anything (e.g., `static` initializer).
                interp_ok(())
            } else if alloc.mutability == Mutability::Mut {
                // Machine configuration does not allow us to read statics (e.g., `const`
                // initializer).
                Err(ConstEvalErrKind::ConstAccessesMutGlobal).into()
            } else {
                // Immutable global, this read is fine.
                assert_eq!(alloc.mutability, Mutability::Not);
                interp_ok(())
            }
        }
    }

    fn retag_ptr_value(
        ecx: &mut InterpCx<'tcx, Self>,
        _kind: mir::RetagKind,
        val: &ImmTy<'tcx, CtfeProvenance>,
    ) -> InterpResult<'tcx, ImmTy<'tcx, CtfeProvenance>> {
        // If it's a frozen shared reference that's not already immutable, potentially make it immutable.
        // (Do nothing on `None` provenance, that cannot store immutability anyway.)
        if let ty::Ref(_, ty, mutbl) = val.layout.ty.kind()
            && *mutbl == Mutability::Not
            && val
                .to_scalar_and_meta()
                .0
                .to_pointer(ecx)?
                .provenance
                .is_some_and(|p| !p.immutable())
        {
            // That next check is expensive, that's why we have all the guards above.
            let is_immutable = ty.is_freeze(*ecx.tcx, ecx.typing_env());
            let place = ecx.ref_to_mplace(val)?;
            let new_place = if is_immutable {
                place.map_provenance(CtfeProvenance::as_immutable)
            } else {
                // Even if it is not immutable, remember that it is a shared reference.
                // This allows it to become part of the final value of the constant.
                // (See <https://github.com/rust-lang/rust/pull/128543> for why we allow this
                // even when there is interior mutability.)
                place.map_provenance(CtfeProvenance::as_shared_ref)
            };
            interp_ok(ImmTy::from_immediate(new_place.to_ref(ecx), val.layout))
        } else {
            interp_ok(val.clone())
        }
    }

    fn before_memory_write(
        _tcx: TyCtxtAt<'tcx>,
        _machine: &mut Self,
        _alloc_extra: &mut Self::AllocExtra,
        _ptr: Pointer<Option<Self::Provenance>>,
        (_alloc_id, immutable): (AllocId, bool),
        range: AllocRange,
    ) -> InterpResult<'tcx> {
        if range.size == Size::ZERO {
            // Nothing to check.
            return interp_ok(());
        }
        // Reject writes through immutable pointers.
        if immutable {
            return Err(ConstEvalErrKind::WriteThroughImmutablePointer).into();
        }
        // Everything else is fine.
        interp_ok(())
    }

    fn before_alloc_access(
        tcx: TyCtxtAt<'tcx>,
        machine: &Self,
        alloc_id: AllocId,
    ) -> InterpResult<'tcx> {
        if machine.stack.is_empty() {
            // Get out of the way for the final copy.
            return interp_ok(());
        }
        // Check if this is the currently evaluated static.
        if Some(alloc_id) == machine.static_root_ids.map(|(id, _)| id) {
            return Err(ConstEvalErrKind::RecursiveStatic).into();
        }
        // If this is another static, make sure we fire off the query to detect cycles.
        // But only do that when checks for static recursion are enabled.
        if machine.static_root_ids.is_some() {
            if let Some(GlobalAlloc::Static(def_id)) = tcx.try_get_global_alloc(alloc_id) {
                if tcx.is_foreign_item(def_id) {
                    throw_unsup!(ExternStatic(def_id));
                }
                tcx.eval_static_initializer(def_id)?;
            }
        }
        interp_ok(())
    }

    fn cached_union_data_range<'e>(
        ecx: &'e mut InterpCx<'tcx, Self>,
        ty: Ty<'tcx>,
        compute_range: impl FnOnce() -> RangeSet,
    ) -> Cow<'e, RangeSet> {
        if ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks {
            Cow::Borrowed(ecx.machine.union_data_ranges.entry(ty).or_insert_with(compute_range))
        } else {
            // Don't bother caching, we're only doing one validation at the end anyway.
            Cow::Owned(compute_range())
        }
    }

    fn get_default_alloc_params(&self) -> <Self::Bytes as mir::interpret::AllocBytes>::AllocParams {
    }
}

// Please do not add any code below the above `Machine` trait impl. I (oli-obk) plan more cleanups
// so we can end up having a file with just that impl, but for now, let's keep the impl discoverable
// at the bottom of this file.
