caller_location: point to macro invocation sites, like file!/line!.
This commit is contained in:
parent
0b7e28a161
commit
c17f89d6ed
@ -995,7 +995,8 @@ fn get_caller_location(
|
||||
bx: &mut Bx,
|
||||
span: Span,
|
||||
) -> OperandRef<'tcx, Bx::Value> {
|
||||
let caller = bx.tcx().sess.source_map().lookup_char_pos(span.lo());
|
||||
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
|
||||
let caller = bx.tcx().sess.source_map().lookup_char_pos(topmost.lo());
|
||||
let const_loc = bx.tcx().const_caller_location((
|
||||
Symbol::intern(&caller.file.name.to_string()),
|
||||
caller.line as u32,
|
||||
|
@ -98,7 +98,8 @@ pub fn emulate_intrinsic(
|
||||
let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..];
|
||||
match intrinsic_name {
|
||||
"caller_location" => {
|
||||
let caller = self.tcx.sess.source_map().lookup_char_pos(span.lo());
|
||||
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
|
||||
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
|
||||
let location = self.alloc_caller_location(
|
||||
Symbol::intern(&caller.file.name.to_string()),
|
||||
caller.line as u32,
|
||||
|
@ -954,18 +954,7 @@ pub fn with_mixed_site_ctxt(&self, span: Span) -> Span {
|
||||
///
|
||||
/// Stops backtracing at include! boundary.
|
||||
pub fn expansion_cause(&self) -> Option<Span> {
|
||||
let mut expn_id = self.current_expansion.id;
|
||||
let mut last_macro = None;
|
||||
loop {
|
||||
let expn_data = expn_id.expn_data();
|
||||
// Stop going up the backtrace once include! is encountered
|
||||
if expn_data.is_root() || expn_data.kind.descr() == sym::include {
|
||||
break;
|
||||
}
|
||||
expn_id = expn_data.call_site.ctxt().outer_expn();
|
||||
last_macro = Some(expn_data.call_site);
|
||||
}
|
||||
last_macro
|
||||
self.current_expansion.id.expansion_cause()
|
||||
}
|
||||
|
||||
pub fn struct_span_warn<S: Into<MultiSpan>>(&self,
|
||||
|
@ -28,7 +28,7 @@
|
||||
use crate::GLOBALS;
|
||||
use crate::{Span, DUMMY_SP};
|
||||
use crate::edition::Edition;
|
||||
use crate::symbol::{kw, Symbol};
|
||||
use crate::symbol::{kw, sym, Symbol};
|
||||
|
||||
use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
@ -119,6 +119,23 @@ pub fn is_descendant_of(self, ancestor: ExpnId) -> bool {
|
||||
pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
|
||||
HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt)))
|
||||
}
|
||||
|
||||
/// Returns span for the macro which originally caused this expansion to happen.
|
||||
///
|
||||
/// Stops backtracing at include! boundary.
|
||||
pub fn expansion_cause(mut self) -> Option<Span> {
|
||||
let mut last_macro = None;
|
||||
loop {
|
||||
let expn_data = self.expn_data();
|
||||
// Stop going up the backtrace once include! is encountered
|
||||
if expn_data.is_root() || expn_data.kind.descr() == sym::include {
|
||||
break;
|
||||
}
|
||||
self = expn_data.call_site.ctxt().outer_expn();
|
||||
last_macro = Some(expn_data.call_site);
|
||||
}
|
||||
last_macro
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -1,9 +1,21 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
macro_rules! caller_location_from_macro {
|
||||
() => (core::intrinsics::caller_location());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let loc = core::intrinsics::caller_location();
|
||||
assert_eq!(loc.file(), file!());
|
||||
assert_eq!(loc.line(), 5);
|
||||
assert_eq!(loc.line(), 10);
|
||||
assert_eq!(loc.column(), 15);
|
||||
|
||||
// `caller_location()` in a macro should behave similarly to `file!` and `line!`,
|
||||
// i.e. point to where the macro was invoked, instead of the macro itself.
|
||||
let loc2 = caller_location_from_macro!();
|
||||
assert_eq!(loc2.file(), file!());
|
||||
assert_eq!(loc2.line(), 17);
|
||||
assert_eq!(loc2.column(), 16);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user