@@ -2,11 +2,33 @@ use rustc::middle::lang_items::PanicLocationLangItem;
22use rustc:: mir:: interpret:: { Pointer , PointerArithmetic , Scalar } ;
33use rustc:: ty:: subst:: Subst ;
44use rustc_target:: abi:: { LayoutOf , Size } ;
5- use syntax_pos:: Symbol ;
5+ use syntax_pos:: { Span , Symbol } ;
66
77use crate :: interpret:: { MemoryKind , MPlaceTy , intrinsics:: { InterpCx , InterpResult , Machine } } ;
88
99impl < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > InterpCx < ' mir , ' tcx , M > {
10+ /// Walks up the callstack from the intrinsic's callsite, searching for the first frame which is
11+ /// not `#[track_caller]`. Returns the (passed) span of the intrinsic's callsite if the first
12+ /// frame in the stack is untracked so that we can display the callsite of the intrinsic within
13+ /// that function.
14+ crate fn find_closest_untracked_caller_location (
15+ & self ,
16+ intrinsic_loc : Span ,
17+ ) -> Span {
18+ debug ! ( "finding closest untracked caller relative to {:?}" , intrinsic_loc) ;
19+
20+ let mut caller_span = intrinsic_loc;
21+ for next_caller in self . stack . iter ( ) . rev ( ) {
22+ if !next_caller. instance . def . requires_caller_location ( * self . tcx ) {
23+ return caller_span;
24+ }
25+ caller_span = next_caller. span ;
26+ }
27+
28+ intrinsic_loc
29+ }
30+
31+ /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
1032 pub fn alloc_caller_location (
1133 & mut self ,
1234 filename : Symbol ,
@@ -19,17 +41,21 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1941 let ptr_size = self . pointer_size ( ) ;
2042 let u32_size = Size :: from_bits ( 32 ) ;
2143
44+ // we can't use TyCtxt::caller_location_ty because that returns `&'static Location`
45+ let static_subst = self . tcx . mk_substs ( [ self . tcx . lifetimes . re_static . into ( ) ] . iter ( ) ) ;
2246 let loc_ty = self . tcx . type_of ( self . tcx . require_lang_item ( PanicLocationLangItem , None ) )
23- . subst ( * self . tcx , self . tcx . mk_substs ( [ self . tcx . lifetimes . re_static . into ( ) ] . iter ( ) ) ) ;
47+ . subst ( * self . tcx , static_subst ) ;
2448 let loc_layout = self . layout_of ( loc_ty) ?;
2549
50+ // we have all our sizes and layouts, start allocating
2651 let file_alloc = self . tcx . allocate_bytes ( filename. as_str ( ) . as_bytes ( ) ) ;
2752 let file_ptr = Pointer :: new ( file_alloc, Size :: ZERO ) ;
2853 let file = Scalar :: Ptr ( self . tag_static_base_pointer ( file_ptr) ) ;
2954 let file_len = Scalar :: from_uint ( filename. as_str ( ) . len ( ) as u128 , ptr_size) ;
3055
3156 let location = self . allocate ( loc_layout, MemoryKind :: Stack ) ;
3257
58+ // now that the struct is allocated, we need to get field offsets
3359 let file_out = self . mplace_field ( location, 0 ) ?;
3460 let file_ptr_out = self . force_ptr ( self . mplace_field ( file_out, 0 ) ?. ptr ) ?;
3561 let file_len_out = self . force_ptr ( self . mplace_field ( file_out, 1 ) ?. ptr ) ?;
@@ -39,6 +65,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
3965 let layout = & self . tcx . data_layout ;
4066 let alloc = self . memory . get_mut ( file_ptr_out. alloc_id ) ?;
4167
68+ // finally write into the field offsets
4269 alloc. write_scalar ( layout, file_ptr_out, file. into ( ) , ptr_size) ?;
4370 alloc. write_scalar ( layout, file_len_out, file_len. into ( ) , ptr_size) ?;
4471 alloc. write_scalar ( layout, line_out, line. into ( ) , u32_size) ?;
0 commit comments