Skip to content

Commit c17f89d

Browse files
committed
caller_location: point to macro invocation sites, like file!/line!.
1 parent 0b7e28a commit c17f89d

File tree

5 files changed

+36
-16
lines changed

5 files changed

+36
-16
lines changed

src/librustc_codegen_ssa/mir/block.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
995995
bx: &mut Bx,
996996
span: Span,
997997
) -> OperandRef<'tcx, Bx::Value> {
998-
let caller = bx.tcx().sess.source_map().lookup_char_pos(span.lo());
998+
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
999+
let caller = bx.tcx().sess.source_map().lookup_char_pos(topmost.lo());
9991000
let const_loc = bx.tcx().const_caller_location((
10001001
Symbol::intern(&caller.file.name.to_string()),
10011002
caller.line as u32,

src/librustc_mir/interpret/intrinsics.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9898
let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..];
9999
match intrinsic_name {
100100
"caller_location" => {
101-
let caller = self.tcx.sess.source_map().lookup_char_pos(span.lo());
101+
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
102+
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
102103
let location = self.alloc_caller_location(
103104
Symbol::intern(&caller.file.name.to_string()),
104105
caller.line as u32,

src/libsyntax_expand/base.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -954,18 +954,7 @@ impl<'a> ExtCtxt<'a> {
954954
///
955955
/// Stops backtracing at include! boundary.
956956
pub fn expansion_cause(&self) -> Option<Span> {
957-
let mut expn_id = self.current_expansion.id;
958-
let mut last_macro = None;
959-
loop {
960-
let expn_data = expn_id.expn_data();
961-
// Stop going up the backtrace once include! is encountered
962-
if expn_data.is_root() || expn_data.kind.descr() == sym::include {
963-
break;
964-
}
965-
expn_id = expn_data.call_site.ctxt().outer_expn();
966-
last_macro = Some(expn_data.call_site);
967-
}
968-
last_macro
957+
self.current_expansion.id.expansion_cause()
969958
}
970959

971960
pub fn struct_span_warn<S: Into<MultiSpan>>(&self,

src/libsyntax_pos/hygiene.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
use crate::GLOBALS;
2929
use crate::{Span, DUMMY_SP};
3030
use crate::edition::Edition;
31-
use crate::symbol::{kw, Symbol};
31+
use crate::symbol::{kw, sym, Symbol};
3232

3333
use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
3434
use rustc_data_structures::fx::FxHashMap;
@@ -119,6 +119,23 @@ impl ExpnId {
119119
pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
120120
HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt)))
121121
}
122+
123+
/// Returns span for the macro which originally caused this expansion to happen.
124+
///
125+
/// Stops backtracing at include! boundary.
126+
pub fn expansion_cause(mut self) -> Option<Span> {
127+
let mut last_macro = None;
128+
loop {
129+
let expn_data = self.expn_data();
130+
// Stop going up the backtrace once include! is encountered
131+
if expn_data.is_root() || expn_data.kind.descr() == sym::include {
132+
break;
133+
}
134+
self = expn_data.call_site.ctxt().outer_expn();
135+
last_macro = Some(expn_data.call_site);
136+
}
137+
last_macro
138+
}
122139
}
123140

124141
#[derive(Debug)]
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
// run-pass
22

33
#![feature(core_intrinsics)]
4+
5+
macro_rules! caller_location_from_macro {
6+
() => (core::intrinsics::caller_location());
7+
}
8+
49
fn main() {
510
let loc = core::intrinsics::caller_location();
611
assert_eq!(loc.file(), file!());
7-
assert_eq!(loc.line(), 5);
12+
assert_eq!(loc.line(), 10);
813
assert_eq!(loc.column(), 15);
14+
15+
// `caller_location()` in a macro should behave similarly to `file!` and `line!`,
16+
// i.e. point to where the macro was invoked, instead of the macro itself.
17+
let loc2 = caller_location_from_macro!();
18+
assert_eq!(loc2.file(), file!());
19+
assert_eq!(loc2.line(), 17);
20+
assert_eq!(loc2.column(), 16);
921
}

0 commit comments

Comments
 (0)