Skip to content

Commit 9ab065d

Browse files
committed
Implement #[track_caller] in const.
1 parent 234c9f2 commit 9ab065d

File tree

5 files changed

+63
-13
lines changed

5 files changed

+63
-13
lines changed

src/librustc/ty/instance.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ impl<'tcx> InstanceDef<'tcx> {
116116
}
117117
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
118118
}
119+
120+
pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
121+
tcx.codegen_fn_attrs(self.def_id()).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
122+
}
119123
}
120124

121125
impl<'tcx> fmt::Display for Instance<'tcx> {
@@ -255,11 +259,8 @@ impl<'tcx> Instance<'tcx> {
255259
) -> Option<Instance<'tcx>> {
256260
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
257261
Instance::resolve(tcx, param_env, def_id, substs).map(|mut resolved| {
258-
let has_track_caller = |def| tcx.codegen_fn_attrs(def).flags
259-
.contains(CodegenFnAttrFlags::TRACK_CALLER);
260-
261262
match resolved.def {
262-
InstanceDef::Item(def_id) if has_track_caller(def_id) => {
263+
InstanceDef::Item(def_id) if resolved.def.requires_caller_location(tcx) => {
263264
debug!(" => fn pointer created for function with #[track_caller]");
264265
resolved.def = InstanceDef::ReifyShim(def_id);
265266
}

src/librustc_mir/interpret/intrinsics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
112112
// `src/librustc/ty/constness.rs`
113113
match intrinsic_name {
114114
sym::caller_location => {
115+
let span = self.find_closest_untracked_caller_location(span);
115116
let location = self.alloc_caller_location_for_span(span);
116117
self.write_scalar(location.ptr, dest)?;
117118
}

src/librustc_mir/interpret/intrinsics/caller_location.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,28 @@ use syntax_pos::{Symbol, Span};
66
use crate::interpret::{Scalar, MemoryKind, MPlaceTy, intrinsics::{InterpCx, Machine}};
77

88
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9+
/// Walks up the callstack from the intrinsic's callsite, searching for the first frame which is
10+
/// not `#[track_caller]`. Returns the (passed) span of the intrinsic's callsite if the first
11+
/// frame in the stack is untracked so that we can display the callsite of the intrinsic within
12+
/// that function.
13+
crate fn find_closest_untracked_caller_location(
14+
&self,
15+
intrinsic_loc: Span,
16+
) -> Span {
17+
debug!("finding closest untracked caller relative to {:?}", intrinsic_loc);
18+
19+
let mut caller_span = intrinsic_loc;
20+
for next_caller in self.stack.iter().rev() {
21+
if !next_caller.instance.def.requires_caller_location(*self.tcx) {
22+
return caller_span;
23+
}
24+
caller_span = next_caller.span;
25+
}
26+
27+
intrinsic_loc
28+
}
29+
30+
/// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
931
crate fn alloc_caller_location(
1032
&mut self,
1133
filename: Symbol,
Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,41 @@
11
// run-pass
22

3-
#![feature(const_fn, core_intrinsics)]
3+
#![feature(const_fn, core_intrinsics, track_caller)]
44

55
use std::{intrinsics::caller_location, panic::Location};
66

77
const LOCATION: &Location = caller_location();
8-
const NESTED: &Location = {
9-
const fn nested_location() -> &'static Location<'static> {
10-
caller_location()
11-
};
12-
nested_location()
13-
};
8+
9+
const TRACKED: &Location = tracked();
10+
#[track_caller]
11+
const fn tracked() -> &'static Location <'static> {
12+
caller_location()
13+
}
14+
15+
const NESTED: &Location = nested_location();
16+
const fn nested_location() -> &'static Location<'static> {
17+
caller_location()
18+
}
19+
20+
const CONTAINED: &Location = contained();
21+
const fn contained() -> &'static Location<'static> {
22+
tracked()
23+
}
1424

1525
fn main() {
1626
assert_eq!(LOCATION.file(), file!());
1727
assert_eq!(LOCATION.line(), 7);
1828
assert_eq!(LOCATION.column(), 29);
1929

30+
assert_eq!(TRACKED.file(), file!());
31+
assert_eq!(TRACKED.line(), 9);
32+
assert_eq!(TRACKED.column(), 28);
33+
2034
assert_eq!(NESTED.file(), file!());
21-
assert_eq!(NESTED.line(), 10);
22-
assert_eq!(NESTED.column(), 9);
35+
assert_eq!(NESTED.line(), 17);
36+
assert_eq!(NESTED.column(), 5);
37+
38+
assert_eq!(CONTAINED.file(), file!());
39+
assert_eq!(CONTAINED.line(), 22);
40+
assert_eq!(CONTAINED.column(), 5);
2341
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
2+
--> $DIR/const_caller_location.rs:3:39
3+
|
4+
LL | #![feature(const_fn, core_intrinsics, track_caller)]
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+

0 commit comments

Comments
 (0)