@@ -14,8 +14,7 @@ mod doc;
14
14
use self :: VariableAccess :: * ;
15
15
use self :: VariableKind :: * ;
16
16
17
- use self :: utils:: { DIB , span_start, create_DIArray, is_node_local_to_unit,
18
- get_namespace_and_span_for_item} ;
17
+ use self :: utils:: { DIB , span_start, create_DIArray, is_node_local_to_unit} ;
19
18
use self :: namespace:: mangled_name_of_item;
20
19
use self :: type_names:: compute_debuginfo_type_name;
21
20
use self :: metadata:: { type_metadata, diverging_type_metadata} ;
@@ -33,7 +32,7 @@ use rustc::hir;
33
32
34
33
use abi:: Abi ;
35
34
use common:: { NodeIdAndSpan , CrateContext , FunctionContext , Block , BlockAndBuilder } ;
36
- use monomorphize:: Instance ;
35
+ use monomorphize:: { self , Instance } ;
37
36
use rustc:: ty:: { self , Ty } ;
38
37
use session:: config:: { self , FullDebugInfo , LimitedDebugInfo , NoDebugInfo } ;
39
38
use util:: nodemap:: { DefIdMap , NodeMap , FnvHashMap , FnvHashSet } ;
@@ -240,8 +239,9 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
240
239
// Do this here already, in case we do an early exit from this function.
241
240
source_loc:: set_debug_location ( cx, None , UnknownLocation ) ;
242
241
242
+ let ( containing_scope, span) = get_containing_scope_and_span ( cx, instance) ;
243
+
243
244
// This can be the case for functions inlined from another crate
244
- let ( containing_scope, span) = get_namespace_and_span_for_item ( cx, instance. def ) ;
245
245
if span == codemap:: DUMMY_SP {
246
246
return FunctionDebugContext :: FunctionWithoutDebugInfo ;
247
247
}
@@ -283,6 +283,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
283
283
284
284
let function_name = CString :: new ( name) . unwrap ( ) ;
285
285
let linkage_name = CString :: new ( linkage_name) . unwrap ( ) ;
286
+
286
287
let fn_metadata = unsafe {
287
288
llvm:: LLVMDIBuilderCreateFunction (
288
289
DIB ( cx) ,
@@ -404,6 +405,47 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
404
405
405
406
return create_DIArray ( DIB ( cx) , & template_params[ ..] ) ;
406
407
}
408
+
409
+ fn get_containing_scope_and_span < ' ccx , ' tcx > ( cx : & CrateContext < ' ccx , ' tcx > ,
410
+ instance : Instance < ' tcx > )
411
+ -> ( DIScope , Span ) {
412
+ // First, let's see if this is a method within an inherent impl. Because
413
+ // if yes, we want to make the result subroutine DIE a child of the
414
+ // subroutine's self-type.
415
+ let self_type = cx. tcx ( ) . impl_of_method ( instance. def ) . and_then ( |impl_def_id| {
416
+ // If the method does *not* belong to a trait, proceed
417
+ if cx. tcx ( ) . trait_id_of_impl ( impl_def_id) . is_none ( ) {
418
+ let impl_self_ty = cx. tcx ( ) . lookup_item_type ( impl_def_id) . ty ;
419
+ let impl_self_ty = cx. tcx ( ) . erase_regions ( & impl_self_ty) ;
420
+ let impl_self_ty = monomorphize:: apply_param_substs ( cx. tcx ( ) ,
421
+ instance. substs ,
422
+ & impl_self_ty) ;
423
+ Some ( type_metadata ( cx, impl_self_ty, codemap:: DUMMY_SP ) )
424
+ } else {
425
+ // For trait method impls we still use the "parallel namespace"
426
+ // strategy
427
+ None
428
+ }
429
+ } ) ;
430
+
431
+ let containing_scope = self_type. unwrap_or_else ( || {
432
+ namespace:: item_namespace ( cx, DefId {
433
+ krate : instance. def . krate ,
434
+ index : cx. tcx ( )
435
+ . def_key ( instance. def )
436
+ . parent
437
+ . expect ( "get_containing_scope_and_span: missing parent?" )
438
+ } )
439
+ } ) ;
440
+
441
+ // Try to get some span information, if we have an inlined item.
442
+ let definition_span = match cx. external ( ) . borrow ( ) . get ( & instance. def ) {
443
+ Some ( & Some ( node_id) ) => cx. tcx ( ) . map . span ( node_id) ,
444
+ _ => cx. tcx ( ) . map . def_id_span ( instance. def , codemap:: DUMMY_SP )
445
+ } ;
446
+
447
+ ( containing_scope, definition_span)
448
+ }
407
449
}
408
450
409
451
/// Computes the scope map for a function given its declaration and body.
0 commit comments