From 0b633c82f094d52a642b53cae64614ff097eebd8 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 26 Jan 2020 18:50:13 +0200 Subject: [PATCH 1/3] rustc_codegen_ssa: split declare_local into create_dbg_var and dbg_var_addr. --- src/librustc_codegen_llvm/builder.rs | 1 + src/librustc_codegen_llvm/common.rs | 1 + src/librustc_codegen_llvm/debuginfo/mod.rs | 84 ++++++++++++-------- src/librustc_codegen_ssa/mir/debuginfo.rs | 8 +- src/librustc_codegen_ssa/traits/backend.rs | 3 + src/librustc_codegen_ssa/traits/builder.rs | 2 +- src/librustc_codegen_ssa/traits/debuginfo.rs | 22 +++-- src/librustc_codegen_ssa/traits/mod.rs | 1 + 8 files changed, 79 insertions(+), 43 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index c59b81eb4cc32..342ac437d3c24 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -57,6 +57,7 @@ impl BackendTypes for Builder<'_, 'll, 'tcx> { type Funclet = as BackendTypes>::Funclet; type DIScope = as BackendTypes>::DIScope; + type DIVariable = as BackendTypes>::DIVariable; } impl ty::layout::HasDataLayout for Builder<'_, '_, '_> { diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 76f6eeb3f7907..1d6bfb321598c 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -91,6 +91,7 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> { type Funclet = Funclet<'ll>; type DIScope = &'ll llvm::debuginfo::DIScope; + type DIVariable = &'ll llvm::debuginfo::DIVariable; } impl CodegenCx<'ll, 'tcx> { diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 0462dcff42919..87af9b9c88da7 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -11,7 +11,7 @@ use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB}; use crate::llvm; use crate::llvm::debuginfo::{ - DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, + DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, DIVariable, }; use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::ty::subst::{GenericArgKind, SubstsRef}; @@ -143,33 +143,23 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) { }; } -impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { - fn declare_local( +impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> { + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). + fn dbg_var_addr( &mut self, dbg_context: &FunctionDebugContext<&'ll DIScope>, - variable_name: ast::Name, - variable_type: Ty<'tcx>, + dbg_var: &'ll DIVariable, scope_metadata: &'ll DIScope, variable_alloca: Self::Value, direct_offset: Size, indirect_offsets: &[Size], - variable_kind: VariableKind, span: Span, ) { assert!(!dbg_context.source_locations_enabled); let cx = self.cx(); - let file = span_start(cx, span).file; - let file_metadata = file_metadata(cx, &file.name, dbg_context.defining_crate); - let loc = span_start(cx, span); - let type_metadata = type_metadata(cx, variable_type, span); - - let (argument_index, dwarf_tag) = match variable_kind { - ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), - LocalVariable => (0, DW_TAG_auto_variable), - }; - let align = cx.align_of(variable_type); // Convert the direct and indirect offsets to address ops. let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() }; @@ -188,32 +178,19 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { } } - let name = SmallCStr::new(&variable_name.as_str()); - let metadata = unsafe { - llvm::LLVMRustDIBuilderCreateVariable( - DIB(cx), - dwarf_tag, - scope_metadata, - name.as_ptr(), - file_metadata, - loc.line as c_uint, - type_metadata, - cx.sess().opts.optimize != config::OptLevel::No, - DIFlags::FlagZero, - argument_index, - align.bytes() as u32, - ) - }; + // FIXME(eddyb) maybe this information could be extracted from `var`, + // to avoid having to pass it down in both places? source_loc::set_debug_location( self, InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()), ); unsafe { let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder); + // FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`. let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd( DIB(cx), variable_alloca, - metadata, + dbg_var, addr_ops.as_ptr(), addr_ops.len() as c_uint, debug_loc, @@ -558,4 +535,45 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn debuginfo_finalize(&self) { finalize(self) } + + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). + fn create_dbg_var( + &self, + dbg_context: &FunctionDebugContext<&'ll DIScope>, + variable_name: ast::Name, + variable_type: Ty<'tcx>, + scope_metadata: &'ll DIScope, + variable_kind: VariableKind, + span: Span, + ) -> &'ll DIVariable { + let file = span_start(self, span).file; + let file_metadata = file_metadata(self, &file.name, dbg_context.defining_crate); + + let loc = span_start(self, span); + let type_metadata = type_metadata(self, variable_type, span); + + let (argument_index, dwarf_tag) = match variable_kind { + ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), + LocalVariable => (0, DW_TAG_auto_variable), + }; + let align = self.align_of(variable_type); + + let name = SmallCStr::new(&variable_name.as_str()); + unsafe { + llvm::LLVMRustDIBuilderCreateVariable( + DIB(self), + dwarf_tag, + scope_metadata, + name.as_ptr(), + file_metadata, + loc.line as c_uint, + type_metadata, + self.sess().opts.optimize != config::OptLevel::No, + DIFlags::FlagZero, + argument_index, + align.bytes() as u32, + ) + } + } } diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index e0aec5d6dd512..1ee5fdba2a202 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -226,15 +226,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (scope, span) = self.debug_loc(var.source_info); if let Some(scope) = scope { - bx.declare_local( + let dbg_var = + bx.create_dbg_var(debug_context, var.name, layout.ty, scope, kind, span); + bx.dbg_var_addr( debug_context, - var.name, - layout.ty, + dbg_var, scope, base.llval, direct_offset, &indirect_offsets, - kind, span, ); } diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index bc3a75250bf70..7b22961cd46e2 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -21,7 +21,10 @@ pub trait BackendTypes { type Type: CodegenObject; type Funclet; + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.). type DIScope: Copy; + type DIVariable: Copy; } pub trait Backend<'tcx>: diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 6f331e14a0d37..b3c830eef8698 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -28,7 +28,7 @@ pub enum OverflowOp { pub trait BuilderMethods<'a, 'tcx>: HasCodegen<'tcx> - + DebugInfoBuilderMethods<'tcx> + + DebugInfoBuilderMethods + ArgAbiMethods<'tcx> + AbiBuilderMethods<'tcx> + IntrinsicCallMethods<'tcx> diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index d2784f5b860f7..22a4e96b9e4bf 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -30,20 +30,32 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes { defining_crate: CrateNum, ) -> Self::DIScope; fn debuginfo_finalize(&self); -} -pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes { - fn declare_local( - &mut self, + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). + fn create_dbg_var( + &self, dbg_context: &FunctionDebugContext, variable_name: Name, variable_type: Ty<'tcx>, scope_metadata: Self::DIScope, + variable_kind: VariableKind, + span: Span, + ) -> Self::DIVariable; +} + +pub trait DebugInfoBuilderMethods: BackendTypes { + // FIXME(eddyb) find a common convention for all of the debuginfo-related + // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). + fn dbg_var_addr( + &mut self, + dbg_context: &FunctionDebugContext, + dbg_var: Self::DIVariable, + scope_metadata: Self::DIScope, variable_alloca: Self::Value, direct_offset: Size, // NB: each offset implies a deref (i.e. they're steps in a pointer chain). indirect_offsets: &[Size], - variable_kind: VariableKind, span: Span, ); fn set_source_location( diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs index fff1b35507ce6..b8afadaadef38 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/src/librustc_codegen_ssa/traits/mod.rs @@ -93,5 +93,6 @@ pub trait HasCodegen<'tcx>: Type = Self::Type, Funclet = Self::Funclet, DIScope = Self::DIScope, + DIVariable = Self::DIVariable, >; } From f4b74773c730e7afb6e81aa90df3ddade7442b60 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 22 Jan 2020 19:45:22 +0200 Subject: [PATCH 2/3] rustc_codegen_ssa: convert mir::VarDebugInfo into a custom PerLocalVarDebugInfo. --- src/librustc_codegen_ssa/mir/debuginfo.rs | 174 ++++++++++++++++------ src/librustc_codegen_ssa/mir/mod.rs | 13 +- 2 files changed, 133 insertions(+), 54 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index 1ee5fdba2a202..f66496d10fb16 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -1,12 +1,12 @@ use crate::traits::*; use rustc::mir; use rustc::session::config::DebugInfo; +use rustc::ty; use rustc::ty::layout::{LayoutOf, Size}; -use rustc::ty::TyCtxt; use rustc_hir::def_id::CrateNum; use rustc_index::vec::IndexVec; -use rustc_span::symbol::kw; +use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, Span}; use super::OperandValue; @@ -24,6 +24,19 @@ pub enum VariableKind { LocalVariable, } +/// Like `mir::VarDebugInfo`, but within a `mir::Local`. +#[derive(Copy, Clone)] +pub struct PerLocalVarDebugInfo<'tcx, D> { + pub name: Symbol, + pub source_info: mir::SourceInfo, + + /// `DIVariable` returned by `create_dbg_var`. + pub dbg_var: Option, + + /// `.place.projection` from `mir::VarDebugInfo`. + pub projection: &'tcx ty::List>, +} + #[derive(Clone, Copy, Debug)] pub struct DebugScope { pub scope_metadata: Option, @@ -103,6 +116,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // FIXME(eddyb) use `llvm.dbg.value` (which would work for operands), // not just `llvm.dbg.declare` (which requires `alloca`). pub fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) { + let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full; + // FIXME(eddyb) maybe name the return place as `_0` or `return`? if local == mir::RETURN_PLACE { return; @@ -112,35 +127,63 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(per_local) => &per_local[local], None => return, }; - let whole_local_var = vars.iter().copied().find(|var| var.place.projection.is_empty()); - let has_proj = || vars.iter().any(|var| !var.place.projection.is_empty()); + let whole_local_var = vars.iter().find(|var| var.projection.is_empty()).copied(); + let has_proj = || vars.iter().any(|var| !var.projection.is_empty()); - let (fallback_var, kind) = if self.mir.local_kind(local) == mir::LocalKind::Arg { + 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? - let var = if arg_index == 0 && has_proj() { + 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 { - Some(mir::VarDebugInfo { - name: kw::Invalid, - source_info: self.mir.local_decls[local].source_info, - place: local.into(), + let name = kw::Invalid; + let decl = &self.mir.local_decls[local]; + let (scope, span) = if full_debug_info { + self.debug_loc(decl.source_info) + } else { + (None, decl.source_info.span) + }; + let dbg_var = scope.map(|scope| { + // FIXME(eddyb) is this `+ 1` needed at all? + let kind = VariableKind::ArgumentVariable(arg_index + 1); + + self.cx.create_dbg_var( + self.debug_context.as_ref().unwrap(), + name, + self.monomorphize(&decl.ty), + scope, + kind, + span, + ) + }); + + Some(PerLocalVarDebugInfo { + name, + source_info: decl.source_info, + dbg_var, + projection: ty::List::empty(), }) - }; - (var, VariableKind::ArgumentVariable(arg_index + 1)) + } } else { - (None, VariableKind::LocalVariable) + None }; let local_ref = &self.locals[local]; if !bx.sess().fewer_names() { - let name = match whole_local_var.or(fallback_var.as_ref()) { + let name = match whole_local_var.or(fallback_var) { Some(var) if var.name != kw::Invalid => var.name.to_string(), _ => format!("{:?}", local), }; @@ -163,7 +206,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - if bx.sess().opts.debuginfo != DebugInfo::Full { + if !full_debug_info { return; } @@ -178,11 +221,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => return, }; - let vars = vars.iter().copied().chain(if whole_local_var.is_none() { - fallback_var.as_ref() - } else { - None - }); + let vars = vars.iter().copied().chain(fallback_var); for var in vars { let mut layout = base.layout; @@ -190,10 +229,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // FIXME(eddyb) use smallvec here. let mut indirect_offsets = vec![]; - let kind = - if var.place.projection.is_empty() { kind } else { VariableKind::LocalVariable }; - - for elem in &var.place.projection[..] { + for elem in &var.projection[..] { match *elem { mir::ProjectionElem::Deref => { indirect_offsets.push(Size::ZERO); @@ -202,7 +238,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .ty .builtin_deref(true) .unwrap_or_else(|| { - span_bug!(var.source_info.span, "cannot deref `{}`", layout.ty,) + span_bug!(var.source_info.span, "cannot deref `{}`", layout.ty) }) .ty, ); @@ -219,24 +255,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => span_bug!( var.source_info.span, "unsupported var debuginfo place `{:?}`", - var.place, + mir::Place { local, projection: var.projection }, ), } } let (scope, span) = self.debug_loc(var.source_info); if let Some(scope) = scope { - let dbg_var = - bx.create_dbg_var(debug_context, var.name, layout.ty, scope, kind, span); - bx.dbg_var_addr( - debug_context, - dbg_var, - scope, - base.llval, - direct_offset, - &indirect_offsets, - span, - ); + if let Some(dbg_var) = var.dbg_var { + bx.dbg_var_addr( + debug_context, + dbg_var, + scope, + base.llval, + direct_offset, + &indirect_offsets, + span, + ); + } } } } @@ -248,20 +284,60 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } -} -/// Partition all `VarDebuginfo` in `body`, by their base `Local`. -pub fn per_local_var_debug_info( - tcx: TyCtxt<'tcx>, - body: &'a mir::Body<'tcx>, -) -> Option>>> { - if tcx.sess.opts.debuginfo == DebugInfo::Full || !tcx.sess.fewer_names() { - let mut per_local = IndexVec::from_elem(vec![], &body.local_decls); - for var in &body.var_debug_info { - per_local[var.place.local].push(var); + /// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`. + pub fn compute_per_local_var_debug_info( + &self, + ) -> Option>>> { + let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full; + + if !(full_debug_info || !self.cx.sess().fewer_names()) { + return None; + } + + let mut per_local = IndexVec::from_elem(vec![], &self.mir.local_decls); + for var in &self.mir.var_debug_info { + let (scope, span) = if full_debug_info { + self.debug_loc(var.source_info) + } else { + (None, var.source_info.span) + }; + let dbg_var = scope.map(|scope| { + let place = var.place; + let var_ty = self.monomorphized_place_ty(place.as_ref()); + let var_kind = if self.mir.local_kind(place.local) == mir::LocalKind::Arg + && place.projection.is_empty() + { + // FIXME(eddyb, #67586) take `var.source_info.scope` into + // account to avoid using `ArgumentVariable` more than once + // per argument local. + + let arg_index = place.local.index() - 1; + + // FIXME(eddyb) shouldn't `ArgumentVariable` indices be + // offset in closures to account for the hidden environment? + // Also, is this `+ 1` needed at all? + VariableKind::ArgumentVariable(arg_index + 1) + } else { + VariableKind::LocalVariable + }; + self.cx.create_dbg_var( + self.debug_context.as_ref().unwrap(), + var.name, + var_ty, + scope, + var_kind, + span, + ) + }); + + per_local[var.place.local].push(PerLocalVarDebugInfo { + name: var.name, + source_info: var.source_info, + dbg_var, + projection: var.place.projection, + }); } Some(per_local) - } else { - None } } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 02b07ebfb7df5..8a6284479c722 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -11,7 +11,7 @@ use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use self::analyze::CleanupKind; -use self::debuginfo::FunctionDebugContext; +use self::debuginfo::{FunctionDebugContext, PerLocalVarDebugInfo}; use self::place::PlaceRef; use rustc::mir::traversal; @@ -74,9 +74,10 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { /// notably `expect`. locals: IndexVec>, - /// All `VarDebuginfo` from the MIR body, partitioned by `Local`. - /// This is `None` if no variable debuginfo/names are needed. - per_local_var_debug_info: Option>>>, + /// All `VarDebugInfo` from the MIR body, partitioned by `Local`. + /// This is `None` if no var`#[non_exhaustive]`iable debuginfo/names are needed. + per_local_var_debug_info: + Option>>>, /// Caller location propagated if this function has `#[track_caller]`. caller_location: Option>, @@ -178,10 +179,12 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( funclets, locals: IndexVec::new(), debug_context, - per_local_var_debug_info: debuginfo::per_local_var_debug_info(cx.tcx(), mir_body), + per_local_var_debug_info: None, caller_location: None, }; + fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(); + let memory_locals = analyze::non_ssa_locals(&fx); // Allocate variable and temp allocas From e35dfad5b8cfe12555c6b7459c75d4b78280bfb2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 3 Feb 2020 12:14:05 +0200 Subject: [PATCH 3/3] rustc_codegen_llvm: avoid redundant calls to span_start. --- src/librustc_codegen_llvm/debuginfo/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 87af9b9c88da7..c4a52a73e25d9 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -290,7 +290,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { // Get the linkage_name, which is just the symbol name let linkage_name = mangled_name_of_instance(self, instance); - let scope_line = span_start(self, span).line; + // FIXME(eddyb) does this need to be separate from `loc.line` for some reason? + let scope_line = loc.line; let function_name = CString::new(name).unwrap(); let linkage_name = SmallCStr::new(&linkage_name.name.as_str()); @@ -547,10 +548,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { variable_kind: VariableKind, span: Span, ) -> &'ll DIVariable { - let file = span_start(self, span).file; - let file_metadata = file_metadata(self, &file.name, dbg_context.defining_crate); - let loc = span_start(self, span); + let file_metadata = file_metadata(self, &loc.file.name, dbg_context.defining_crate); + let type_metadata = type_metadata(self, variable_type, span); let (argument_index, dwarf_tag) = match variable_kind {