Skip to content

Commit 3d39b9c

Browse files
committed
WIP Support #[track_caller] on closures.Closes rust-lang#74042.
1 parent 7d31ffc commit 3d39b9c

File tree

4 files changed

+62
-7
lines changed

4 files changed

+62
-7
lines changed

src/librustc_codegen_ssa/mir/block.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
808808
let needs_location =
809809
instance.map_or(false, |i| i.def.requires_caller_location(self.cx.tcx()));
810810
if needs_location {
811-
assert_eq!(
812-
fn_abi.args.len(),
813-
args.len() + 1,
814-
"#[track_caller] fn's must have 1 more argument in their ABI than in their MIR",
815-
);
811+
// FIXME figure out the right number of args for closures
812+
// assert_eq!(
813+
// fn_abi.args.len(),
814+
// args.len() + 1,
815+
// "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR",
816+
// );
816817
let location = self.get_caller_location(&mut bx, fn_span);
817818
debug!(
818819
"codegen_call_terminator({:?}): location={:?} (fn_span {:?})",

src/librustc_passes/check_attr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ impl CheckAttrVisitor<'tcx> {
154154
.emit();
155155
false
156156
}
157-
Target::Fn | Target::Method(..) | Target::ForeignFn => true,
157+
Target::Closure | Target::Fn | Target::ForeignFn | Target::Method(..) => true,
158158
_ => {
159159
struct_span_err!(
160160
self.tcx.sess,

src/librustc_typeck/collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2413,7 +2413,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
24132413
} else if attr.check_name(sym::thread_local) {
24142414
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
24152415
} else if attr.check_name(sym::track_caller) {
2416-
if tcx.is_closure(id) || tcx.fn_sig(id).abi() != abi::Abi::Rust {
2416+
if !tcx.is_closure(id) && tcx.fn_sig(id).abi() != abi::Abi::Rust {
24172417
struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
24182418
.emit();
24192419
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// run-pass
2+
3+
#![feature(stmt_expr_attributes)]
4+
5+
use std::panic::Location;
6+
7+
#[track_caller]
8+
fn tracked() -> &'static Location<'static> {
9+
let get_location = #[track_caller] || Location::caller();
10+
get_location()
11+
}
12+
13+
fn untracked_wrapper() -> (&'static Location<'static>, u32) {
14+
let get_location = #[track_caller] || Location::caller();
15+
(get_location(), line!())
16+
}
17+
18+
fn nested_tracked() -> (&'static Location<'static>, u32) {
19+
(tracked(), line!())
20+
}
21+
22+
fn main() {
23+
let get_location = #[track_caller] || Location::caller();
24+
let (location, line) = (get_location(), line!());
25+
assert_eq!(location.file(), file!());
26+
assert_eq!(location.line(), line);
27+
28+
let (tracked, tracked_line) = (tracked(), line!());
29+
assert_eq!(tracked.file(), file!());
30+
assert_eq!(tracked.line(), tracked_line);
31+
32+
let (nested, nested_line) = untracked_wrapper();
33+
assert_eq!(nested.file(), file!());
34+
assert_eq!(nested.line(), nested_line);
35+
36+
let (contained, contained_line) = nested_tracked();
37+
assert_eq!(contained.file(), file!());
38+
assert_eq!(contained.line(), contained_line);
39+
40+
fn pass_to_ptr_call<T, R>(f: fn(T) -> R, x: T) -> R {
41+
f(x)
42+
}
43+
44+
let (get_location_w_n, line_from_shim) = (#[track_caller] |_| Location::caller(), line!());
45+
46+
let (location_with_arg, line_with_arg) = (get_location_w_n(3), line!());
47+
assert_eq!(location_with_arg.file(), file!());
48+
assert_eq!(location_with_arg.line(), line_with_arg);
49+
50+
let location_with_shim = pass_to_ptr_call(get_location_w_n, 5);
51+
// FIXME make the closure's "def site" point to this file
52+
assert_eq!(location_with_shim.file(), file!());
53+
assert_eq!(location_with_shim.line(), line_from_shim);
54+
}

0 commit comments

Comments
 (0)