about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-04-06 15:37:19 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-04-11 20:49:07 +0300
commit4e6b178649b30b060cce043862dbaeedd361f2c7 (patch)
treea15b84afea0643490e1d8f01b5a845f36517465f
parente945b2852e772960248105bd9a0518c4a0b10b04 (diff)
downloadrust-4e6b178649b30b060cce043862dbaeedd361f2c7.tar.gz
rust-4e6b178649b30b060cce043862dbaeedd361f2c7.zip
trans: use DefKey directly in debuginfo for paths.
-rw-r--r--src/librustc_trans/base.rs29
-rw-r--r--src/librustc_trans/closure.rs6
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs38
-rw-r--r--src/librustc_trans/debuginfo/mod.rs56
-rw-r--r--src/librustc_trans/debuginfo/namespace.rs160
-rw-r--r--src/librustc_trans/debuginfo/utils.rs17
6 files changed, 113 insertions, 193 deletions
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index f504a720cb5..956e1a5ce96 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -1400,15 +1400,11 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
     pub fn new(ccx: &'blk CrateContext<'blk, 'tcx>,
                llfndecl: ValueRef,
                fn_ty: FnType,
-               definition: Option<(Instance<'tcx>,
-                                   &ty::FnSig<'tcx>,
-                                   Abi,
-                                   &ty::Generics<'tcx>,
-                                   Option<ast::Name>)>,
+               definition: Option<(Instance<'tcx>, &ty::FnSig<'tcx>, Abi)>,
                block_arena: &'blk TypedArena<common::BlockS<'blk, 'tcx>>)
                -> FunctionContext<'blk, 'tcx> {
         let (param_substs, def_id) = match definition {
-            Some((instance, _, _, _, _)) => {
+            Some((instance, _, _)) => {
                 common::validate_substs(instance.substs);
                 (instance.substs, Some(instance.def))
             }
@@ -1450,14 +1446,9 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
             None
         };
 
-        let span = inlined_id.and_then(|id| ccx.tcx().map.opt_span(id));
-
         let debug_context = if let (false, Some(definition)) = (no_debug, definition) {
-            let (instance, sig, abi, generics, name) = definition;
-            debuginfo::create_function_debug_context(ccx, instance, sig,
-                                                     abi, generics, name,
-                                                     span.unwrap_or(DUMMY_SP),
-                                                     llfndecl)
+            let (instance, sig, abi) = definition;
+            debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfndecl)
         } else {
             debuginfo::empty_function_debug_context(ccx)
         };
@@ -1476,7 +1467,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
             lldropflag_hints: RefCell::new(DropFlagHintsMap::new()),
             fn_ty: fn_ty,
             param_substs: param_substs,
-            span: span,
+            span: inlined_id.and_then(|id| ccx.tcx().map.opt_span(id)),
             block_arena: block_arena,
             lpad_arena: TypedArena::new(),
             ccx: ccx,
@@ -1831,8 +1822,6 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                inlined_id: ast::NodeId,
                                sig: &ty::FnSig<'tcx>,
                                abi: Abi,
-                               generics: &ty::Generics<'tcx>,
-                               name: Option<ast::Name>,
                                closure_env: closure::ClosureEnv) {
     ccx.stats().n_closures.set(ccx.stats().n_closures.get() + 1);
 
@@ -1849,8 +1838,7 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     let (arena, fcx): (TypedArena<_>, FunctionContext);
     arena = TypedArena::new();
-    fcx = FunctionContext::new(ccx, llfndecl, fn_ty,
-                               Some((instance, sig, abi, generics, name)), &arena);
+    fcx = FunctionContext::new(ccx, llfndecl, fn_ty, Some((instance, sig, abi)), &arena);
 
     if fcx.mir.is_some() {
         return mir::trans_mir(&fcx);
@@ -1931,8 +1919,7 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     } else {
         ccx.tcx().map.local_def_id(id)
     };
-    let scheme = ccx.tcx().lookup_item_type(def_id);
-    let fn_ty = scheme.ty;
+    let fn_ty = ccx.tcx().lookup_item_type(def_id).ty;
     let fn_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &fn_ty);
     let sig = ccx.tcx().erase_late_bound_regions(fn_ty.fn_sig());
     let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
@@ -1945,8 +1932,6 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                   id,
                   &sig,
                   abi,
-                  &scheme.generics,
-                  Some(ccx.tcx().item_name(def_id)),
                   closure::ClosureEnv::NotClosure);
 }
 
diff --git a/src/librustc_trans/closure.rs b/src/librustc_trans/closure.rs
index 209f4b39319..c2031638044 100644
--- a/src/librustc_trans/closure.rs
+++ b/src/librustc_trans/closure.rs
@@ -235,10 +235,6 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
         variadic: false
     };
 
-    // This is not quite right. It should actually inherit
-    // the generics of the enclosing function.
-    let generics = ty::Generics::empty();
-
     trans_closure(ccx,
                   decl,
                   body,
@@ -247,8 +243,6 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
                   id,
                   &sig,
                   Abi::RustCall,
-                  &generics,
-                  None,
                   ClosureEnv::Closure(closure_def_id, id));
 
     // Don't hoist this to the top of the function. It's perfectly legitimate
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index 8471b6a274c..de403732269 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -16,7 +16,7 @@ use self::EnumDiscriminantInfo::*;
 use super::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align_of,
                    get_namespace_and_span_for_item, create_DIArray,
                    fn_should_be_ignored, is_node_local_to_unit};
-use super::namespace::namespace_for_item;
+use super::namespace::mangled_name_of_item;
 use super::type_names::{compute_debuginfo_type_name, push_debuginfo_type_name};
 use super::{declare_local, VariableKind, VariableAccess};
 
@@ -68,8 +68,8 @@ pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
 pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
 
 // ptr::null() doesn't work :(
-const NO_FILE_METADATA: DIFile = (0 as DIFile);
-const NO_SCOPE_METADATA: DIScope = (0 as DIScope);
+pub const NO_FILE_METADATA: DIFile = (0 as DIFile);
+pub const NO_SCOPE_METADATA: DIScope = (0 as DIScope);
 
 const FLAGS_NONE: c_uint = 0;
 
@@ -1846,28 +1846,8 @@ pub fn create_global_var_metadata(cx: &CrateContext,
         return;
     }
 
-    let var_item = cx.tcx().map.get(node_id);
-
-    let (name, span) = match var_item {
-        hir_map::NodeItem(item) => {
-            match item.node {
-                hir::ItemStatic(..) => (item.name, item.span),
-                hir::ItemConst(..) => (item.name, item.span),
-                _ => {
-                    span_bug!(item.span,
-                              "debuginfo::\
-                               create_global_var_metadata() -
-                               Captured var-id refers to \
-                               unexpected ast_item variant: {:?}",
-                              var_item)
-                }
-            }
-        },
-        _ => bug!("debuginfo::create_global_var_metadata() \
-                   - Captured var-id refers to unexpected \
-                   hir_map variant: {:?}",
-                  var_item)
-    };
+    let node_def_id = cx.tcx().map.local_def_id(node_id);
+    let (var_scope, span) = get_namespace_and_span_for_item(cx, node_def_id);
 
     let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
         let loc = span_start(cx, span);
@@ -1879,12 +1859,8 @@ pub fn create_global_var_metadata(cx: &CrateContext,
     let is_local_to_unit = is_node_local_to_unit(cx, node_id);
     let variable_type = cx.tcx().node_id_to_type(node_id);
     let type_metadata = type_metadata(cx, variable_type, span);
-    let node_def_id = cx.tcx().map.local_def_id(node_id);
-    let namespace_node = namespace_for_item(cx, node_def_id);
-    let var_name = name.to_string();
-    let linkage_name =
-        namespace_node.mangled_name_of_contained_item(&var_name[..]);
-    let var_scope = namespace_node.scope;
+    let var_name = cx.tcx().item_name(node_def_id).to_string();
+    let linkage_name = mangled_name_of_item(cx, node_def_id, "");
 
     let var_name = CString::new(var_name).unwrap();
     let linkage_name = CString::new(linkage_name).unwrap();
diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs
index cf7d98f2f01..2ecd6c5ebf7 100644
--- a/src/librustc_trans/debuginfo/mod.rs
+++ b/src/librustc_trans/debuginfo/mod.rs
@@ -14,8 +14,9 @@ mod doc;
 use self::VariableAccess::*;
 use self::VariableKind::*;
 
-use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit};
-use self::namespace::{namespace_for_item, NamespaceTreeNode};
+use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit,
+                  get_namespace_and_span_for_item};
+use self::namespace::mangled_name_of_item;
 use self::type_names::compute_debuginfo_type_name;
 use self::metadata::{type_metadata, diverging_type_metadata};
 use self::metadata::{file_metadata, scope_metadata, TypeMap, compile_unit_metadata};
@@ -26,6 +27,7 @@ use llvm::{ModuleRef, ContextRef, ValueRef};
 use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray,
                       FlagPrototyped};
 use rustc::hir::def_id::DefId;
+use rustc::hir::map::DefPathData;
 use rustc::ty::subst::Substs;
 use rustc::hir;
 
@@ -34,18 +36,16 @@ use common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
 use monomorphize::Instance;
 use rustc::ty::{self, Ty};
 use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
-use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
+use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
 
 use libc::c_uint;
 use std::cell::{Cell, RefCell};
 use std::ffi::CString;
 use std::ptr;
-use std::rc::Rc;
 
 use syntax::codemap::{Span, Pos};
 use syntax::{ast, codemap};
 use syntax::attr::IntType;
-use syntax::parse::token;
 
 pub mod gdb;
 mod utils;
@@ -80,7 +80,7 @@ pub struct CrateDebugContext<'tcx> {
     created_enum_disr_types: RefCell<FnvHashMap<(DefId, IntType), DIType>>,
 
     type_map: RefCell<TypeMap<'tcx>>,
-    namespace_map: RefCell<FnvHashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
+    namespace_map: RefCell<DefIdMap<DIScope>>,
 
     // This collection is used to assert that composite types (structs, enums,
     // ...) have their members only set once:
@@ -100,7 +100,7 @@ impl<'tcx> CrateDebugContext<'tcx> {
             created_files: RefCell::new(FnvHashMap()),
             created_enum_disr_types: RefCell::new(FnvHashMap()),
             type_map: RefCell::new(TypeMap::new()),
-            namespace_map: RefCell::new(FnvHashMap()),
+            namespace_map: RefCell::new(DefIdMap()),
             composite_types_completed: RefCell::new(FnvHashSet()),
         };
     }
@@ -232,9 +232,6 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                                instance: Instance<'tcx>,
                                                sig: &ty::FnSig<'tcx>,
                                                abi: Abi,
-                                               generics: &ty::Generics<'tcx>,
-                                               name: Option<ast::Name>,
-                                               span: Span,
                                                llfn: ValueRef) -> FunctionDebugContext {
     if cx.sess().opts.debuginfo == NoDebugInfo {
         return FunctionDebugContext::DebugInfoDisabled;
@@ -245,6 +242,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     source_loc::set_debug_location(cx, InternalDebugLocation::UnknownLocation);
 
     // This can be the case for functions inlined from another crate
+    let (containing_scope, span) = get_namespace_and_span_for_item(cx, instance.def);
     if span == codemap::DUMMY_SP {
         return FunctionDebugContext::FunctionWithoutDebugInfo;
     }
@@ -257,38 +255,34 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
     };
 
+    // Find the enclosing function, in case this is a closure.
+    let mut fn_def_id = instance.def;
+    let mut def_key = cx.tcx().def_key(fn_def_id);
+    let mut name = def_key.disambiguated_data.data.to_string();
+    let name_len = name.len();
+    while def_key.disambiguated_data.data == DefPathData::ClosureExpr {
+        fn_def_id.index = def_key.parent.expect("closure without a parent?");
+        def_key = cx.tcx().def_key(fn_def_id);
+    }
+
     // Get_template_parameters() will append a `<...>` clause to the function
     // name if necessary.
-    let mut function_name = name.map(|name| name.to_string()).unwrap_or_else(|| {
-        // We do this only for closures atm.
-        format!("fn{}", token::gensym("fn"))
-    });
+    let generics = cx.tcx().lookup_item_type(fn_def_id).generics;
     let template_parameters = get_template_parameters(cx,
-                                                      generics,
+                                                      &generics,
                                                       instance.substs,
                                                       file_metadata,
-                                                      &mut function_name);
-
-    // There is no hir_map::Path for hir::ExprClosure-type functions. For now,
-    // just don't put them into a namespace. In the future this could be improved
-    // somehow (storing a path in the hir_map, or construct a path using the
-    // enclosing function).
-    let (linkage_name, containing_scope) = if name.is_some() {
-        let namespace_node = namespace_for_item(cx, instance.def);
-        let linkage_name = namespace_node.mangled_name_of_contained_item(
-            &function_name[..]);
-        let containing_scope = namespace_node.scope;
-        (linkage_name, containing_scope)
-    } else {
-        (function_name.clone(), file_metadata)
-    };
+                                                      &mut name);
+
+    // Build the linkage_name out of the item path and "template" parameters.
+    let linkage_name = mangled_name_of_item(cx, instance.def, &name[name_len..]);
 
     let scope_line = span_start(cx, span).line;
 
     let local_id = cx.tcx().map.as_local_node_id(instance.def);
     let is_local_to_unit = local_id.map_or(false, |id| is_node_local_to_unit(cx, id));
 
-    let function_name = CString::new(function_name).unwrap();
+    let function_name = CString::new(name).unwrap();
     let linkage_name = CString::new(linkage_name).unwrap();
     let fn_metadata = unsafe {
         llvm::LLVMDIBuilderCreateFunction(
diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs
index 5272a4fbbb7..fc31eaa4e74 100644
--- a/src/librustc_trans/debuginfo/namespace.rs
+++ b/src/librustc_trans/debuginfo/namespace.rs
@@ -10,118 +10,82 @@
 
 // Namespace Handling.
 
-use super::utils::{DIB, debug_context};
+use super::metadata::{file_metadata, NO_FILE_METADATA, UNKNOWN_LINE_NUMBER};
+use super::utils::{DIB, debug_context, span_start};
 
 use llvm;
 use llvm::debuginfo::DIScope;
 use rustc::hir::def_id::DefId;
-use rustc::hir::map as hir_map;
+use rustc::hir::map::DefPathData;
 use common::CrateContext;
 
+use libc::c_uint;
 use std::ffi::CString;
-use std::iter::once;
 use std::ptr;
-use std::rc::{Rc, Weak};
-use syntax::ast;
-use syntax::parse::token;
-
-pub struct NamespaceTreeNode {
-    pub name: ast::Name,
-    pub scope: DIScope,
-    pub parent: Option<Weak<NamespaceTreeNode>>,
-}
-
-impl NamespaceTreeNode {
-    pub fn mangled_name_of_contained_item(&self, item_name: &str) -> String {
-        fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
-            match node.parent {
-                Some(ref parent) => fill_nested(&parent.upgrade().unwrap(), output),
-                None => {}
-            }
-            let string = node.name.as_str();
-            output.push_str(&string.len().to_string());
-            output.push_str(&string);
+use syntax::codemap::DUMMY_SP;
+
+pub fn mangled_name_of_item(ccx: &CrateContext, def_id: DefId, extra: &str) -> String {
+    fn fill_nested(ccx: &CrateContext, def_id: DefId, extra: &str, output: &mut String) {
+        let def_key = ccx.tcx().def_key(def_id);
+        if let Some(parent) = def_key.parent {
+            fill_nested(ccx, DefId {
+                krate: def_id.krate,
+                index: parent
+            }, "", output);
         }
 
-        let mut name = String::from("_ZN");
-        fill_nested(self, &mut name);
-        name.push_str(&item_name.len().to_string());
-        name.push_str(item_name);
-        name.push('E');
-        name
-    }
-}
-
-pub fn namespace_for_item(cx: &CrateContext, def_id: DefId) -> Rc<NamespaceTreeNode> {
-    // prepend crate name.
-    // This shouldn't need a roundtrip through InternedString.
-    let krate = token::intern(&cx.tcx().crate_name(def_id.krate));
-    let krate = hir_map::DefPathData::TypeNs(krate);
-    let path = cx.tcx().def_path(def_id).data;
-    let mut path = once(krate).chain(path.into_iter().map(|e| e.data)).peekable();
-
-    let mut current_key = Vec::new();
-    let mut parent_node: Option<Rc<NamespaceTreeNode>> = None;
-
-    // Create/Lookup namespace for each element of the path.
-    loop {
-        // Emulate a for loop so we can use peek below.
-        let path_element = match path.next() {
-            Some(e) => e,
-            None => break
+        let name = match def_key.disambiguated_data.data {
+            DefPathData::CrateRoot => ccx.tcx().crate_name(def_id.krate),
+            data => data.as_interned_str()
         };
-        // Ignore the name of the item (the last path element).
-        if path.peek().is_none() {
-            break;
-        }
 
-        // This shouldn't need a roundtrip through InternedString.
-        let namespace_name = path_element.as_interned_str();
-        let name = token::intern(&namespace_name);
-        current_key.push(name);
-
-        let existing_node = debug_context(cx).namespace_map.borrow()
-                                             .get(&current_key).cloned();
-        let current_node = match existing_node {
-            Some(existing_node) => existing_node,
-            None => {
-                // create and insert
-                let parent_scope = match parent_node {
-                    Some(ref node) => node.scope,
-                    None => ptr::null_mut()
-                };
-                let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
-                let scope = unsafe {
-                    llvm::LLVMDIBuilderCreateNameSpace(
-                        DIB(cx),
-                        parent_scope,
-                        namespace_name.as_ptr(),
-                        // cannot reconstruct file ...
-                        ptr::null_mut(),
-                        // ... or line information, but that's not so important.
-                        0)
-                };
-
-                let node = Rc::new(NamespaceTreeNode {
-                    name: name,
-                    scope: scope,
-                    parent: parent_node.map(|parent| Rc::downgrade(&parent)),
-                });
-
-                debug_context(cx).namespace_map.borrow_mut()
-                                 .insert(current_key.clone(), node.clone());
+        output.push_str(&(name.len() + extra.len()).to_string());
+        output.push_str(&name);
+        output.push_str(extra);
+    }
 
-                node
-            }
-        };
+    let mut name = String::from("_ZN");
+    fill_nested(ccx, def_id, extra, &mut name);
+    name.push('E');
+    name
+}
 
-        parent_node = Some(current_node);
+pub fn item_namespace(ccx: &CrateContext, def_id: DefId) -> DIScope {
+    if let Some(&scope) = debug_context(ccx).namespace_map.borrow().get(&def_id) {
+        return scope;
     }
 
-    match parent_node {
-        Some(node) => node,
-        None => {
-            bug!("debuginfo::namespace_for_item: path too short for {:?}", def_id);
-        }
-    }
+    let def_key = ccx.tcx().def_key(def_id);
+    let parent_scope = def_key.parent.map_or(ptr::null_mut(), |parent| {
+        item_namespace(ccx, DefId {
+            krate: def_id.krate,
+            index: parent
+        })
+    });
+
+    let namespace_name = match def_key.disambiguated_data.data {
+        DefPathData::CrateRoot => ccx.tcx().crate_name(def_id.krate),
+        data => data.as_interned_str()
+    };
+
+    let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
+    let span = ccx.tcx().map.def_id_span(def_id, DUMMY_SP);
+    let (file, line) = if span != DUMMY_SP {
+        let loc = span_start(ccx, span);
+        (file_metadata(ccx, &loc.file.name), loc.line as c_uint)
+    } else {
+        (NO_FILE_METADATA, UNKNOWN_LINE_NUMBER)
+    };
+
+    let scope = unsafe {
+        llvm::LLVMDIBuilderCreateNameSpace(
+            DIB(ccx),
+            parent_scope,
+            namespace_name.as_ptr(),
+            file,
+            line as c_uint)
+    };
+
+    debug_context(ccx).namespace_map.borrow_mut().insert(def_id, scope);
+    scope
 }
diff --git a/src/librustc_trans/debuginfo/utils.rs b/src/librustc_trans/debuginfo/utils.rs
index 805cb67986c..3fd97937184 100644
--- a/src/librustc_trans/debuginfo/utils.rs
+++ b/src/librustc_trans/debuginfo/utils.rs
@@ -11,7 +11,7 @@
 // Utility Functions.
 
 use super::{FunctionDebugContext, CrateDebugContext};
-use super::namespace::namespace_for_item;
+use super::namespace::item_namespace;
 
 use rustc::hir::def_id::DefId;
 
@@ -79,10 +79,17 @@ pub fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
 
 pub fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: DefId)
                                    -> (DIScope, Span) {
-    let containing_scope = namespace_for_item(cx, def_id).scope;
-    let definition_span = cx.tcx().map.def_id_span(def_id, codemap::DUMMY_SP /* (1) */ );
-
-    // (1) For external items there is no span information
+    let containing_scope = item_namespace(cx, DefId {
+        krate: def_id.krate,
+        index: cx.tcx().def_key(def_id).parent
+                 .expect("get_namespace_and_span_for_item: missing parent?")
+    });
+
+    // Try to get some span information, if we have an inlined item.
+    let definition_span = match cx.external().borrow().get(&def_id) {
+        Some(&Some(node_id)) => cx.tcx().map.span(node_id),
+        _ => cx.tcx().map.def_id_span(def_id, codemap::DUMMY_SP)
+    };
 
     (containing_scope, definition_span)
 }