//! Manages the low-level pushing and popping of stack frames and the (de)allocation of local variables.
//! For handling of argument passing and return values, see the `call` module.
use std::cell::Cell;
use std::{fmt, mem};

use either::{Either, Left, Right};
use rustc_hir as hir;
use rustc_hir::definitions::DefPathData;
use rustc_index::IndexVec;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_mir_dataflow::impls::always_storage_live_locals;
use rustc_span::Span;
use tracing::field::Empty;
use tracing::{info_span, instrument, trace};

use super::{
    AllocId, CtfeProvenance, Immediate, InterpCx, InterpResult, Machine, MemPlace, MemPlaceMeta,
    MemoryKind, Operand, PlaceTy, Pointer, Provenance, ReturnAction, Scalar, from_known_layout,
    interp_ok, throw_ub, throw_unsup,
};
use crate::{enter_trace_span, errors};

// The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread
// boundary and dropped in the other thread, it would exit the span in the other thread.
struct SpanGuard(tracing::Span, std::marker::PhantomData<*const u8>);

impl SpanGuard {
    /// By default a `SpanGuard` does nothing.
    fn new() -> Self {
        Self(tracing::Span::none(), std::marker::PhantomData)
    }

    /// If a span is entered, we exit the previous span (if any, normally none) and enter the
    /// new span. This is mainly so we don't have to use `Option` for the `tracing_span` field of
    /// `Frame` by creating a dummy span to being with and then entering it once the frame has
    /// been pushed.
    fn enter(&mut self, span: tracing::Span) {
        // This executes the destructor on the previous instance of `SpanGuard`, ensuring that
        // we never enter or exit more spans than vice versa. Unless you `mem::leak`, then we
        // can't protect the tracing stack, but that'll just lead to weird logging, no actual
        // problems.
        *self = Self(span, std::marker::PhantomData);
        self.0.with_subscriber(|(id, dispatch)| {
            dispatch.enter(id);
        });
    }
}

impl Drop for SpanGuard {
    fn drop(&mut self) {
        self.0.with_subscriber(|(id, dispatch)| {
            dispatch.exit(id);
        });
    }
}

/// A stack frame.
pub struct Frame<'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> {
    ////////////////////////////////////////////////////////////////////////////////
    // Function and callsite information
    ////////////////////////////////////////////////////////////////////////////////
    /// The MIR for the function called on this frame.
    pub(super) body: &'tcx mir::Body<'tcx>,

    /// The def_id and args of the current function.
    pub(super) instance: ty::Instance<'tcx>,

    /// Extra data for the machine.
    pub extra: Extra,

    ////////////////////////////////////////////////////////////////////////////////
    // Return place and locals
    ////////////////////////////////////////////////////////////////////////////////
    /// Where to continue when returning from this function.
    return_cont: ReturnContinuation,

    /// The location where the result of the current stack frame should be written to,
    /// and its layout in the caller. This place is to be interpreted relative to the
    /// *caller's* stack frame. We use a `PlaceTy` instead of an `MPlaceTy` since this
    /// avoids having to move *all* return places into Miri's memory.
    pub return_place: PlaceTy<'tcx, Prov>,

    /// The list of locals for this stack frame, stored in order as
    /// `[return_ptr, arguments..., variables..., temporaries...]`.
    /// The locals are stored as `Option<Value>`s.
    /// `None` represents a local that is currently dead, while a live local
    /// can either directly contain `Scalar` or refer to some part of an `Allocation`.
    ///
    /// Do *not* access this directly; always go through the machine hook!
    pub locals: IndexVec<mir::Local, LocalState<'tcx, Prov>>,

    /// The span of the `tracing` crate is stored here.
    /// When the guard is dropped, the span is exited. This gives us
    /// a full stack trace on all tracing statements.
    tracing_span: SpanGuard,

    ////////////////////////////////////////////////////////////////////////////////
    // Current position within the function
    ////////////////////////////////////////////////////////////////////////////////
    /// If this is `Right`, we are not currently executing any particular statement in
    /// this frame (can happen e.g. during frame initialization, and during unwinding on
    /// frames without cleanup code).
    ///
    /// Needs to be public because ConstProp does unspeakable things to it.
    pub(super) loc: Either<mir::Location, Span>,
}

/// Where and how to continue when returning/unwinding from the current function.
#[derive(Clone, Copy, Eq, PartialEq, Debug)] // Miri debug-prints these
pub enum ReturnContinuation {
    /// Jump to the next block in the caller, or cause UB if None (that's a function
    /// that may never return).
    /// `ret` stores the block we jump to on a normal return, while `unwind`
    /// stores the block used for cleanup during unwinding.
    Goto { ret: Option<mir::BasicBlock>, unwind: mir::UnwindAction },
    /// The root frame of the stack: nowhere else to jump to, so we stop.
    /// `cleanup` says whether locals are deallocated. Static computation
    /// wants them leaked to intern what they need (and just throw away
    /// the entire `ecx` when it is done).
    Stop { cleanup: bool },
}

/// Return type of [`InterpCx::pop_stack_frame_raw`].
pub struct StackPopInfo<'tcx, Prov: Provenance> {
    /// Additional information about the action to be performed when returning from the popped
    /// stack frame.
    pub return_action: ReturnAction,

    /// [`return_cont`](Frame::return_cont) of the popped stack frame.
    pub return_cont: ReturnContinuation,

    /// [`return_place`](Frame::return_place) of the popped stack frame.
    pub return_place: PlaceTy<'tcx, Prov>,
}

/// State of a local variable including a memoized layout
#[derive(Clone)]
pub struct LocalState<'tcx, Prov: Provenance = CtfeProvenance> {
    value: LocalValue<Prov>,
    /// Don't modify if `Some`, this is only used to prevent computing the layout twice.
    /// Avoids computing the layout of locals that are never actually initialized.
    layout: Cell<Option<TyAndLayout<'tcx>>>,
}

impl<Prov: Provenance> std::fmt::Debug for LocalState<'_, Prov> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("LocalState")
            .field("value", &self.value)
            .field("ty", &self.layout.get().map(|l| l.ty))
            .finish()
    }
}

/// Current value of a local variable
///
/// This does not store the type of the local; the type is given by `body.local_decls` and can never
/// change, so by not storing here we avoid having to maintain that as an invariant.
#[derive(Copy, Clone, Debug)] // Miri debug-prints these
pub(super) enum LocalValue<Prov: Provenance = CtfeProvenance> {
    /// This local is not currently alive, and cannot be used at all.
    Dead,
    /// A normal, live local.
    /// Mostly for convenience, we re-use the `Operand` type here.
    /// This is an optimization over just always having a pointer here;
    /// we can thus avoid doing an allocation when the local just stores
    /// immediate values *and* never has its address taken.
    Live(Operand<Prov>),
}

impl<'tcx, Prov: Provenance> LocalState<'tcx, Prov> {
    pub fn make_live_uninit(&mut self) {
        self.value = LocalValue::Live(Operand::Immediate(Immediate::Uninit));
    }

    /// This is a hack because Miri needs a way to visit all the provenance in a `LocalState`
    /// without having a layout or `TyCtxt` available, and we want to keep the `Operand` type
    /// private.
    pub fn as_mplace_or_imm(
        &self,
    ) -> Option<Either<(Pointer<Option<Prov>>, MemPlaceMeta<Prov>), Immediate<Prov>>> {
        match self.value {
            LocalValue::Dead => None,
            LocalValue::Live(Operand::Indirect(mplace)) => Some(Left((mplace.ptr, mplace.meta))),
            LocalValue::Live(Operand::Immediate(imm)) => Some(Right(imm)),
        }
    }

    /// Read the local's value or error if the local is not yet live or not live anymore.
    #[inline(always)]
    pub(super) fn access(&self) -> InterpResult<'tcx, &Operand<Prov>> {
        match &self.value {
            LocalValue::Dead => throw_ub!(DeadLocal), // could even be "invalid program"?
            LocalValue::Live(val) => interp_ok(val),
        }
    }

    /// Overwrite the local. If the local can be overwritten in place, return a reference
    /// to do so; otherwise return the `MemPlace` to consult instead.
    #[inline(always)]
    pub(super) fn access_mut(&mut self) -> InterpResult<'tcx, &mut Operand<Prov>> {
        match &mut self.value {
            LocalValue::Dead => throw_ub!(DeadLocal), // could even be "invalid program"?
            LocalValue::Live(val) => interp_ok(val),
        }
    }
}

/// What we store about a frame in an interpreter backtrace.
#[derive(Clone, Debug)]
pub struct FrameInfo<'tcx> {
    pub instance: ty::Instance<'tcx>,
    pub span: Span,
}

// FIXME: only used by miri, should be removed once translatable.
impl<'tcx> fmt::Display for FrameInfo<'tcx> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        ty::tls::with(|tcx| {
            if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::Closure {
                write!(f, "inside closure")
            } else {
                // Note: this triggers a `must_produce_diag` state, which means that if we ever
                // get here we must emit a diagnostic. We should never display a `FrameInfo` unless
                // we actually want to emit a warning or error to the user.
                write!(f, "inside `{}`", self.instance)
            }
        })
    }
}

impl<'tcx> FrameInfo<'tcx> {
    pub fn as_note(&self, tcx: TyCtxt<'tcx>) -> errors::FrameNote {
        let span = self.span;
        if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::Closure {
            errors::FrameNote {
                where_: "closure",
                span,
                instance: String::new(),
                times: 0,
                has_label: false,
            }
        } else {
            let instance = format!("{}", self.instance);
            // Note: this triggers a `must_produce_diag` state, which means that if we ever get
            // here we must emit a diagnostic. We should never display a `FrameInfo` unless we
            // actually want to emit a warning or error to the user.
            errors::FrameNote { where_: "instance", span, instance, times: 0, has_label: false }
        }
    }
}

impl<'tcx, Prov: Provenance> Frame<'tcx, Prov> {
    pub fn with_extra<Extra>(self, extra: Extra) -> Frame<'tcx, Prov, Extra> {
        Frame {
            body: self.body,
            instance: self.instance,
            return_cont: self.return_cont,
            return_place: self.return_place,
            locals: self.locals,
            loc: self.loc,
            extra,
            tracing_span: self.tracing_span,
        }
    }
}

impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> {
    /// Get the current location within the Frame.
    ///
    /// If this is `Right`, we are not currently executing any particular statement in
    /// this frame (can happen e.g. during frame initialization, and during unwinding on
    /// frames without cleanup code).
    ///
    /// Used by [priroda](https://github.com/oli-obk/priroda).
    pub fn current_loc(&self) -> Either<mir::Location, Span> {
        self.loc
    }

    pub fn body(&self) -> &'tcx mir::Body<'tcx> {
        self.body
    }

    pub fn instance(&self) -> ty::Instance<'tcx> {
        self.instance
    }

    /// Return the `SourceInfo` of the current instruction.
    pub fn current_source_info(&self) -> Option<&mir::SourceInfo> {
        self.loc.left().map(|loc| self.body.source_info(loc))
    }

    pub fn current_span(&self) -> Span {
        match self.loc {
            Left(loc) => self.body.source_info(loc).span,
            Right(span) => span,
        }
    }

    pub fn lint_root(&self, tcx: TyCtxt<'tcx>) -> Option<hir::HirId> {
        // We first try to get a HirId via the current source scope,
        // and fall back to `body.source`.
        self.current_source_info()
            .and_then(|source_info| match &self.body.source_scopes[source_info.scope].local_data {
                mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
                mir::ClearCrossCrate::Clear => None,
            })
            .or_else(|| {
                let def_id = self.body.source.def_id().as_local();
                def_id.map(|def_id| tcx.local_def_id_to_hir_id(def_id))
            })
    }

    /// Returns the address of the buffer where the locals are stored. This is used by `Place` as a
    /// sanity check to detect bugs where we mix up which stack frame a place refers to.
    #[inline(always)]
    pub(super) fn locals_addr(&self) -> usize {
        self.locals.raw.as_ptr().addr()
    }

    #[must_use]
    pub fn generate_stacktrace_from_stack(stack: &[Self]) -> Vec<FrameInfo<'tcx>> {
        let mut frames = Vec::new();
        // This deliberately does *not* honor `requires_caller_location` since it is used for much
        // more than just panics.
        for frame in stack.iter().rev() {
            let span = match frame.loc {
                Left(loc) => {
                    // If the stacktrace passes through MIR-inlined source scopes, add them.
                    let mir::SourceInfo { mut span, scope } = *frame.body.source_info(loc);
                    let mut scope_data = &frame.body.source_scopes[scope];
                    while let Some((instance, call_span)) = scope_data.inlined {
                        frames.push(FrameInfo { span, instance });
                        span = call_span;
                        scope_data = &frame.body.source_scopes[scope_data.parent_scope.unwrap()];
                    }
                    span
                }
                Right(span) => span,
            };
            frames.push(FrameInfo { span, instance: frame.instance });
        }
        trace!("generate stacktrace: {:#?}", frames);
        frames
    }
}

impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
    /// Very low-level helper that pushes a stack frame without initializing
    /// the arguments or local variables.
    ///
    /// The high-level version of this is `init_stack_frame`.
    #[instrument(skip(self, body, return_place, return_cont), level = "debug")]
    pub(crate) fn push_stack_frame_raw(
        &mut self,
        instance: ty::Instance<'tcx>,
        body: &'tcx mir::Body<'tcx>,
        return_place: &PlaceTy<'tcx, M::Provenance>,
        return_cont: ReturnContinuation,
    ) -> InterpResult<'tcx> {
        trace!("body: {:#?}", body);

        // We can push a `Root` frame if and only if the stack is empty.
        debug_assert_eq!(
            self.stack().is_empty(),
            matches!(return_cont, ReturnContinuation::Stop { .. })
        );

        // First push a stack frame so we have access to `instantiate_from_current_frame` and other
        // `self.frame()`-based functions.
        let dead_local = LocalState { value: LocalValue::Dead, layout: Cell::new(None) };
        let locals = IndexVec::from_elem(dead_local, &body.local_decls);
        let pre_frame = Frame {
            body,
            loc: Right(body.span), // Span used for errors caused during preamble.
            return_cont,
            return_place: return_place.clone(),
            locals,
            instance,
            tracing_span: SpanGuard::new(),
            extra: (),
        };
        let frame = M::init_frame(self, pre_frame)?;
        self.stack_mut().push(frame);

        // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check).
        for &const_ in body.required_consts() {
            // We can't use `eval_mir_constant` here as that assumes that all required consts have
            // already been checked, so we need a separate tracing call.
            let _trace = enter_trace_span!(M, const_eval::required_consts, ?const_.const_);
            let c =
                self.instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?;
            c.eval(*self.tcx, self.typing_env, const_.span).map_err(|err| {
                err.emit_note(*self.tcx);
                err
            })?;
        }

        // Finish things up.
        M::after_stack_push(self)?;
        self.frame_mut().loc = Left(mir::Location::START);
        // `tracing_separate_thread` is used to instruct the tracing_chrome [tracing::Layer] in Miri
        // to put the "frame" span on a separate trace thread/line than other spans, to make the
        // visualization in <https://ui.perfetto.dev> easier to interpret. It is set to a value of
        // [tracing::field::Empty] so that other tracing layers (e.g. the logger) will ignore it.
        let span = info_span!("frame", tracing_separate_thread = Empty, frame = %instance);
        self.frame_mut().tracing_span.enter(span);

        interp_ok(())
    }

    /// Low-level helper that pops a stack frame from the stack and returns some information about
    /// it.
    ///
    /// This also deallocates locals, if necessary.
    /// `copy_ret_val` gets called after the frame has been taken from the stack but before the locals have been deallocated.
    ///
    /// [`M::before_stack_pop`] and [`M::after_stack_pop`] are called by this function
    /// automatically.
    ///
    /// The high-level version of this is `return_from_current_stack_frame`.
    ///
    /// [`M::before_stack_pop`]: Machine::before_stack_pop
    /// [`M::after_stack_pop`]: Machine::after_stack_pop
    pub(super) fn pop_stack_frame_raw(
        &mut self,
        unwinding: bool,
        copy_ret_val: impl FnOnce(&mut Self, &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx>,
    ) -> InterpResult<'tcx, StackPopInfo<'tcx, M::Provenance>> {
        M::before_stack_pop(self)?;
        let frame =
            self.stack_mut().pop().expect("tried to pop a stack frame, but there were none");

        // Copy return value (unless we are unwinding).
        if !unwinding {
            copy_ret_val(self, &frame.return_place)?;
        }

        let return_cont = frame.return_cont;
        let return_place = frame.return_place.clone();

        // Cleanup: deallocate locals.
        // Usually we want to clean up (deallocate locals), but in a few rare cases we don't.
        // We do this while the frame is still on the stack, so errors point to the callee.
        let cleanup = match return_cont {
            ReturnContinuation::Goto { .. } => true,
            ReturnContinuation::Stop { cleanup, .. } => cleanup,
        };

        let return_action = if cleanup {
            // We need to take the locals out, since we need to mutate while iterating.
            for local in &frame.locals {
                self.deallocate_local(local.value)?;
            }

            // Call the machine hook, which determines the next steps.
            let return_action = M::after_stack_pop(self, frame, unwinding)?;
            assert_ne!(return_action, ReturnAction::NoCleanup);
            return_action
        } else {
            // We also skip the machine hook when there's no cleanup. This not a real "pop" anyway.
            ReturnAction::NoCleanup
        };

        interp_ok(StackPopInfo { return_action, return_cont, return_place })
    }

    /// In the current stack frame, mark all locals as live that are not arguments and don't have
    /// `Storage*` annotations (this includes the return place).
    pub(crate) fn storage_live_for_always_live_locals(&mut self) -> InterpResult<'tcx> {
        self.storage_live(mir::RETURN_PLACE)?;

        let body = self.body();
        let always_live = always_storage_live_locals(body);
        for local in body.vars_and_temps_iter() {
            if always_live.contains(local) {
                self.storage_live(local)?;
            }
        }
        interp_ok(())
    }

    pub fn storage_live_dyn(
        &mut self,
        local: mir::Local,
        meta: MemPlaceMeta<M::Provenance>,
    ) -> InterpResult<'tcx> {
        trace!("{:?} is now live", local);

        // We avoid `ty.is_trivially_sized` since that does something expensive for ADTs.
        fn is_very_trivially_sized(ty: Ty<'_>) -> bool {
            match ty.kind() {
                ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
                | ty::Uint(_)
                | ty::Int(_)
                | ty::Bool
                | ty::Float(_)
                | ty::FnDef(..)
                | ty::FnPtr(..)
                | ty::RawPtr(..)
                | ty::Char
                | ty::Ref(..)
                | ty::Coroutine(..)
                | ty::CoroutineWitness(..)
                | ty::Array(..)
                | ty::Closure(..)
                | ty::CoroutineClosure(..)
                | ty::Never
                | ty::Error(_) => true,

                ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false,

                ty::Tuple(tys) => tys.last().is_none_or(|ty| is_very_trivially_sized(*ty)),

                ty::Pat(ty, ..) => is_very_trivially_sized(*ty),

                // We don't want to do any queries, so there is not much we can do with ADTs.
                ty::Adt(..) => false,

                ty::UnsafeBinder(ty) => is_very_trivially_sized(ty.skip_binder()),

                ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false,

                ty::Infer(ty::TyVar(_)) => false,

                ty::Bound(..)
                | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
                    bug!("`is_very_trivially_sized` applied to unexpected type: {}", ty)
                }
            }
        }

        // This is a hot function, we avoid computing the layout when possible.
        // `unsized_` will be `None` for sized types and `Some(layout)` for unsized types.
        let unsized_ = if is_very_trivially_sized(self.body().local_decls[local].ty) {
            None
        } else {
            // We need the layout.
            let layout = self.layout_of_local(self.frame(), local, None)?;
            if layout.is_sized() { None } else { Some(layout) }
        };

        let local_val = LocalValue::Live(if let Some(layout) = unsized_ {
            if !meta.has_meta() {
                throw_unsup!(UnsizedLocal);
            }
            // Need to allocate some memory, since `Immediate::Uninit` cannot be unsized.
            let dest_place = self.allocate_dyn(layout, MemoryKind::Stack, meta)?;
            Operand::Indirect(*dest_place.mplace())
        } else {
            // Just make this an efficient immediate.
            assert!(!meta.has_meta()); // we're dropping the metadata
            // Make sure the machine knows this "write" is happening. (This is important so that
            // races involving local variable allocation can be detected by Miri.)
            M::after_local_write(self, local, /*storage_live*/ true)?;
            // Note that not calling `layout_of` here does have one real consequence:
            // if the type is too big, we'll only notice this when the local is actually initialized,
            // which is a bit too late -- we should ideally notice this already here, when the memory
            // is conceptually allocated. But given how rare that error is and that this is a hot function,
            // we accept this downside for now.
            Operand::Immediate(Immediate::Uninit)
        });

        // If the local is already live, deallocate its old memory.
        let old = mem::replace(&mut self.frame_mut().locals[local].value, local_val);
        self.deallocate_local(old)?;
        interp_ok(())
    }

    /// Mark a storage as live, killing the previous content.
    #[inline(always)]
    pub fn storage_live(&mut self, local: mir::Local) -> InterpResult<'tcx> {
        self.storage_live_dyn(local, MemPlaceMeta::None)
    }

    pub fn storage_dead(&mut self, local: mir::Local) -> InterpResult<'tcx> {
        assert!(local != mir::RETURN_PLACE, "Cannot make return place dead");
        trace!("{:?} is now dead", local);

        // If the local is already dead, this is a NOP.
        let old = mem::replace(&mut self.frame_mut().locals[local].value, LocalValue::Dead);
        self.deallocate_local(old)?;
        interp_ok(())
    }

    fn deallocate_local(&mut self, local: LocalValue<M::Provenance>) -> InterpResult<'tcx> {
        if let LocalValue::Live(Operand::Indirect(MemPlace { ptr, .. })) = local {
            // All locals have a backing allocation, even if the allocation is empty
            // due to the local having ZST type. Hence we can `unwrap`.
            trace!(
                "deallocating local {:?}: {:?}",
                local,
                // Locals always have a `alloc_id` (they are never the result of a int2ptr).
                self.dump_alloc(ptr.provenance.unwrap().get_alloc_id().unwrap())
            );
            self.deallocate_ptr(ptr, None, MemoryKind::Stack)?;
        };
        interp_ok(())
    }

    /// This is public because it is used by [Aquascope](https://github.com/cognitive-engineering-lab/aquascope/)
    /// to analyze all the locals in a stack frame.
    #[inline(always)]
    pub fn layout_of_local(
        &self,
        frame: &Frame<'tcx, M::Provenance, M::FrameExtra>,
        local: mir::Local,
        layout: Option<TyAndLayout<'tcx>>,
    ) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
        let state = &frame.locals[local];
        if let Some(layout) = state.layout.get() {
            return interp_ok(layout);
        }

        let layout = from_known_layout(self.tcx, self.typing_env, layout, || {
            let local_ty = frame.body.local_decls[local].ty;
            let local_ty =
                self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
            self.layout_of(local_ty).into()
        })?;

        // Layouts of locals are requested a lot, so we cache them.
        state.layout.set(Some(layout));
        interp_ok(layout)
    }
}

impl<'tcx, Prov: Provenance> LocalState<'tcx, Prov> {
    pub(super) fn print(
        &self,
        allocs: &mut Vec<Option<AllocId>>,
        fmt: &mut std::fmt::Formatter<'_>,
    ) -> std::fmt::Result {
        match self.value {
            LocalValue::Dead => write!(fmt, " is dead")?,
            LocalValue::Live(Operand::Immediate(Immediate::Uninit)) => {
                write!(fmt, " is uninitialized")?
            }
            LocalValue::Live(Operand::Indirect(mplace)) => {
                write!(
                    fmt,
                    " by {} ref {:?}:",
                    match mplace.meta {
                        MemPlaceMeta::Meta(meta) => format!(" meta({meta:?})"),
                        MemPlaceMeta::None => String::new(),
                    },
                    mplace.ptr,
                )?;
                allocs.extend(mplace.ptr.provenance.map(Provenance::get_alloc_id));
            }
            LocalValue::Live(Operand::Immediate(Immediate::Scalar(val))) => {
                write!(fmt, " {val:?}")?;
                if let Scalar::Ptr(ptr, _size) = val {
                    allocs.push(ptr.provenance.get_alloc_id());
                }
            }
            LocalValue::Live(Operand::Immediate(Immediate::ScalarPair(val1, val2))) => {
                write!(fmt, " ({val1:?}, {val2:?})")?;
                if let Scalar::Ptr(ptr, _size) = val1 {
                    allocs.push(ptr.provenance.get_alloc_id());
                }
                if let Scalar::Ptr(ptr, _size) = val2 {
                    allocs.push(ptr.provenance.get_alloc_id());
                }
            }
        }

        Ok(())
    }
}
