]> git.proxmox.com Git - rustc.git/blame - src/librustc_mir/interpret/intrinsics/caller_location.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / librustc_mir / interpret / intrinsics / caller_location.rs
CommitLineData
e74abb32 1use rustc::middle::lang_items::PanicLocationLangItem;
e74abb32 2use rustc::ty::subst::Subst;
60c5eb7d
XL
3use rustc_target::abi::LayoutOf;
4use syntax_pos::{Symbol, Span};
e74abb32 5
60c5eb7d 6use crate::interpret::{Scalar, MemoryKind, MPlaceTy, intrinsics::{InterpCx, Machine}};
e74abb32
XL
7
8impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
60c5eb7d
XL
9 /// Walks up the callstack from the intrinsic's callsite, searching for the first frame which is
10 /// not `#[track_caller]`.
11 crate fn find_closest_untracked_caller_location(&self) -> Option<Span> {
12 let mut caller_span = None;
13 for next_caller in self.stack.iter().rev() {
14 if !next_caller.instance.def.requires_caller_location(*self.tcx) {
15 return caller_span;
16 }
17 caller_span = Some(next_caller.span);
18 }
19
20 caller_span
21 }
22
23 /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
24 crate fn alloc_caller_location(
e74abb32
XL
25 &mut self,
26 filename: Symbol,
27 line: u32,
28 col: u32,
60c5eb7d
XL
29 ) -> MPlaceTy<'tcx, M::PointerTag> {
30 let file = self.allocate_str(&filename.as_str(), MemoryKind::CallerLocation);
e74abb32
XL
31 let line = Scalar::from_u32(line);
32 let col = Scalar::from_u32(col);
33
60c5eb7d 34 // Allocate memory for `CallerLocation` struct.
e74abb32
XL
35 let loc_ty = self.tcx.type_of(self.tcx.require_lang_item(PanicLocationLangItem, None))
36 .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_static.into()].iter()));
60c5eb7d
XL
37 let loc_layout = self.layout_of(loc_ty).unwrap();
38 let location = self.allocate(loc_layout, MemoryKind::CallerLocation);
39
40 // Initialize fields.
41 self.write_immediate(file.to_ref(), self.mplace_field(location, 0).unwrap().into())
42 .expect("writing to memory we just allocated cannot fail");
43 self.write_scalar(line, self.mplace_field(location, 1).unwrap().into())
44 .expect("writing to memory we just allocated cannot fail");
45 self.write_scalar(col, self.mplace_field(location, 2).unwrap().into())
46 .expect("writing to memory we just allocated cannot fail");
47
48 location
49 }
e74abb32 50
60c5eb7d
XL
51 pub fn alloc_caller_location_for_span(
52 &mut self,
53 span: Span,
54 ) -> MPlaceTy<'tcx, M::PointerTag> {
55 let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
56 let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
57 self.alloc_caller_location(
58 Symbol::intern(&caller.file.name.to_string()),
59 caller.line as u32,
60 caller.col_display as u32 + 1,
61 )
e74abb32
XL
62 }
63}