use std::collections::hash_map::Entry;
use std::marker::PhantomData;
use std::ops::Range;

use rustc_abi::{BackendRepr, FieldIdx, FieldsShape, Size, VariantIdx};
use rustc_data_structures::fx::FxHashMap;
use rustc_index::IndexVec;
use rustc_index::bit_set::DenseBitSet;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::{Instance, Ty};
use rustc_middle::{bug, mir, ty};
use rustc_session::config::{DebugInfo, OptLevel};
use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, hygiene, sym};

use super::operand::{OperandRef, OperandValue};
use super::place::{PlaceRef, PlaceValue};
use super::{FunctionCx, LocalRef, PerLocalVarDebugInfoIndexVec};
use crate::traits::*;

pub struct FunctionDebugContext<'tcx, S, L> {
    /// Maps from source code to the corresponding debug info scope.
    pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>,

    /// Maps from an inlined function to its debug info declaration.
    pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
}

#[derive(Copy, Clone)]
pub enum VariableKind {
    ArgumentVariable(usize /*index*/),
    LocalVariable,
}

/// Like `mir::VarDebugInfo`, but within a `mir::Local`.
#[derive(Clone)]
pub struct PerLocalVarDebugInfo<'tcx, D> {
    pub name: Symbol,
    pub source_info: mir::SourceInfo,

    /// `DIVariable` returned by `create_dbg_var`.
    pub dbg_var: Option<D>,

    /// Byte range in the `dbg_var` covered by this fragment,
    /// if this is a fragment of a composite `VarDebugInfo`.
    pub fragment: Option<Range<Size>>,

    /// `.place.projection` from `mir::VarDebugInfo`.
    pub projection: &'tcx ty::List<mir::PlaceElem<'tcx>>,
}

/// Information needed to emit a constant.
pub struct ConstDebugInfo<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
    pub name: String,
    pub source_info: mir::SourceInfo,
    pub operand: OperandRef<'tcx, Bx::Value>,
    pub dbg_var: Bx::DIVariable,
    pub dbg_loc: Bx::DILocation,
    pub fragment: Option<Range<Size>>,
    pub _phantom: PhantomData<&'a ()>,
}

#[derive(Clone, Copy, Debug)]
pub struct DebugScope<S, L> {
    pub dbg_scope: S,

    /// Call site location, if this scope was inlined from another function.
    pub inlined_at: Option<L>,

    // Start and end offsets of the file to which this DIScope belongs.
    // These are used to quickly determine whether some span refers to the same file.
    pub file_start_pos: BytePos,
    pub file_end_pos: BytePos,
}

impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
    /// DILocations inherit source file name from the parent DIScope. Due to macro expansions
    /// it may so happen that the current span belongs to a different file than the DIScope
    /// corresponding to span's containing source scope. If so, we need to create a DIScope
    /// "extension" into that file.
    pub fn adjust_dbg_scope_for_span<
        'a,
        Bx: BuilderMethods<'a, 'tcx, DIScope = S, DILocation = L>,
    >(
        &self,
        bx: &mut Bx,
        span: Span,
    ) -> S {
        let pos = span.lo();
        if pos < self.file_start_pos || pos >= self.file_end_pos {
            let sm = bx.sess().source_map();
            bx.extend_scope_to_file(self.dbg_scope, &sm.lookup_char_pos(pos).file)
        } else {
            self.dbg_scope
        }
    }
}

trait DebugInfoOffsetLocation<'tcx, Bx> {
    fn deref(&self, bx: &mut Bx) -> Self;
    fn layout(&self) -> TyAndLayout<'tcx>;
    fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self;
    fn project_constant_index(&self, bx: &mut Bx, offset: u64) -> Self;
    fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self;
}

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
    for PlaceRef<'tcx, Bx::Value>
{
    fn deref(&self, bx: &mut Bx) -> Self {
        bx.load_operand(*self).deref(bx.cx())
    }

    fn layout(&self) -> TyAndLayout<'tcx> {
        self.layout
    }

    fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self {
        PlaceRef::project_field(*self, bx, field.index())
    }

    fn project_constant_index(&self, bx: &mut Bx, offset: u64) -> Self {
        let lloffset = bx.cx().const_usize(offset);
        self.project_index(bx, lloffset)
    }

    fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
        self.project_downcast(bx, variant)
    }
}

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
    for TyAndLayout<'tcx>
{
    fn deref(&self, bx: &mut Bx) -> Self {
        bx.cx().layout_of(
            self.ty.builtin_deref(true).unwrap_or_else(|| bug!("cannot deref `{}`", self.ty)),
        )
    }

    fn layout(&self) -> TyAndLayout<'tcx> {
        *self
    }

    fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self {
        self.field(bx.cx(), field.index())
    }

    fn project_constant_index(&self, bx: &mut Bx, index: u64) -> Self {
        self.field(bx.cx(), index as usize)
    }

    fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
        self.for_variant(bx.cx(), variant)
    }
}

struct DebugInfoOffset<T> {
    /// Offset from the `base` used to calculate the debuginfo offset.
    direct_offset: Size,
    /// Each offset in this vector indicates one level of indirection from the base or previous
    /// indirect offset plus a dereference.
    indirect_offsets: Vec<Size>,
    /// The final location debuginfo should point to.
    result: T,
}

fn calculate_debuginfo_offset<
    'a,
    'tcx,
    Bx: BuilderMethods<'a, 'tcx>,
    L: DebugInfoOffsetLocation<'tcx, Bx>,
>(
    bx: &mut Bx,
    projection: &[mir::PlaceElem<'tcx>],
    base: L,
) -> DebugInfoOffset<L> {
    let mut direct_offset = Size::ZERO;
    // FIXME(eddyb) use smallvec here.
    let mut indirect_offsets = vec![];
    let mut place = base;

    for elem in projection {
        match *elem {
            mir::ProjectionElem::Deref => {
                indirect_offsets.push(Size::ZERO);
                place = place.deref(bx);
            }
            mir::ProjectionElem::Field(field, _) => {
                let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
                *offset += place.layout().fields.offset(field.index());
                place = place.project_field(bx, field);
            }
            mir::ProjectionElem::Downcast(_, variant) => {
                place = place.downcast(bx, variant);
            }
            mir::ProjectionElem::ConstantIndex {
                offset: index,
                min_length: _,
                from_end: false,
            } => {
                let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
                let FieldsShape::Array { stride, count: _ } = place.layout().fields else {
                    bug!("ConstantIndex on non-array type {:?}", place.layout())
                };
                *offset += stride * index;
                place = place.project_constant_index(bx, index);
            }
            _ => {
                // Sanity check for `can_use_in_debuginfo`.
                assert!(!elem.can_use_in_debuginfo());
                bug!("unsupported var debuginfo projection `{:?}`", projection)
            }
        }
    }

    DebugInfoOffset { direct_offset, indirect_offsets, result: place }
}

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
    pub fn set_debug_loc(&self, bx: &mut Bx, source_info: mir::SourceInfo) {
        bx.set_span(source_info.span);
        if let Some(dbg_loc) = self.dbg_loc(bx, source_info) {
            bx.set_dbg_loc(dbg_loc);
        }
    }

    fn dbg_loc(&self, bx: &mut Bx, source_info: mir::SourceInfo) -> Option<Bx::DILocation> {
        let (dbg_scope, inlined_at, span) = self.adjusted_span_and_dbg_scope(bx, source_info)?;
        Some(bx.dbg_loc(dbg_scope, inlined_at, span))
    }

    fn adjusted_span_and_dbg_scope(
        &self,
        bx: &mut Bx,
        source_info: mir::SourceInfo,
    ) -> Option<(Bx::DIScope, Option<Bx::DILocation>, Span)> {
        let scope = &self.debug_context.as_ref()?.scopes[source_info.scope];
        let span = hygiene::walk_chain_collapsed(source_info.span, self.mir.span);
        Some((scope.adjust_dbg_scope_for_span(bx, span), scope.inlined_at, span))
    }

    fn spill_operand_to_stack(
        operand: OperandRef<'tcx, Bx::Value>,
        name: Option<String>,
        bx: &mut Bx,
    ) -> PlaceRef<'tcx, Bx::Value> {
        // "Spill" the value onto the stack, for debuginfo,
        // without forcing non-debuginfo uses of the local
        // to also load from the stack every single time.
        // FIXME(#68817) use `llvm.dbg.value` instead,
        // at least for the cases which LLVM handles correctly.
        let spill_slot = PlaceRef::alloca(bx, operand.layout);
        if let Some(name) = name {
            bx.set_var_name(spill_slot.val.llval, &(name + ".dbg.spill"));
        }
        operand.val.store(bx, spill_slot);
        spill_slot
    }

    // Indicates that local is set to a new value. The `layout` and `projection` are used to
    // calculate the offset.
    pub(crate) fn debug_new_val_to_local(
        &self,
        bx: &mut Bx,
        local: mir::Local,
        base: PlaceRef<'tcx, Bx::Value>,
        projection: &[mir::PlaceElem<'tcx>],
    ) {
        let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full;
        if !full_debug_info {
            return;
        }

        let vars = match &self.per_local_var_debug_info {
            Some(per_local) => &per_local[local],
            None => return,
        };

        let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
            calculate_debuginfo_offset(bx, projection, base.layout);
        for var in vars.iter() {
            let Some(dbg_var) = var.dbg_var else {
                continue;
            };
            let Some(dbg_loc) = self.dbg_loc(bx, var.source_info) else {
                continue;
            };
            bx.dbg_var_value(
                dbg_var,
                dbg_loc,
                base.val.llval,
                direct_offset,
                &indirect_offsets,
                &var.fragment,
            );
        }
    }

    pub(crate) fn debug_poison_to_local(&self, bx: &mut Bx, local: mir::Local) {
        let ty = self.monomorphize(self.mir.local_decls[local].ty);
        let layout = bx.cx().layout_of(ty);
        let to_backend_ty = bx.cx().immediate_backend_type(layout);
        let place_ref = PlaceRef::new_sized(bx.cx().const_poison(to_backend_ty), layout);
        self.debug_new_val_to_local(bx, local, place_ref, &[]);
    }

    /// Apply debuginfo and/or name, after creating the `alloca` for a local,
    /// or initializing the local with an operand (whichever applies).
    pub(crate) fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) {
        let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full;

        let vars = match &self.per_local_var_debug_info {
            Some(per_local) => &per_local[local],
            None => return,
        };
        let whole_local_var = vars.iter().find(|var| var.projection.is_empty()).cloned();
        let has_proj = || vars.iter().any(|var| !var.projection.is_empty());

        let fallback_var = if self.mir.local_kind(local) == mir::LocalKind::Arg {
            let arg_index = local.index() - 1;

            // Add debuginfo even to unnamed arguments.
            // FIXME(eddyb) is this really needed?
            if arg_index == 0 && has_proj() {
                // Hide closure environments from debuginfo.
                // FIXME(eddyb) shouldn't `ArgumentVariable` indices
                // be offset to account for the hidden environment?
                None
            } else if whole_local_var.is_some() {
                // No need to make up anything, there is a `mir::VarDebugInfo`
                // covering the whole local.
                // FIXME(eddyb) take `whole_local_var.source_info.scope` into
                // account, just in case it doesn't use `ArgumentVariable`
                // (after #67586 gets fixed).
                None
            } else {
                let name = sym::empty;
                let decl = &self.mir.local_decls[local];
                let dbg_var = if full_debug_info {
                    self.adjusted_span_and_dbg_scope(bx, decl.source_info).map(
                        |(dbg_scope, _, span)| {
                            // FIXME(eddyb) is this `+ 1` needed at all?
                            let kind = VariableKind::ArgumentVariable(arg_index + 1);

                            let arg_ty = self.monomorphize(decl.ty);

                            bx.create_dbg_var(name, arg_ty, dbg_scope, kind, span)
                        },
                    )
                } else {
                    None
                };

                Some(PerLocalVarDebugInfo {
                    name,
                    source_info: decl.source_info,
                    dbg_var,
                    fragment: None,
                    projection: ty::List::empty(),
                })
            }
        } else {
            None
        };

        let local_ref = &self.locals[local];

        let name = if bx.sess().fewer_names() {
            None
        } else {
            Some(match whole_local_var.or_else(|| fallback_var.clone()) {
                Some(var) if var.name != sym::empty => var.name.to_string(),
                _ => format!("{local:?}"),
            })
        };

        if let Some(name) = &name {
            match local_ref {
                LocalRef::Place(place) | LocalRef::UnsizedPlace(place) => {
                    bx.set_var_name(place.val.llval, name);
                }
                LocalRef::Operand(operand) => match operand.val {
                    OperandValue::Ref(PlaceValue { llval: x, .. }) | OperandValue::Immediate(x) => {
                        bx.set_var_name(x, name);
                    }
                    OperandValue::Pair(a, b) => {
                        // FIXME(eddyb) these are scalar components,
                        // maybe extract the high-level fields?
                        bx.set_var_name(a, &(name.clone() + ".0"));
                        bx.set_var_name(b, &(name.clone() + ".1"));
                    }
                    OperandValue::ZeroSized => {
                        // These never have a value to talk about
                    }
                },
                LocalRef::PendingOperand => {}
            }
        }

        if !full_debug_info || vars.is_empty() && fallback_var.is_none() {
            return;
        }

        let base = match local_ref {
            LocalRef::PendingOperand => return,

            LocalRef::Operand(operand) => {
                // Don't spill operands onto the stack in naked functions.
                // See: https://github.com/rust-lang/rust/issues/42779
                let attrs = bx.tcx().codegen_instance_attrs(self.instance.def);
                if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
                    return;
                }

                // Don't spill `<vscale x N x i1>` for `N != 16`:
                //
                // SVE predicates are only one bit for each byte in an SVE vector (which makes
                // sense, the predicate only needs to keep track of whether a lane is
                // enabled/disabled). i.e. a `<vscale x 16 x i8>` vector has a `<vscale x 16 x i1>`
                // predicate type. `<vscale x 16 x i1>` corresponds to two bytes of storage,
                // multiplied by the `vscale`, with one bit for each of the sixteen lanes.
                //
                // For a vector with fewer elements, such as `svint32_t`/`<vscale x 4 x i32>`,
                // while only a `<vscale x 4 x i1>` predicate type would be strictly necessary,
                // relevant intrinsics still take a `svbool_t`/`<vscale x 16 x i1>` - this is
                // because a `<vscale x 4 x i1>` is only half of a byte (for `vscale=1`), and with
                // memory being byte-addressable, it's unclear how to store that.
                //
                // Due to this, LLVM ultimately decided not to support stores of `<vscale x N x i1>`
                // for `N != 16`. As for `vscale=1` and `N` fewer than sixteen, partial bytes would
                // need to be stored (except for `N=8`, but that also isn't supported). `N` can
                // never be greater than sixteen as that ends up larger than the 128-bit increment
                // size.
                //
                // Internally, with an intrinsic operating on a `svint32_t`/`<vscale x 4 x i32>`
                // (for example), the intrinsic takes the `svbool_t`/`<vscale x 16 x i1>` predicate
                // and casts it to a `svbool4_t`/`<vscale x 4 x i1>`. Therefore, it's important that
                // the `<vscale x 4 x i1>` never spills because that'll cause errors during
                // instruction selection. Spilling to the stack to create debuginfo for these
                // intermediate values must be avoided and doing so won't affect the
                // debugging experience anyway.
                if operand.layout.ty.is_scalable_vector()
                    && bx.sess().target.arch == rustc_target::spec::Arch::AArch64
                {
                    let (count, element_ty, _) =
                        operand.layout.ty.scalable_vector_parts(bx.tcx()).unwrap();
                    // i.e. `<vscale x N x i1>` when `N != 16`
                    if element_ty.is_bool() && count != 16 {
                        return;
                    }
                }

                Self::spill_operand_to_stack(*operand, name, bx)
            }

            LocalRef::Place(place) => *place,

            // FIXME(eddyb) add debuginfo for unsized places too.
            LocalRef::UnsizedPlace(_) => return,
        };

        // FIXME(arm-maintainers): LLVM uses GlobalISel with -O0 that doesn't support scalable
        // vectors. It normally falls back to SDAG which does support scalable vectors, but there's
        // a bug that means that isn't happening for debuginfo - so temporarily don't emit debuginfo
        // for scalable vector locals when there are no optimisations until that bug is
        // fixed. See <https://github.com/llvm/llvm-project/issues/204585>.
        if base.layout.peel_transparent_wrappers(bx).ty.is_scalable_vector()
            && bx.tcx().backend_optimization_level(()) == OptLevel::No
            && bx.sess().opts.debuginfo != DebugInfo::None
        {
            return;
        }

        let vars = vars.iter().cloned().chain(fallback_var);

        for var in vars {
            self.debug_introduce_local_as_var(bx, local, base, var);
        }
    }

    fn debug_introduce_local_as_var(
        &self,
        bx: &mut Bx,
        local: mir::Local,
        base: PlaceRef<'tcx, Bx::Value>,
        var: PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
    ) {
        let Some(dbg_var) = var.dbg_var else { return };
        let Some(dbg_loc) = self.dbg_loc(bx, var.source_info) else { return };

        let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
            calculate_debuginfo_offset(bx, var.projection, base.layout);

        // When targeting MSVC, create extra allocas for arguments instead of pointing multiple
        // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
        // not DWARF and LLVM doesn't support translating the resulting
        // [DW_OP_deref, DW_OP_plus_uconst, offset, DW_OP_deref] debug info to CodeView.
        // Creating extra allocas on the stack makes the resulting debug info simple enough
        // that LLVM can generate correct CodeView records and thus the values appear in the
        // debugger. (#83709)
        let should_create_individual_allocas = bx.cx().sess().target.is_like_msvc
            && self.mir.local_kind(local) == mir::LocalKind::Arg
            // LLVM can handle simple things but anything more complex than just a direct
            // offset or one indirect offset of 0 is too complex for it to generate CV records
            // correctly.
            && (direct_offset != Size::ZERO || !matches!(&indirect_offsets[..], [Size::ZERO] | []));

        if should_create_individual_allocas {
            let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
                calculate_debuginfo_offset(bx, var.projection, base);

            // Create a variable which will be a pointer to the actual value
            let ptr_ty = Ty::new_mut_ptr(bx.tcx(), place.layout.ty);
            let ptr_layout = bx.layout_of(ptr_ty);
            let alloca = PlaceRef::alloca(bx, ptr_layout);
            bx.set_var_name(alloca.val.llval, &(var.name.to_string() + ".dbg.spill"));

            // Write the pointer to the variable
            bx.store_to_place(place.val.llval, alloca.val);

            // Point the debug info to `*alloca` for the current variable
            bx.dbg_var_addr(
                dbg_var,
                dbg_loc,
                alloca.val.llval,
                Size::ZERO,
                &[Size::ZERO],
                &var.fragment,
            );
        } else {
            bx.dbg_var_addr(
                dbg_var,
                dbg_loc,
                base.val.llval,
                direct_offset,
                &indirect_offsets,
                &var.fragment,
            );
        }
    }

    pub(crate) fn debug_introduce_locals(
        &self,
        bx: &mut Bx,
        consts: Vec<ConstDebugInfo<'a, 'tcx, Bx>>,
    ) {
        if bx.sess().opts.debuginfo == DebugInfo::Full || !bx.sess().fewer_names() {
            for local in self.locals.indices() {
                self.debug_introduce_local(bx, local);
            }

            for ConstDebugInfo { name, source_info, operand, dbg_var, dbg_loc, fragment, .. } in
                consts.into_iter()
            {
                self.set_debug_loc(bx, source_info);
                let base = FunctionCx::spill_operand_to_stack(operand, Some(name), bx);
                bx.clear_dbg_loc();

                bx.dbg_var_addr(dbg_var, dbg_loc, base.val.llval, Size::ZERO, &[], &fragment);
            }
        }
    }

    /// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`.
    pub(crate) fn compute_per_local_var_debug_info(
        &self,
        bx: &mut Bx,
    ) -> Option<(
        PerLocalVarDebugInfoIndexVec<'tcx, Bx::DIVariable>,
        Vec<ConstDebugInfo<'a, 'tcx, Bx>>,
    )> {
        let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full;

        let target_is_msvc = self.cx.sess().target.is_like_msvc;

        if !full_debug_info && self.cx.sess().fewer_names() {
            return None;
        }

        let mut per_local = IndexVec::from_elem(vec![], &self.mir.local_decls);
        let mut constants = vec![];
        let mut params_seen: FxHashMap<_, Bx::DIVariable> = Default::default();
        for var in &self.mir.var_debug_info {
            let dbg_scope_and_span = if full_debug_info {
                self.adjusted_span_and_dbg_scope(bx, var.source_info)
            } else {
                None
            };

            let var_ty = if let Some(ref fragment) = var.composite {
                self.monomorphize(fragment.ty)
            } else {
                match var.value {
                    mir::VarDebugInfoContents::Place(place) => {
                        self.monomorphized_place_ty(place.as_ref())
                    }
                    mir::VarDebugInfoContents::Const(c) => self.monomorphize(c.ty()),
                }
            };

            let dbg_var = dbg_scope_and_span.map(|(dbg_scope, _, span)| {
                let var_kind = if let Some(arg_index) = var.argument_index
                    && var.composite.is_none()
                    && let mir::VarDebugInfoContents::Place(place) = var.value
                    && place.projection.is_empty()
                {
                    let arg_index = arg_index as usize;
                    if target_is_msvc {
                        // ScalarPair parameters are spilled to the stack so they need to
                        // be marked as a `LocalVariable` for MSVC debuggers to visualize
                        // their data correctly. (See #81894 & #88625)
                        let var_ty_layout = self.cx.layout_of(var_ty);
                        if let BackendRepr::ScalarPair(_, _) = var_ty_layout.backend_repr {
                            VariableKind::LocalVariable
                        } else {
                            VariableKind::ArgumentVariable(arg_index)
                        }
                    } else {
                        // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
                        // offset in closures to account for the hidden environment?
                        VariableKind::ArgumentVariable(arg_index)
                    }
                } else {
                    VariableKind::LocalVariable
                };

                if let VariableKind::ArgumentVariable(arg_index) = var_kind {
                    match params_seen.entry((dbg_scope, arg_index)) {
                        Entry::Occupied(o) => o.get().clone(),
                        Entry::Vacant(v) => v
                            .insert(bx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span))
                            .clone(),
                    }
                } else {
                    bx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span)
                }
            });

            let fragment = if let Some(ref fragment) = var.composite {
                let var_layout = self.cx.layout_of(var_ty);

                let DebugInfoOffset { direct_offset, indirect_offsets, result: fragment_layout } =
                    calculate_debuginfo_offset(bx, &fragment.projection, var_layout);
                assert!(indirect_offsets.is_empty());

                if fragment_layout.size == Size::ZERO {
                    // Fragment is a ZST, so does not represent anything. Avoid generating anything
                    // as this may conflict with a fragment that covers the entire variable.
                    continue;
                } else if fragment_layout.size == var_layout.size {
                    // Fragment covers entire variable, so as far as
                    // DWARF is concerned, it's not really a fragment.
                    None
                } else {
                    Some(direct_offset..direct_offset + fragment_layout.size)
                }
            } else {
                None
            };

            match var.value {
                mir::VarDebugInfoContents::Place(place) => {
                    per_local[place.local].push(PerLocalVarDebugInfo {
                        name: var.name,
                        source_info: var.source_info,
                        dbg_var,
                        fragment,
                        projection: place.projection,
                    });
                }
                mir::VarDebugInfoContents::Const(c) => {
                    if let Some(dbg_var) = dbg_var {
                        let Some(dbg_loc) = self.dbg_loc(bx, var.source_info) else { continue };

                        let operand = self.eval_mir_constant_to_operand(bx, &c);
                        constants.push(ConstDebugInfo {
                            name: var.name.to_string(),
                            source_info: var.source_info,
                            operand,
                            dbg_var,
                            dbg_loc,
                            fragment,
                            _phantom: PhantomData,
                        });
                    }
                }
            }
        }
        Some((per_local, constants))
    }

    /// Creates the function-specific debug context.
    ///
    /// Returns the FunctionDebugContext for the function which holds state needed
    /// for debug info creation, if it is enabled.
    pub(super) fn fill_function_debug_context(&mut self, bx: &mut Bx) {
        if self.cx.sess().opts.debuginfo == DebugInfo::None {
            return;
        }

        // Initialize fn debug context (including scopes).
        self.debug_context = Some(FunctionDebugContext {
            scopes: IndexVec::with_capacity(self.mir.source_scopes.len()),
            inlined_function_scopes: Default::default(),
        });

        // Find all scopes with variables defined in them.
        let variables = if self.cx.sess().opts.debuginfo == DebugInfo::Full {
            let mut vars = DenseBitSet::new_empty(self.mir.source_scopes.len());
            // FIXME(eddyb) take into account that arguments always have debuginfo,
            // irrespective of their name (assuming full debuginfo is enabled).
            // NOTE(eddyb) actually, on second thought, those are always in the
            // function scope, which always exists.
            for var_debug_info in &self.mir.var_debug_info {
                vars.insert(var_debug_info.source_info.scope);
            }
            Some(vars)
        } else {
            // Nothing to emit, of course.
            None
        };

        // Instantiate all scopes.
        let mut discriminators = FxHashMap::default();
        for scope in self.mir.source_scopes.indices() {
            let scope_data = self.make_mir_scope(bx, &variables, &mut discriminators, scope);
            let _s = self.debug_context.as_mut().unwrap().scopes.push(scope_data);
            debug_assert_eq!(_s, scope);
        }
    }

    fn make_mir_scope(
        &mut self,
        bx: &mut Bx,
        variables: &Option<DenseBitSet<mir::SourceScope>>,
        discriminators: &mut FxHashMap<BytePos, u32>,
        scope: mir::SourceScope,
    ) -> DebugScope<Bx::DIScope, Bx::DILocation> {
        let scope_data = &self.mir.source_scopes[scope];
        let parent_scope = if let Some(parent) = scope_data.parent_scope {
            debug_assert!(parent.as_u32() < scope.as_u32());
            self.debug_context.as_ref().unwrap().scopes[parent]
        } else {
            // The root is the function itself.
            let file = self.cx.sess().source_map().lookup_source_file(self.mir.span.lo());
            let dbg_scope = bx.dbg_scope_fn(self.instance, self.fn_abi, Some(self.llfn));
            return DebugScope {
                dbg_scope,
                inlined_at: None,
                file_start_pos: file.start_pos,
                file_end_pos: file.end_position(),
            };
        };

        if let Some(vars) = variables
            && !vars.contains(scope)
            && scope_data.inlined.is_none()
        {
            // Do not create a DIScope if there are no variables defined in this
            // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
            return parent_scope;
        }

        let dbg_scope = match scope_data.inlined {
            Some((callee, _)) => {
                let callee = self.monomorphize(callee);
                *self
                    .debug_context
                    .as_mut()
                    .unwrap()
                    .inlined_function_scopes
                    .entry(callee)
                    .or_insert_with(|| {
                        let callee_fn_abi = self.cx.fn_abi_of_instance(callee, ty::List::empty());
                        bx.dbg_scope_fn(callee, callee_fn_abi, None)
                    })
            }
            None => bx.dbg_create_lexical_block(scope_data.span.lo(), parent_scope.dbg_scope),
        };

        let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
            let callsite_span = hygiene::walk_chain_collapsed(callsite_span, self.mir.span);
            let callsite_scope = parent_scope.adjust_dbg_scope_for_span(bx, callsite_span);
            let loc = bx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span);

            // NB: In order to produce proper debug info for variables (particularly
            // arguments) in multiply-inlined functions, LLVM expects to see a single
            // DILocalVariable with multiple different DILocations in the IR. While
            // the source information for each DILocation would be identical, their
            // inlinedAt attributes will be unique to the particular callsite.
            //
            // We generate DILocations here based on the callsite's location in the
            // source code. A single location in the source code usually can't
            // produce multiple distinct calls so this mostly works, until
            // macros get involved. A macro can generate multiple calls
            // at the same span, which breaks the assumption that we're going to
            // produce a unique DILocation for every scope we process here. We
            // have to explicitly add discriminators if we see inlines into the
            // same source code location.
            //
            // Note further that we can't key this hashtable on the span itself,
            // because these spans could have distinct SyntaxContexts. We have
            // to key on exactly what we're giving to LLVM.
            match discriminators.entry(callsite_span.lo()) {
                Entry::Occupied(mut o) => {
                    *o.get_mut() += 1;
                    // NB: We have to emit *something* here or we'll fail LLVM IR verification
                    // in at least some circumstances (see issue #135322) so if the required
                    // discriminant cannot be encoded fall back to the dummy location.
                    bx.dbg_location_clone_with_discriminator(loc, *o.get()).unwrap_or_else(|| {
                        bx.dbg_loc(callsite_scope, parent_scope.inlined_at, DUMMY_SP)
                    })
                }
                Entry::Vacant(v) => {
                    v.insert(0);
                    loc
                }
            }
        });

        let file = self.cx.sess().source_map().lookup_source_file(scope_data.span.lo());
        DebugScope {
            dbg_scope,
            inlined_at: inlined_at.or(parent_scope.inlined_at),
            file_start_pos: file.start_pos,
            file_end_pos: file.end_position(),
        }
    }
}
