@@ -15,7 +15,7 @@ use rustc::mir::interpret::PanicInfo;
15
15
use rustc:: ty:: layout:: { self , FnAbiExt , HasTyCtxt , LayoutOf } ;
16
16
use rustc:: ty:: { self , Instance , Ty , TypeFoldable } ;
17
17
use rustc_index:: vec:: Idx ;
18
- use rustc_span:: { source_map :: Span , symbol :: Symbol } ;
18
+ use rustc_span:: { Span , Symbol } ;
19
19
use rustc_target:: abi:: call:: { ArgAbi , FnAbi , PassMode } ;
20
20
use rustc_target:: spec:: abi:: Abi ;
21
21
@@ -408,7 +408,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
408
408
self . set_debug_loc ( & mut bx, terminator. source_info ) ;
409
409
410
410
// Get the location information.
411
- let location = self . get_caller_location ( & mut bx, span ) . immediate ( ) ;
411
+ let location = self . get_caller_location ( & mut bx, terminator . source_info ) . immediate ( ) ;
412
412
413
413
// Put together the arguments to the panic entry point.
414
414
let ( lang_item, args) = match msg {
@@ -444,7 +444,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
444
444
destination : & Option < ( mir:: Place < ' tcx > , mir:: BasicBlock ) > ,
445
445
cleanup : Option < mir:: BasicBlock > ,
446
446
) {
447
- let span = terminator. source_info . span ;
447
+ let source_info = terminator. source_info ;
448
+ let span = source_info. span ;
449
+
448
450
// Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar.
449
451
let callee = self . codegen_operand ( & mut bx, func) ;
450
452
@@ -530,7 +532,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
530
532
if layout. abi . is_uninhabited ( ) {
531
533
let msg_str = format ! ( "Attempted to instantiate uninhabited type {}" , ty) ;
532
534
let msg = bx. const_str ( Symbol :: intern ( & msg_str) ) ;
533
- let location = self . get_caller_location ( & mut bx, span ) . immediate ( ) ;
535
+ let location = self . get_caller_location ( & mut bx, source_info ) . immediate ( ) ;
534
536
535
537
// Obtain the panic entry point.
536
538
let def_id =
@@ -575,7 +577,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
575
577
576
578
if intrinsic == Some ( "caller_location" ) {
577
579
if let Some ( ( _, target) ) = destination. as_ref ( ) {
578
- let location = self . get_caller_location ( & mut bx, span ) ;
580
+ let location = self . get_caller_location ( & mut bx, source_info ) ;
579
581
580
582
if let ReturnDest :: IndirectOperand ( tmp, _) = ret_dest {
581
583
location. val . store ( & mut bx, tmp) ;
@@ -627,13 +629,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
627
629
} )
628
630
. collect ( ) ;
629
631
630
- bx. codegen_intrinsic_call (
631
- * instance. as_ref ( ) . unwrap ( ) ,
632
- & fn_abi,
633
- & args,
634
- dest,
635
- terminator. source_info . span ,
636
- ) ;
632
+ bx. codegen_intrinsic_call ( * instance. as_ref ( ) . unwrap ( ) , & fn_abi, & args, dest, span) ;
637
633
638
634
if let ReturnDest :: IndirectOperand ( dst, _) = ret_dest {
639
635
self . store_return ( & mut bx, ret_dest, & fn_abi. ret , dst. llval ) ;
@@ -739,7 +735,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
739
735
args. len( ) + 1 ,
740
736
"#[track_caller] fn's must have 1 more argument in their ABI than in their MIR" ,
741
737
) ;
742
- let location = self . get_caller_location ( & mut bx, span ) ;
738
+ let location = self . get_caller_location ( & mut bx, source_info ) ;
743
739
let last_arg = fn_abi. args . last ( ) . unwrap ( ) ;
744
740
self . codegen_argument ( & mut bx, location, & mut llargs, last_arg) ;
745
741
}
@@ -982,17 +978,46 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
982
978
}
983
979
}
984
980
985
- fn get_caller_location ( & mut self , bx : & mut Bx , span : Span ) -> OperandRef < ' tcx , Bx :: Value > {
986
- self . caller_location . unwrap_or_else ( || {
981
+ fn get_caller_location (
982
+ & mut self ,
983
+ bx : & mut Bx ,
984
+ source_info : mir:: SourceInfo ,
985
+ ) -> OperandRef < ' tcx , Bx :: Value > {
986
+ let tcx = bx. tcx ( ) ;
987
+
988
+ let mut span_to_caller_location = |span : Span | {
987
989
let topmost = span. ctxt ( ) . outer_expn ( ) . expansion_cause ( ) . unwrap_or ( span) ;
988
- let caller = bx . tcx ( ) . sess . source_map ( ) . lookup_char_pos ( topmost. lo ( ) ) ;
989
- let const_loc = bx . tcx ( ) . const_caller_location ( (
990
+ let caller = tcx. sess . source_map ( ) . lookup_char_pos ( topmost. lo ( ) ) ;
991
+ let const_loc = tcx. const_caller_location ( (
990
992
Symbol :: intern ( & caller. file . name . to_string ( ) ) ,
991
993
caller. line as u32 ,
992
994
caller. col_display as u32 + 1 ,
993
995
) ) ;
994
996
OperandRef :: from_const ( bx, const_loc)
995
- } )
997
+ } ;
998
+
999
+ // Walk up the `SourceScope`s, in case some of them are from MIR inlining.
1000
+ let mut caller_span = source_info. span ;
1001
+ let mut scope = source_info. scope ;
1002
+ loop {
1003
+ let scope_data = & self . mir . source_scopes [ scope] ;
1004
+
1005
+ if let Some ( ( callee, callsite_span) ) = scope_data. inlined {
1006
+ // Stop before ("inside") the callsite of a non-`#[track_caller]` function.
1007
+ if !callee. def . requires_caller_location ( tcx) {
1008
+ return span_to_caller_location ( caller_span) ;
1009
+ }
1010
+ caller_span = callsite_span;
1011
+ }
1012
+
1013
+ match scope_data. parent_scope {
1014
+ Some ( parent) => scope = parent,
1015
+ None => break ,
1016
+ }
1017
+ }
1018
+
1019
+ // No inlined `SourceScope`s, or all of them were `#[track_caller]`.
1020
+ self . caller_location . unwrap_or_else ( || span_to_caller_location ( caller_span) )
996
1021
}
997
1022
998
1023
fn get_personality_slot ( & mut self , bx : & mut Bx ) -> PlaceRef < ' tcx , Bx :: Value > {
0 commit comments