@@ -15,7 +15,7 @@ use rustc::mir::interpret::PanicInfo;
1515use rustc:: ty:: layout:: { self , FnAbiExt , HasTyCtxt , LayoutOf } ;
1616use rustc:: ty:: { self , Instance , Ty , TypeFoldable } ;
1717use rustc_index:: vec:: Idx ;
18- use rustc_span:: { source_map :: Span , symbol :: Symbol } ;
18+ use rustc_span:: { Span , Symbol } ;
1919use rustc_target:: abi:: call:: { ArgAbi , FnAbi , PassMode } ;
2020use rustc_target:: spec:: abi:: Abi ;
2121
@@ -408,7 +408,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
408408 self . set_debug_loc ( & mut bx, terminator. source_info ) ;
409409
410410 // 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 ( ) ;
412412
413413 // Put together the arguments to the panic entry point.
414414 let ( lang_item, args) = match msg {
@@ -444,7 +444,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
444444 destination : & Option < ( mir:: Place < ' tcx > , mir:: BasicBlock ) > ,
445445 cleanup : Option < mir:: BasicBlock > ,
446446 ) {
447- let span = terminator. source_info . span ;
447+ let source_info = terminator. source_info ;
448+ let span = source_info. span ;
449+
448450 // Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar.
449451 let callee = self . codegen_operand ( & mut bx, func) ;
450452
@@ -530,7 +532,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
530532 if layout. abi . is_uninhabited ( ) {
531533 let msg_str = format ! ( "Attempted to instantiate uninhabited type {}" , ty) ;
532534 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 ( ) ;
534536
535537 // Obtain the panic entry point.
536538 let def_id =
@@ -575,7 +577,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
575577
576578 if intrinsic == Some ( "caller_location" ) {
577579 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 ) ;
579581
580582 if let ReturnDest :: IndirectOperand ( tmp, _) = ret_dest {
581583 location. val . store ( & mut bx, tmp) ;
@@ -627,13 +629,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
627629 } )
628630 . collect ( ) ;
629631
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) ;
637633
638634 if let ReturnDest :: IndirectOperand ( dst, _) = ret_dest {
639635 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> {
739735 args. len( ) + 1 ,
740736 "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR" ,
741737 ) ;
742- let location = self . get_caller_location ( & mut bx, span ) ;
738+ let location = self . get_caller_location ( & mut bx, source_info ) ;
743739 let last_arg = fn_abi. args . last ( ) . unwrap ( ) ;
744740 self . codegen_argument ( & mut bx, location, & mut llargs, last_arg) ;
745741 }
@@ -982,17 +978,46 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
982978 }
983979 }
984980
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 | {
987989 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 ( (
990992 Symbol :: intern ( & caller. file . name . to_string ( ) ) ,
991993 caller. line as u32 ,
992994 caller. col_display as u32 + 1 ,
993995 ) ) ;
994996 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) )
9961021 }
9971022
9981023 fn get_personality_slot ( & mut self , bx : & mut Bx ) -> PlaceRef < ' tcx , Bx :: Value > {
0 commit comments