Skip to content

Commit bc6e66e

Browse files
committed
Implement core::panic::Location::caller using #[track_caller].
1 parent ebaebd9 commit bc6e66e

File tree

5 files changed

+70
-15
lines changed

5 files changed

+70
-15
lines changed

src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
#![feature(staged_api)]
103103
#![feature(std_internals)]
104104
#![feature(stmt_expr_attributes)]
105+
#![cfg_attr(not(bootstrap), feature(track_caller))]
105106
#![feature(transparent_unions)]
106107
#![feature(unboxed_closures)]
107108
#![feature(unsized_locals)]

src/libcore/panic.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,60 @@ pub struct Location<'a> {
176176
col: u32,
177177
}
178178

179+
impl<'a> Location<'a> {
180+
/// Returns the source location of the caller of this function. If that function's caller is
181+
/// annotated then its call location will be returned, and so on up the stack to the first call
182+
/// within a non-tracked function body.
183+
///
184+
/// # Examples
185+
///
186+
/// ```
187+
/// #![feature(track_caller)]
188+
/// use core::panic::Location;
189+
///
190+
/// /// Returns the [`Location`] at which it is called.
191+
/// #[track_caller]
192+
/// fn get_caller_location() -> &'static Location<'static> {
193+
/// Location::caller()
194+
/// }
195+
///
196+
/// /// Returns a [`Location`] from within this function's definition.
197+
/// fn get_just_one_location() -> &'static Location<'static> {
198+
/// get_caller_location()
199+
/// }
200+
///
201+
/// let fixed_location = get_just_one_location();
202+
/// assert_eq!(fixed_location.file(), file!());
203+
/// assert_eq!(fixed_location.line(), 15);
204+
/// assert_eq!(fixed_location.column(), 5);
205+
///
206+
/// // running the same untracked function in a different location gives us the same result
207+
/// let second_fixed_location = get_just_one_location();
208+
/// assert_eq!(fixed_location.file(), second_fixed_location.file());
209+
/// assert_eq!(fixed_location.line(), second_fixed_location.line());
210+
/// assert_eq!(fixed_location.column(), second_fixed_location.column());
211+
///
212+
/// let this_location = get_caller_location();
213+
/// assert_eq!(this_location.file(), file!());
214+
/// assert_eq!(this_location.line(), 29);
215+
/// assert_eq!(this_location.column(), 21);
216+
///
217+
/// // running the tracked function in a different location produces a different value
218+
/// let another_location = get_caller_location();
219+
/// assert_eq!(this_location.file(), another_location.file());
220+
/// assert_ne!(this_location.line(), another_location.line());
221+
/// assert_ne!(this_location.column(), another_location.column());
222+
/// ```
223+
#[cfg(not(bootstrap))]
224+
#[unstable(feature = "track_caller",
225+
reason = "uses #[track_caller] which is not yet stable",
226+
issue = "47809")]
227+
#[track_caller]
228+
pub const fn caller() -> &'static Location<'static> {
229+
crate::intrinsics::caller_location()
230+
}
231+
}
232+
179233
impl<'a> Location<'a> {
180234
#![unstable(feature = "panic_internals",
181235
reason = "internal details of the implementation of the `panic!` \

src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
// run-pass
22

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

55
macro_rules! caller_location_from_macro {
6-
() => (core::intrinsics::caller_location());
6+
() => (core::panic::Location::caller());
77
}
88

99
fn main() {
10-
let loc = core::intrinsics::caller_location();
10+
let loc = core::panic::Location::caller();
1111
assert_eq!(loc.file(), file!());
1212
assert_eq!(loc.line(), 10);
1313
assert_eq!(loc.column(), 15);
1414

15-
// `caller_location()` in a macro should behave similarly to `file!` and `line!`,
15+
// `Location::caller()` in a macro should behave similarly to `file!` and `line!`,
1616
// i.e. point to where the macro was invoked, instead of the macro itself.
1717
let loc2 = caller_location_from_macro!();
1818
assert_eq!(loc2.file(), file!());

src/test/ui/rfc-2091-track-caller/const-caller-location.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
// run-pass
22

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

5-
use std::{intrinsics::caller_location, panic::Location};
5+
use std::panic::Location;
66

7-
const LOCATION: &Location = caller_location();
7+
const LOCATION: &Location = Location::caller();
88

99
const TRACKED: &Location = tracked();
1010
#[track_caller]
1111
const fn tracked() -> &'static Location <'static> {
12-
caller_location()
12+
Location::caller()
1313
}
1414

1515
const NESTED: &Location = nested_location();
1616
const fn nested_location() -> &'static Location<'static> {
17-
caller_location()
17+
Location::caller()
1818
}
1919

2020
const CONTAINED: &Location = contained();

src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
// run-pass
22

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

5-
use std::{intrinsics::caller_location, panic::Location};
5+
use std::panic::Location;
66

77
#[track_caller]
8-
fn tracked() -> &'static Location <'static> {
9-
caller_location()
8+
fn tracked() -> &'static Location<'static> {
9+
Location::caller()
1010
}
1111

1212
fn nested_intrinsic() -> &'static Location<'static> {
13-
caller_location()
13+
Location::caller()
1414
}
1515

1616
fn nested_tracked() -> &'static Location<'static> {
1717
tracked()
1818
}
1919

2020
fn main() {
21-
let location = caller_location();
21+
let location = Location::caller();
2222
assert_eq!(location.file(), file!());
2323
assert_eq!(location.line(), 21);
2424
assert_eq!(location.column(), 20);

0 commit comments

Comments
 (0)