about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-10-26 18:50:22 +0000
committerbors <bors@rust-lang.org>2020-10-26 18:50:22 +0000
commit0da6d42f297642a60f2640ec313b879b376b9ad8 (patch)
treed6272e429e289507cfb80fbb588f98ca468a4c7a /compiler/rustc_codegen_ssa/src
parent35debd4c111610317346f46d791f32551d449bd8 (diff)
parent2b3f00928c3b0db93c87d462a53c9f0df98f3e27 (diff)
downloadrust-0da6d42f297642a60f2640ec313b879b376b9ad8.tar.gz
rust-0da6d42f297642a60f2640ec313b879b376b9ad8.zip
Auto merge of #68965 - eddyb:mir-inline-scope, r=nagisa,oli-obk
 rustc_mir: track inlined callees in SourceScopeData.

We now record which MIR scopes are the roots of *other* (inlined) functions's scope trees, which allows us to generate the correct debuginfo in codegen, similar to what LLVM inlining generates.
This PR makes the `ui` test `backtrace-debuginfo` pass, if the MIR inliner is turned on by default.

Also, `#[track_caller]` is now correct in the face of MIR inlining (cc `@anp).`

Fixes #76997.

r? `@rust-lang/wg-mir-opt`
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs65
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs177
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/debuginfo.rs28
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/mod.rs1
6 files changed, 158 insertions, 116 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index bec0a84cac0..da4637b1afc 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -405,7 +405,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         self.set_debug_loc(&mut bx, terminator.source_info);
 
         // Get the location information.
-        let location = self.get_caller_location(&mut bx, span).immediate();
+        let location = self.get_caller_location(&mut bx, terminator.source_info).immediate();
 
         // Put together the arguments to the panic entry point.
         let (lang_item, args) = match msg {
@@ -442,7 +442,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         bx: &mut Bx,
         intrinsic: Option<Symbol>,
         instance: Option<Instance<'tcx>>,
-        span: Span,
+        source_info: mir::SourceInfo,
         destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>,
         cleanup: Option<mir::BasicBlock>,
     ) -> bool {
@@ -484,11 +484,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     }
                 });
                 let msg = bx.const_str(Symbol::intern(&msg_str));
-                let location = self.get_caller_location(bx, span).immediate();
+                let location = self.get_caller_location(bx, source_info).immediate();
 
                 // Obtain the panic entry point.
                 // FIXME: dedup this with `codegen_assert_terminator` above.
-                let def_id = common::langcall(bx.tcx(), Some(span), "", LangItem::Panic);
+                let def_id =
+                    common::langcall(bx.tcx(), Some(source_info.span), "", LangItem::Panic);
                 let instance = ty::Instance::mono(bx.tcx(), def_id);
                 let fn_abi = FnAbi::of_instance(bx, instance, &[]);
                 let llfn = bx.get_fn_addr(instance);
@@ -529,7 +530,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         cleanup: Option<mir::BasicBlock>,
         fn_span: Span,
     ) {
-        let span = terminator.source_info.span;
+        let source_info = terminator.source_info;
+        let span = source_info.span;
+
         // Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar.
         let callee = self.codegen_operand(&mut bx, func);
 
@@ -606,7 +609,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             &mut bx,
             intrinsic,
             instance,
-            span,
+            source_info,
             destination,
             cleanup,
         ) {
@@ -627,7 +630,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         if intrinsic == Some(sym::caller_location) {
             if let Some((_, target)) = destination.as_ref() {
-                let location = self.get_caller_location(&mut bx, fn_span);
+                let location = self
+                    .get_caller_location(&mut bx, mir::SourceInfo { span: fn_span, ..source_info });
 
                 if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
                     location.val.store(&mut bx, tmp);
@@ -686,7 +690,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 &fn_abi,
                 &args,
                 dest,
-                terminator.source_info.span,
+                span,
             );
 
             if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
@@ -793,7 +797,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 args.len() + 1,
                 "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR",
             );
-            let location = self.get_caller_location(&mut bx, fn_span);
+            let location =
+                self.get_caller_location(&mut bx, mir::SourceInfo { span: fn_span, ..source_info });
             debug!(
                 "codegen_call_terminator({:?}): location={:?} (fn_span {:?})",
                 terminator, location, fn_span
@@ -1179,17 +1184,49 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    fn get_caller_location(&mut self, bx: &mut Bx, span: Span) -> OperandRef<'tcx, Bx::Value> {
-        self.caller_location.unwrap_or_else(|| {
+    fn get_caller_location(
+        &mut self,
+        bx: &mut Bx,
+        mut source_info: mir::SourceInfo,
+    ) -> OperandRef<'tcx, Bx::Value> {
+        let tcx = bx.tcx();
+
+        let mut span_to_caller_location = |span: Span| {
             let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
-            let caller = bx.tcx().sess.source_map().lookup_char_pos(topmost.lo());
-            let const_loc = bx.tcx().const_caller_location((
+            let caller = tcx.sess.source_map().lookup_char_pos(topmost.lo());
+            let const_loc = tcx.const_caller_location((
                 Symbol::intern(&caller.file.name.to_string()),
                 caller.line as u32,
                 caller.col_display as u32 + 1,
             ));
             OperandRef::from_const(bx, const_loc, bx.tcx().caller_location_ty())
-        })
+        };
+
+        // Walk up the `SourceScope`s, in case some of them are from MIR inlining.
+        // If so, the starting `source_info.span` is in the innermost inlined
+        // function, and will be replaced with outer callsite spans as long
+        // as the inlined functions were `#[track_caller]`.
+        loop {
+            let scope_data = &self.mir.source_scopes[source_info.scope];
+
+            if let Some((callee, callsite_span)) = scope_data.inlined {
+                // Stop inside the most nested non-`#[track_caller]` function,
+                // before ever reaching its caller (which is irrelevant).
+                if !callee.def.requires_caller_location(tcx) {
+                    return span_to_caller_location(source_info.span);
+                }
+                source_info.span = callsite_span;
+            }
+
+            // Skip past all of the parents with `inlined: None`.
+            match scope_data.inlined_parent_scope {
+                Some(parent) => source_info.scope = parent,
+                None => break,
+            }
+        }
+
+        // No inlined `SourceScope`s, or all of them were `#[track_caller]`.
+        self.caller_location.unwrap_or_else(|| span_to_caller_location(source_info.span))
     }
 
     fn get_personality_slot(&mut self, bx: &mut Bx) -> PlaceRef<'tcx, Bx::Value> {
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 26a646b0293..4e0396a15a6 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -1,5 +1,4 @@
 use crate::traits::*;
-use rustc_hir::def_id::CrateNum;
 use rustc_index::vec::IndexVec;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir;
@@ -13,9 +12,8 @@ use super::operand::OperandValue;
 use super::place::PlaceRef;
 use super::{FunctionCx, LocalRef};
 
-pub struct FunctionDebugContext<D> {
-    pub scopes: IndexVec<mir::SourceScope, DebugScope<D>>,
-    pub defining_crate: CrateNum,
+pub struct FunctionDebugContext<S, L> {
+    pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>,
 }
 
 #[derive(Copy, Clone)]
@@ -38,77 +36,84 @@ pub struct PerLocalVarDebugInfo<'tcx, D> {
 }
 
 #[derive(Clone, Copy, Debug)]
-pub struct DebugScope<D> {
-    pub scope_metadata: Option<D>,
+pub struct DebugScope<S, L> {
+    // FIXME(eddyb) this should never be `None`, after initialization.
+    pub dbg_scope: Option<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<D> DebugScope<D> {
-    pub fn is_valid(&self) -> bool {
-        self.scope_metadata.is_some()
+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<Cx: CodegenMethods<'tcx, DIScope = S, DILocation = L>>(
+        &self,
+        cx: &Cx,
+        span: Span,
+    ) -> S {
+        // FIXME(eddyb) this should never be `None`.
+        let dbg_scope = self
+            .dbg_scope
+            .unwrap_or_else(|| bug!("`dbg_scope` is only `None` during initialization"));
+
+        let pos = span.lo();
+        if pos < self.file_start_pos || pos >= self.file_end_pos {
+            let sm = cx.sess().source_map();
+            cx.extend_scope_to_file(dbg_scope, &sm.lookup_char_pos(pos).file)
+        } else {
+            dbg_scope
+        }
     }
 }
 
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     pub fn set_debug_loc(&self, bx: &mut Bx, source_info: mir::SourceInfo) {
-        let (scope, span) = self.debug_loc(source_info);
-        bx.set_span(span);
-        if let Some(scope) = scope {
-            bx.set_source_location(scope, span);
+        bx.set_span(source_info.span);
+        if let Some(dbg_loc) = self.dbg_loc(source_info) {
+            bx.set_dbg_loc(dbg_loc);
         }
     }
 
-    pub fn debug_loc(&self, source_info: mir::SourceInfo) -> (Option<Bx::DIScope>, Span) {
+    fn dbg_loc(&self, source_info: mir::SourceInfo) -> Option<Bx::DILocation> {
+        let (dbg_scope, inlined_at, span) = self.adjusted_span_and_dbg_scope(source_info)?;
+        Some(self.cx.dbg_loc(dbg_scope, inlined_at, span))
+    }
+
+    fn adjusted_span_and_dbg_scope(
+        &self,
+        source_info: mir::SourceInfo,
+    ) -> Option<(Bx::DIScope, Option<Bx::DILocation>, Span)> {
+        let span = self.adjust_span_for_debugging(source_info.span);
+        let scope = &self.debug_context.as_ref()?.scopes[source_info.scope];
+        Some((scope.adjust_dbg_scope_for_span(self.cx, span), scope.inlined_at, span))
+    }
+
+    /// In order to have a good line stepping behavior in debugger, we overwrite debug
+    /// locations of macro expansions with that of the outermost expansion site
+    /// (unless the crate is being compiled with `-Z debug-macros`).
+    fn adjust_span_for_debugging(&self, mut span: Span) -> Span {
         // Bail out if debug info emission is not enabled.
-        match self.debug_context {
-            None => return (None, source_info.span),
-            Some(_) => {}
+        if self.debug_context.is_none() {
+            return span;
         }
 
-        // In order to have a good line stepping behavior in debugger, we overwrite debug
-        // locations of macro expansions with that of the outermost expansion site
-        // (unless the crate is being compiled with `-Z debug-macros`).
-        if !source_info.span.from_expansion() || self.cx.sess().opts.debugging_opts.debug_macros {
-            let scope = self.scope_metadata_for_loc(source_info.scope, source_info.span.lo());
-            (scope, source_info.span)
-        } else {
+        if span.from_expansion() && !self.cx.sess().opts.debugging_opts.debug_macros {
             // Walk up the macro expansion chain until we reach a non-expanded span.
             // We also stop at the function body level because no line stepping can occur
             // at the level above that.
-            let span = rustc_span::hygiene::walk_chain(source_info.span, self.mir.span.ctxt());
-            let scope = self.scope_metadata_for_loc(source_info.scope, span.lo());
             // Use span of the outermost expansion site, while keeping the original lexical scope.
-            (scope, span)
+            span = rustc_span::hygiene::walk_chain(span, self.mir.span.ctxt());
         }
-    }
 
-    // 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.
-    fn scope_metadata_for_loc(
-        &self,
-        scope_id: mir::SourceScope,
-        pos: BytePos,
-    ) -> Option<Bx::DIScope> {
-        let debug_context = self.debug_context.as_ref()?;
-        let scope_metadata = debug_context.scopes[scope_id].scope_metadata;
-        if pos < debug_context.scopes[scope_id].file_start_pos
-            || pos >= debug_context.scopes[scope_id].file_end_pos
-        {
-            let sm = self.cx.sess().source_map();
-            let defining_crate = debug_context.defining_crate;
-            Some(self.cx.extend_scope_to_file(
-                scope_metadata.unwrap(),
-                &sm.lookup_char_pos(pos).file,
-                defining_crate,
-            ))
-        } else {
-            scope_metadata
-        }
+        span
     }
 
     /// Apply debuginfo and/or name, after creating the `alloca` for a local,
@@ -149,24 +154,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             } else {
                 let name = kw::Invalid;
                 let decl = &self.mir.local_decls[local];
-                let (scope, span) = if full_debug_info {
-                    self.debug_loc(decl.source_info)
+                let dbg_var = if full_debug_info {
+                    self.adjusted_span_and_dbg_scope(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);
+
+                            self.cx.create_dbg_var(name, arg_ty, dbg_scope, kind, span)
+                        },
+                    )
                 } else {
-                    (None, decl.source_info.span)
+                    None
                 };
-                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,
@@ -247,6 +248,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let vars = vars.iter().copied().chain(fallback_var);
 
         for var in vars {
+            let dbg_var = match var.dbg_var {
+                Some(dbg_var) => dbg_var,
+                None => continue,
+            };
+            let dbg_loc = match self.dbg_loc(var.source_info) {
+                Some(dbg_loc) => dbg_loc,
+                None => continue,
+            };
+
             let mut layout = base.layout;
             let mut direct_offset = Size::ZERO;
             // FIXME(eddyb) use smallvec here.
@@ -283,19 +293,7 @@ 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 {
-                if let Some(dbg_var) = var.dbg_var {
-                    bx.dbg_var_addr(
-                        dbg_var,
-                        scope,
-                        base.llval,
-                        direct_offset,
-                        &indirect_offsets,
-                        span,
-                    );
-                }
-            }
+            bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, direct_offset, &indirect_offsets);
         }
     }
 
@@ -319,12 +317,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         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)
+            let dbg_scope_and_span = if full_debug_info {
+                self.adjusted_span_and_dbg_scope(var.source_info)
             } else {
-                (None, var.source_info.span)
+                None
             };
-            let dbg_var = scope.map(|scope| {
+            let dbg_var = dbg_scope_and_span.map(|(dbg_scope, _, span)| {
                 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
@@ -340,14 +338,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 } else {
                     VariableKind::LocalVariable
                 };
-                self.cx.create_dbg_var(
-                    self.debug_context.as_ref().unwrap(),
-                    var.name,
-                    var_ty,
-                    scope,
-                    var_kind,
-                    span,
-                )
+                self.cx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span)
             });
 
             per_local[var.place.local].push(PerLocalVarDebugInfo {
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index bff263567bf..84e82e88e8e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -26,7 +26,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
 
     mir: &'tcx mir::Body<'tcx>,
 
-    debug_context: Option<FunctionDebugContext<Bx::DIScope>>,
+    debug_context: Option<FunctionDebugContext<Bx::DIScope, Bx::DILocation>>,
 
     llfn: Bx::Function,
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 3fb189e1984..b9c555c2eb0 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -34,6 +34,7 @@ pub trait BackendTypes {
     // FIXME(eddyb) find a common convention for all of the debuginfo-related
     // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.).
     type DIScope: Copy;
+    type DILocation: Copy;
     type DIVariable: Copy;
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
index 1ee0f489ffc..3e66d711d2e 100644
--- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
@@ -1,6 +1,5 @@
 use super::BackendTypes;
 use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
-use rustc_hir::def_id::CrateNum;
 use rustc_middle::mir;
 use rustc_middle::ty::{Instance, Ty};
 use rustc_span::{SourceFile, Span, Symbol};
@@ -19,14 +18,29 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
         instance: Instance<'tcx>,
         fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
         llfn: Self::Function,
-        mir: &mir::Body<'_>,
-    ) -> Option<FunctionDebugContext<Self::DIScope>>;
+        mir: &mir::Body<'tcx>,
+    ) -> Option<FunctionDebugContext<Self::DIScope, Self::DILocation>>;
+
+    // FIXME(eddyb) find a common convention for all of the debuginfo-related
+    // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
+    fn dbg_scope_fn(
+        &self,
+        instance: Instance<'tcx>,
+        fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
+        maybe_definition_llfn: Option<Self::Function>,
+    ) -> Self::DIScope;
+
+    fn dbg_loc(
+        &self,
+        scope: Self::DIScope,
+        inlined_at: Option<Self::DILocation>,
+        span: Span,
+    ) -> Self::DILocation;
 
     fn extend_scope_to_file(
         &self,
         scope_metadata: Self::DIScope,
         file: &SourceFile,
-        defining_crate: CrateNum,
     ) -> Self::DIScope;
     fn debuginfo_finalize(&self);
 
@@ -34,7 +48,6 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
     // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
     fn create_dbg_var(
         &self,
-        dbg_context: &FunctionDebugContext<Self::DIScope>,
         variable_name: Symbol,
         variable_type: Ty<'tcx>,
         scope_metadata: Self::DIScope,
@@ -49,14 +62,13 @@ pub trait DebugInfoBuilderMethods: BackendTypes {
     fn dbg_var_addr(
         &mut self,
         dbg_var: Self::DIVariable,
-        scope_metadata: Self::DIScope,
+        dbg_loc: Self::DILocation,
         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],
-        span: Span,
     );
-    fn set_source_location(&mut self, scope: Self::DIScope, span: Span);
+    fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation);
     fn insert_reference_to_gdb_debug_scripts_section_global(&mut self);
     fn set_var_name(&mut self, value: Self::Value, name: &str);
 }
diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs
index 82518b7f0c3..8ada6c10479 100644
--- a/compiler/rustc_codegen_ssa/src/traits/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs
@@ -95,6 +95,7 @@ pub trait HasCodegen<'tcx>:
             Type = Self::Type,
             Funclet = Self::Funclet,
             DIScope = Self::DIScope,
+            DILocation = Self::DILocation,
             DIVariable = Self::DIVariable,
         >;
 }