]>
Commit | Line | Data |
---|---|---|
e74abb32 | 1 | use rustc::middle::lang_items::PanicLocationLangItem; |
e74abb32 | 2 | use rustc::ty::subst::Subst; |
60c5eb7d XL |
3 | use rustc_target::abi::LayoutOf; |
4 | use syntax_pos::{Symbol, Span}; | |
e74abb32 | 5 | |
60c5eb7d | 6 | use crate::interpret::{Scalar, MemoryKind, MPlaceTy, intrinsics::{InterpCx, Machine}}; |
e74abb32 XL |
7 | |
8 | impl<'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 | } |