use std::cell::RefCell;
use std::collections::hash_map::Entry;

use either::{Left, Right};
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::DefId;
use rustc_hir::limit::Limit;
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{
    self, FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf,
    LayoutOfHelpers, TyAndLayout,
};
use rustc_middle::ty::{
    self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingEnv, Variance,
};
use rustc_middle::{mir, span_bug};
use rustc_span::Span;
use rustc_target::callconv::FnAbi;
use tracing::{debug, trace};

use super::{
    Frame, FrameInfo, GlobalId, InterpErrorInfo, InterpErrorKind, InterpResult, MPlaceTy, Machine,
    MemPlaceMeta, Memory, OpTy, Place, PlaceTy, PointerArithmetic, Projectable, Provenance,
    err_inval, interp_ok, throw_inval, throw_ub, throw_ub_format,
};
use crate::{enter_trace_span, util};

pub struct InterpCx<'tcx, M: Machine<'tcx>> {
    /// Stores the `Machine` instance.
    ///
    /// Note: the stack is provided by the machine.
    pub machine: M,

    /// The results of the type checker, from rustc.
    /// The span in this is the "root" of the evaluation, i.e., the const
    /// we are evaluating (if this is CTFE).
    pub tcx: TyCtxtAt<'tcx>,

    /// The current context in case we're evaluating in a
    /// polymorphic context. This always uses `ty::TypingMode::PostAnalysis`.
    pub(super) typing_env: ty::TypingEnv<'tcx>,

    /// The query cache is slow so we have our own cache in front of it.
    pub(super) layout_cache: RefCell<FxHashMap<Ty<'tcx>, rustc_abi::Layout<'tcx>>>,

    /// The virtual memory system.
    pub memory: Memory<'tcx, M>,

    /// The recursion limit (cached from `tcx.recursion_limit(())`)
    pub recursion_limit: Limit,
}

impl<'tcx, M: Machine<'tcx>> HasDataLayout for InterpCx<'tcx, M> {
    #[inline]
    fn data_layout(&self) -> &TargetDataLayout {
        &self.tcx.data_layout
    }
}

impl<'tcx, M> layout::HasTyCtxt<'tcx> for InterpCx<'tcx, M>
where
    M: Machine<'tcx>,
{
    #[inline]
    fn tcx(&self) -> TyCtxt<'tcx> {
        *self.tcx
    }
}

impl<'tcx, M> layout::HasTypingEnv<'tcx> for InterpCx<'tcx, M>
where
    M: Machine<'tcx>,
{
    fn typing_env(&self) -> ty::TypingEnv<'tcx> {
        self.typing_env
    }
}

impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> {
    type LayoutOfResult = Result<TyAndLayout<'tcx>, InterpErrorKind<'tcx>>;

    #[inline]
    fn layout_tcx_at_span(&self) -> Span {
        // Using the cheap root span for performance.
        self.tcx.span
    }

    #[inline]
    fn handle_layout_err(
        &self,
        mut err: LayoutError<'tcx>,
        _: Span,
        _: Ty<'tcx>,
    ) -> InterpErrorKind<'tcx> {
        // FIXME(#149283): This is really hacky and is only used to hide type
        // system bugs. We use it as a temporary fix for #149081.
        //
        // While it's expected that we sometimes get ambiguity errors when
        // entering another generic environment while the current environment
        // itself is still generic, we should never fail to entirely prove
        // something.
        match err {
            LayoutError::NormalizationFailure(ty, _) => {
                if ty.has_non_region_param() {
                    err = LayoutError::TooGeneric(ty);
                }
            }

            LayoutError::Unknown(_)
            | LayoutError::SizeOverflow(_)
            | LayoutError::InvalidSimd { .. }
            | LayoutError::TooGeneric(_)
            | LayoutError::ReferencesError(_) => {}
        }
        err_inval!(Layout(err))
    }
}

impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> {
    type FnAbiOfResult = Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, InterpErrorKind<'tcx>>;

    fn handle_fn_abi_err(
        &self,
        err: FnAbiError<'tcx>,
        _span: Span,
        _fn_abi_request: FnAbiRequest<'tcx>,
    ) -> InterpErrorKind<'tcx> {
        match err {
            FnAbiError::Layout(err) => err_inval!(Layout(err)),
        }
    }
}

impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
    /// This inherent method takes priority over the trait method with the same name in LayoutOf,
    /// and allows wrapping the actual [LayoutOf::layout_of] with a tracing span.
    /// See [LayoutOf::layout_of] for the original documentation.
    #[inline]
    pub fn layout_of(&self, ty: Ty<'tcx>) -> Result<TyAndLayout<'tcx>, InterpErrorKind<'tcx>> {
        match self.layout_cache.borrow_mut().entry(ty) {
            Entry::Occupied(occupied_entry) => {
                Ok(TyAndLayout { ty, layout: *occupied_entry.get() })
            }
            Entry::Vacant(vacant_entry) => {
                let _trace = enter_trace_span!(M, layouting::layout_of, ty = ?ty.kind());
                let layout = LayoutOf::layout_of(self, ty)?;
                vacant_entry.insert(layout.layout);
                Ok(layout)
            }
        }
    }

    /// This inherent method takes priority over the trait method with the same name in FnAbiOf,
    /// and allows wrapping the actual [FnAbiOf::fn_abi_of_fn_ptr] with a tracing span.
    /// See [FnAbiOf::fn_abi_of_fn_ptr] for the original documentation.
    #[inline(always)]
    pub fn fn_abi_of_fn_ptr(
        &self,
        sig: ty::PolyFnSig<'tcx>,
        extra_args: &'tcx ty::List<Ty<'tcx>>,
    ) -> <Self as FnAbiOfHelpers<'tcx>>::FnAbiOfResult {
        let _trace = enter_trace_span!(M, layouting::fn_abi_of_fn_ptr, ?sig, ?extra_args);
        FnAbiOf::fn_abi_of_fn_ptr(self, sig, extra_args)
    }

    /// This inherent method takes priority over the trait method with the same name in FnAbiOf,
    /// and allows wrapping the actual [FnAbiOf::fn_abi_of_instance_no_deduced_attrs] with a tracing span.
    /// See [FnAbiOf::fn_abi_of_instance_no_deduced_attrs] for the original documentation.
    #[inline(always)]
    pub fn fn_abi_of_instance_no_deduced_attrs(
        &self,
        instance: ty::Instance<'tcx>,
        extra_args: &'tcx ty::List<Ty<'tcx>>,
    ) -> <Self as FnAbiOfHelpers<'tcx>>::FnAbiOfResult {
        let _trace = enter_trace_span!(M, layouting::fn_abi_of_instance, ?instance, ?extra_args);
        FnAbiOf::fn_abi_of_instance_no_deduced_attrs(self, instance, extra_args)
    }
}

/// Test if it is valid for a MIR assignment to assign `src`-typed place to `dest`-typed value.
pub(super) fn mir_assign_valid_types<'tcx>(
    tcx: TyCtxt<'tcx>,
    typing_env: TypingEnv<'tcx>,
    src: TyAndLayout<'tcx>,
    dest: TyAndLayout<'tcx>,
) -> bool {
    // We *could* check `Invariant` here since all subtyping must be explicit post-borrowck.
    // However, this check is also used by the interpreter to figure out if a transmute can be
    // turned into a regular assignment (which has a more efficient codepath), so we want the check
    // to consider as many assignments as possible to be valid. Therefore we are happy to accept
    // one-way subtyping.
    if util::relate_types(tcx, typing_env, Variance::Covariant, src.ty, dest.ty) {
        // Make sure the layout is equal, too -- just to be safe. Miri really needs layout equality.
        // For performance reason we skip this check when the types are equal. Equal types *can*
        // have different layouts when enum downcast is involved (as enum variants carry the type of
        // the enum), but those should never occur in assignments.
        if cfg!(debug_assertions) || src.ty != dest.ty {
            assert_eq!(
                src.layout,
                dest.layout,
                "{src} is a subtype of {dest} but they have different layout",
                src = src.ty,
                dest = dest.ty,
            );
        }
        true
    } else {
        false
    }
}

/// Use the already known layout if given (but sanity check in debug mode),
/// or compute the layout.
#[cfg_attr(not(debug_assertions), inline(always))]
pub(super) fn from_known_layout<'tcx>(
    tcx: TyCtxtAt<'tcx>,
    typing_env: TypingEnv<'tcx>,
    known_layout: Option<TyAndLayout<'tcx>>,
    compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
    match known_layout {
        None => compute(),
        Some(known_layout) => {
            if cfg!(debug_assertions) {
                let check_layout = compute()?;
                if !mir_assign_valid_types(tcx.tcx, typing_env, check_layout, known_layout) {
                    span_bug!(
                        tcx.span,
                        "expected type differs from actual type.\nexpected: {}\nactual: {}",
                        known_layout.ty,
                        check_layout.ty,
                    );
                }
            }
            interp_ok(known_layout)
        }
    }
}

/// Turn the given error into a human-readable string. Expects the string to be printed, so if
/// `RUSTC_CTFE_BACKTRACE` is set this will show a backtrace of the rustc internals that
/// triggered the error.
///
/// This is NOT the preferred way to render an error; use `report` from `const_eval` instead.
/// However, this is useful when error messages appear in ICEs.
pub fn format_interp_error<'tcx>(e: InterpErrorInfo<'tcx>) -> String {
    let (e, backtrace) = e.into_parts();
    backtrace.print_backtrace();
    e.to_string()
}

impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
    pub fn new(
        tcx: TyCtxt<'tcx>,
        root_span: Span,
        typing_env: ty::TypingEnv<'tcx>,
        machine: M,
    ) -> Self {
        crate::assert_typing_mode(typing_env.typing_mode());

        InterpCx {
            machine,
            tcx: tcx.at(root_span),
            typing_env,
            layout_cache: RefCell::new(FxHashMap::default()),
            memory: Memory::new(),
            recursion_limit: tcx.recursion_limit(),
        }
    }

    /// Returns the span of the currently executed statement/terminator.
    /// This is the span typically used for error reporting.
    #[inline(always)]
    pub fn cur_span(&self) -> Span {
        // This deliberately does *not* honor `requires_caller_location` since it is used for much
        // more than just panics.
        self.stack().last().map_or(self.tcx.span, |f| f.current_span())
    }

    pub(crate) fn stack(&self) -> &[Frame<'tcx, M::Provenance, M::FrameExtra>] {
        M::stack(self)
    }

    #[inline(always)]
    pub(crate) fn stack_mut(&mut self) -> &mut Vec<Frame<'tcx, M::Provenance, M::FrameExtra>> {
        M::stack_mut(self)
    }

    #[inline(always)]
    pub fn frame_idx(&self) -> usize {
        let stack = self.stack();
        assert!(!stack.is_empty());
        stack.len() - 1
    }

    #[inline(always)]
    pub fn frame(&self) -> &Frame<'tcx, M::Provenance, M::FrameExtra> {
        self.stack().last().expect("no call frames exist")
    }

    #[inline(always)]
    pub fn frame_mut(&mut self) -> &mut Frame<'tcx, M::Provenance, M::FrameExtra> {
        self.stack_mut().last_mut().expect("no call frames exist")
    }

    #[inline(always)]
    pub fn body(&self) -> &'tcx mir::Body<'tcx> {
        self.frame().body
    }

    #[inline]
    pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
        ty.is_freeze(*self.tcx, self.typing_env)
    }

    pub fn load_mir(
        &self,
        instance: ty::InstanceKind<'tcx>,
        promoted: Option<mir::Promoted>,
    ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
        trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
        let body = if let Some(promoted) = promoted {
            let def = instance.def_id();
            &self.tcx.promoted_mir(def)[promoted]
        } else {
            M::load_mir(self, instance)
        };
        // do not continue if typeck errors occurred (can only occur in local crate)
        if let Some(err) = body.tainted_by_errors {
            throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(err)));
        }
        interp_ok(body)
    }

    /// Call this on things you got out of the MIR (so it is as generic as the current
    /// stack frame), to bring it into the proper environment for this interpreter.
    pub fn instantiate_from_current_frame_and_normalize_erasing_regions<
        T: TypeFoldable<TyCtxt<'tcx>>,
    >(
        &self,
        value: T,
    ) -> Result<T, ErrorHandled> {
        self.instantiate_from_frame_and_normalize_erasing_regions(self.frame(), value)
    }

    /// Call this on things you got out of the MIR (so it is as generic as the provided
    /// stack frame), to bring it into the proper environment for this interpreter.
    pub fn instantiate_from_frame_and_normalize_erasing_regions<T: TypeFoldable<TyCtxt<'tcx>>>(
        &self,
        frame: &Frame<'tcx, M::Provenance, M::FrameExtra>,
        value: T,
    ) -> Result<T, ErrorHandled> {
        let _trace = enter_trace_span!(
            M,
            "instantiate_from_frame_and_normalize_erasing_regions",
            %frame.instance
        );
        frame
            .instance
            .try_instantiate_mir_and_normalize_erasing_regions(
                *self.tcx,
                self.typing_env,
                ty::EarlyBinder::bind(self.tcx.tcx, value),
            )
            .map_err(|_| ErrorHandled::TooGeneric(self.cur_span()))
    }

    /// The `args` are assumed to already be in our interpreter "universe".
    pub(super) fn resolve(
        &self,
        def: DefId,
        args: GenericArgsRef<'tcx>,
    ) -> InterpResult<'tcx, ty::Instance<'tcx>> {
        let _trace = enter_trace_span!(M, resolve::try_resolve, def = ?def);
        trace!("resolve: {:?}, {:#?}", def, args);
        trace!("typing_env: {:#?}", self.typing_env);
        trace!("args: {:#?}", args);
        match ty::Instance::try_resolve(*self.tcx, self.typing_env, def, args) {
            Ok(Some(instance)) => interp_ok(instance),
            Ok(None) => throw_inval!(TooGeneric),

            // FIXME(eddyb) this could be a bit more specific than `AlreadyReported`.
            Err(error_guaranteed) => throw_inval!(AlreadyReported(
                ReportedErrorInfo::non_const_eval_error(error_guaranteed)
            )),
        }
    }

    /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
    /// frame which is not `#[track_caller]`. This matches the `caller_location` intrinsic,
    /// and is primarily intended for the panic machinery.
    pub(crate) fn find_closest_untracked_caller_location(&self) -> Span {
        for frame in self.stack().iter().rev() {
            debug!("find_closest_untracked_caller_location: checking frame {:?}", frame.instance);

            // Assert that the frame we look at is actually executing code currently
            // (`loc` is `Right` when we are unwinding and the frame does not require cleanup).
            let loc = frame.loc.left().unwrap();

            // This could be a non-`Call` terminator (such as `Drop`), or not a terminator at all
            // (such as `box`). Use the normal span by default.
            let mut source_info = *frame.body.source_info(loc);

            // If this is a `Call` terminator, use the `fn_span` instead.
            let block = &frame.body.basic_blocks[loc.block];
            if loc.statement_index == block.statements.len() {
                debug!(
                    "find_closest_untracked_caller_location: got terminator {:?} ({:?})",
                    block.terminator(),
                    block.terminator().kind,
                );
                if let mir::TerminatorKind::Call { fn_span, .. } = block.terminator().kind {
                    source_info.span = fn_span;
                }
            }

            let caller_location = if frame.instance.def.requires_caller_location(*self.tcx) {
                // We use `Err(())` as indication that we should continue up the call stack since
                // this is a `#[track_caller]` function.
                Some(Err(()))
            } else {
                None
            };
            if let Ok(span) =
                frame.body.caller_location_span(source_info, caller_location, *self.tcx, Ok)
            {
                return span;
            }
        }

        span_bug!(self.cur_span(), "no non-`#[track_caller]` frame found")
    }

    /// Returns the actual dynamic size and alignment of the place at the given type.
    /// Only the "meta" (metadata) part of the place matters.
    /// This can fail to provide an answer for extern types.
    pub(super) fn size_and_align_from_meta(
        &self,
        metadata: &MemPlaceMeta<M::Provenance>,
        layout: &TyAndLayout<'tcx>,
    ) -> InterpResult<'tcx, Option<(Size, Align)>> {
        if layout.is_sized() {
            return interp_ok(Some((layout.size, layout.align.abi)));
        }
        match layout.ty.kind() {
            ty::Adt(..) | ty::Tuple(..) => {
                // First get the size of all statically known fields.
                // Don't use type_of::sizing_type_of because that expects t to be sized,
                // and it also rounds up to alignment, which we want to avoid,
                // as the unsized field's alignment could be smaller.
                assert!(!layout.ty.is_simd());
                assert!(layout.fields.count() > 0);
                trace!("DST layout: {:?}", layout);

                let unsized_offset_unadjusted = layout.fields.offset(layout.fields.count() - 1);
                let sized_align = layout.align.abi;

                // Recurse to get the size of the dynamically sized field (must be
                // the last field). Can't have foreign types here, how would we
                // adjust alignment and size for them?
                let field = layout.field(self, layout.fields.count() - 1);
                let Some((unsized_size, mut unsized_align)) =
                    self.size_and_align_from_meta(metadata, &field)?
                else {
                    // A field with an extern type. We don't know the actual dynamic size
                    // or the alignment.
                    return interp_ok(None);
                };

                // # First compute the dynamic alignment

                // Packed type alignment needs to be capped.
                if let ty::Adt(def, _) = layout.ty.kind()
                    && let Some(packed) = def.repr().pack
                {
                    unsized_align = unsized_align.min(packed);
                }

                // Choose max of two known alignments (combined value must
                // be aligned according to more restrictive of the two).
                let full_align = sized_align.max(unsized_align);

                // # Then compute the dynamic size

                let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align);
                let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align);

                // Just for our sanitiy's sake, assert that this is equal to what codegen would compute.
                assert_eq!(
                    full_size,
                    (unsized_offset_unadjusted + unsized_size).align_to(full_align)
                );

                // Check if this brought us over the size limit.
                if full_size > self.max_size_of_val() {
                    throw_ub!(InvalidMeta(InvalidMetaKind::TooBig));
                }
                interp_ok(Some((full_size, full_align)))
            }
            ty::Dynamic(expected_trait, _) => {
                let vtable = metadata.unwrap_meta().to_pointer(self)?;
                // Read size and align from vtable (already checks size).
                interp_ok(Some(self.get_vtable_size_and_align(vtable, Some(expected_trait))?))
            }

            ty::Slice(_) | ty::Str => {
                let len = metadata.unwrap_meta().to_target_usize(self)?;
                let elem = layout.field(self, 0);

                // Make sure the slice is not too big.
                let size = elem.size.bytes().saturating_mul(len); // we rely on `max_size_of_val` being smaller than `u64::MAX`.
                let size = Size::from_bytes(size);
                if size > self.max_size_of_val() {
                    throw_ub!(InvalidMeta(InvalidMetaKind::SliceTooBig));
                }
                interp_ok(Some((size, elem.align.abi)))
            }

            ty::Foreign(_) => interp_ok(None),

            _ => span_bug!(self.cur_span(), "size_and_align_of::<{}> not supported", layout.ty),
        }
    }
    #[inline]
    pub fn size_and_align_of_val(
        &self,
        val: &impl Projectable<'tcx, M::Provenance>,
    ) -> InterpResult<'tcx, Option<(Size, Align)>> {
        self.size_and_align_from_meta(&val.meta(), &val.layout())
    }

    /// Jump to the given block.
    #[inline]
    pub fn go_to_block(&mut self, target: mir::BasicBlock) {
        self.frame_mut().loc = Left(mir::Location { block: target, statement_index: 0 });
    }

    /// *Return* to the given `target` basic block.
    /// Do *not* use for unwinding! Use `unwind_to_block` instead.
    ///
    /// If `target` is `None`, that indicates the function cannot return, so we raise UB.
    pub fn return_to_block(&mut self, target: Option<mir::BasicBlock>) -> InterpResult<'tcx> {
        if let Some(target) = target {
            self.go_to_block(target);
            interp_ok(())
        } else {
            throw_ub!(Unreachable)
        }
    }

    /// *Unwind* to the given `target` basic block.
    /// Do *not* use for returning! Use `return_to_block` instead.
    ///
    /// If `target` is `UnwindAction::Continue`, that indicates the function does not need cleanup
    /// during unwinding, and we will just keep propagating that upwards.
    ///
    /// If `target` is `UnwindAction::Unreachable`, that indicates the function does not allow
    /// unwinding, and doing so is UB.
    #[cold] // usually we have normal returns, not unwinding
    pub fn unwind_to_block(&mut self, target: mir::UnwindAction) -> InterpResult<'tcx> {
        self.frame_mut().loc = match target {
            mir::UnwindAction::Cleanup(block) => Left(mir::Location { block, statement_index: 0 }),
            mir::UnwindAction::Continue => Right(self.frame_mut().body.span),
            mir::UnwindAction::Unreachable => {
                throw_ub_format!("unwinding past a stack frame that does not allow unwinding");
            }
            mir::UnwindAction::Terminate(reason) => {
                self.frame_mut().loc = Right(self.frame_mut().body.span);
                M::unwind_terminate(self, reason)?;
                // This might have pushed a new stack frame, or it terminated execution.
                // Either way, `loc` will not be updated.
                return interp_ok(());
            }
        };
        interp_ok(())
    }

    /// Call a query that can return `ErrorHandled`. Should be used for statics and other globals.
    /// (`mir::Const`/`ty::Const` have `eval` methods that can be used directly instead.)
    pub fn ctfe_query<T>(
        &self,
        query: impl FnOnce(TyCtxtAt<'tcx>) -> Result<T, ErrorHandled>,
    ) -> Result<T, ErrorHandled> {
        // Use a precise span for better cycle errors.
        query(self.tcx.at(self.cur_span())).map_err(|err| {
            err.emit_note(*self.tcx);
            err
        })
    }

    pub fn eval_global(
        &self,
        instance: ty::Instance<'tcx>,
    ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
        let gid = GlobalId { instance, promoted: None };
        let val = if self.tcx.is_static(gid.instance.def_id()) {
            let alloc_id = self.tcx.reserve_and_set_static_alloc(gid.instance.def_id());

            let ty = instance.ty(self.tcx.tcx, self.typing_env);
            mir::ConstAlloc { alloc_id, ty }
        } else {
            self.ctfe_query(|tcx| tcx.eval_to_allocation_raw(self.typing_env.as_query_input(gid)))?
        };
        self.raw_const_to_mplace(val)
    }

    pub fn eval_mir_constant(
        &self,
        val: &mir::Const<'tcx>,
        span: Span,
        layout: Option<TyAndLayout<'tcx>>,
    ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
        let _trace = enter_trace_span!(M, const_eval::eval_mir_constant, ?val);
        let const_val = val.eval(*self.tcx, self.typing_env, span).map_err(|err| {
                if M::ALL_CONSTS_ARE_PRECHECKED {
                    match err {
                        ErrorHandled::TooGeneric(..) => {},
                        ErrorHandled::Reported(reported, span) => {
                            if reported.is_allowed_in_infallible() {
                                // These errors can just sometimes happen, even when the expression
                                // is nominally "infallible", e.g. when running out of memory
                                // or when some layout could not be computed.
                            } else {
                                // Looks like the const is not captured by `required_consts`, that's bad.
                                span_bug!(span, "interpret const eval failure of {val:?} which is not in required_consts");
                            }
                        }
                    }
                }
                err.emit_note(*self.tcx);
                err
            })?;
        self.const_val_to_op(const_val, val.ty(), layout)
    }

    #[must_use]
    pub fn dump_place(&self, place: &PlaceTy<'tcx, M::Provenance>) -> PlacePrinter<'_, 'tcx, M> {
        PlacePrinter { ecx: self, place: *place.place() }
    }

    #[must_use]
    pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> {
        Frame::generate_stacktrace_from_stack(self.stack(), *self.tcx)
    }

    pub fn adjust_nan<F1, F2>(&self, f: F2, inputs: &[F1]) -> F2
    where
        F1: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F2>,
        F2: rustc_apfloat::Float,
    {
        if f.is_nan() { M::generate_nan(self, inputs) } else { f }
    }
}

#[doc(hidden)]
/// Helper struct for the `dump_place` function.
pub struct PlacePrinter<'a, 'tcx, M: Machine<'tcx>> {
    ecx: &'a InterpCx<'tcx, M>,
    place: Place<M::Provenance>,
}

impl<'a, 'tcx, M: Machine<'tcx>> std::fmt::Debug for PlacePrinter<'a, 'tcx, M> {
    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self.place {
            Place::Local { local, offset, locals_addr } => {
                debug_assert_eq!(locals_addr, self.ecx.frame().locals_addr());
                let mut allocs = Vec::new();
                write!(fmt, "{local:?}")?;
                if let Some(offset) = offset {
                    write!(fmt, "+{:#x}", offset.bytes())?;
                }
                write!(fmt, ":")?;

                self.ecx.frame().locals[local].print(&mut allocs, fmt)?;

                write!(fmt, ": {:?}", self.ecx.dump_allocs(allocs.into_iter().flatten().collect()))
            }
            Place::Ptr(mplace) => match mplace.ptr.provenance.and_then(Provenance::get_alloc_id) {
                Some(alloc_id) => {
                    write!(fmt, "by ref {:?}: {:?}", mplace.ptr, self.ecx.dump_alloc(alloc_id))
                }
                ptr => write!(fmt, " integral by ref: {ptr:?}"),
            },
        }
    }
}
