1 #![feature(core_intrinsics)]
3 use std::panic::Location;
6 fn tracked() -> &'static Location<'static> {
7 Location::caller() // most importantly, we never get line 7
10 fn nested_intrinsic() -> &'static Location<'static> {
14 fn nested_tracked() -> &'static Location<'static> {
18 macro_rules! caller_location_from_macro {
20 core::panic::Location::caller()
25 fn pass_to_ptr_call<T>(f: fn(T), x: T) {
30 fn tracked_unit(_: ()) {
31 let expected_line = line!() - 1;
32 let location = std::panic::Location::caller();
33 assert_eq!(location.file(), file!());
34 assert_eq!(location.line(), expected_line, "call shims report location as fn definition");
37 pass_to_ptr_call(tracked_unit, ());
43 fn handle(&self) -> &'static Location<'static> {
44 std::panic::Location::caller()
48 impl Tracked for () {}
49 impl Tracked for u8 {}
51 // Test that we get the correct location
52 // even with a call through a trait object
54 let tracked: &dyn Tracked = &5u8;
55 let location = tracked.handle();
56 let expected_line = line!() - 1;
57 assert_eq!(location.file(), file!());
58 assert_eq!(location.line(), expected_line);
59 assert_eq!(location.column(), 28);
61 const TRACKED: &dyn Tracked = &();
62 let location = TRACKED.handle();
63 let expected_line = line!() - 1;
64 assert_eq!(location.file(), file!());
65 assert_eq!(location.line(), expected_line);
66 assert_eq!(location.column(), 28);
69 fn test_trait_obj2() {
70 // track_caller on the impl but not the trait.
72 fn foo(&self) -> &'static Location<'static>;
78 fn foo(&self) -> &'static Location<'static> {
79 std::panic::Location::caller()
82 let expected_line = line!() - 4; // the `fn` signature above
84 let f = &Bar as &dyn Foo;
85 let loc = f.foo(); // trait doesn't track, so we don't point at this call site
86 assert_eq!(loc.file(), file!());
87 assert_eq!(loc.line(), expected_line);
91 let location = Location::caller();
92 let expected_line = line!() - 1;
93 assert_eq!(location.file(), file!());
94 assert_eq!(location.line(), expected_line);
95 assert_eq!(location.column(), 20);
97 let tracked = tracked();
98 let expected_line = line!() - 1;
99 assert_eq!(tracked.file(), file!());
100 assert_eq!(tracked.line(), expected_line);
101 assert_eq!(tracked.column(), 19);
103 let nested = nested_intrinsic();
104 assert_eq!(nested.file(), file!());
105 assert_eq!(nested.line(), 11);
106 assert_eq!(nested.column(), 5);
108 let contained = nested_tracked();
109 assert_eq!(contained.file(), file!());
110 assert_eq!(contained.line(), 15);
111 assert_eq!(contained.column(), 5);
113 // `Location::caller()` in a macro should behave similarly to `file!` and `line!`,
114 // i.e. point to where the macro was invoked, instead of the macro itself.
115 let inmacro = caller_location_from_macro!();
116 let expected_line = line!() - 1;
117 assert_eq!(inmacro.file(), file!());
118 assert_eq!(inmacro.line(), expected_line);
119 assert_eq!(inmacro.column(), 19);
121 let intrinsic = core::intrinsics::caller_location();
122 let expected_line = line!() - 1;
123 assert_eq!(intrinsic.file(), file!());
124 assert_eq!(intrinsic.line(), expected_line);
125 assert_eq!(intrinsic.column(), 21);