diff options
| author | bors <bors@rust-lang.org> | 2019-12-07 21:14:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-12-07 21:14:39 +0000 |
| commit | de17464b14e503edca6625daa9cd4c338ffafee2 (patch) | |
| tree | 88969c0d7bbddc53c7fa798ae477efad19f2147c /src/libcore/panic.rs | |
| parent | 5c5c8eb864e56ce905742b8e97df5506bba6aeef (diff) | |
| parent | 15d1f7cffdc0b111123a6d34a356eae95af04676 (diff) | |
| download | rust-de17464b14e503edca6625daa9cd4c338ffafee2.tar.gz rust-de17464b14e503edca6625daa9cd4c338ffafee2.zip | |
Auto merge of #65881 - anp:implicit-caller-location, r=eddyb,oli-obk
Implement #[track_caller] attribute. (RFC 2091 4/N) Implements the `#[track_caller]` attribute in both const and codegen contexts. The const implementation walks up the stack to find the nearest untracked callsite. The codegen implementation adds an implicit argument to tracked function calls, and populates it with either a call to the previously-landed intrinsic or if the caller has `#[track_caller]` with a copy of the location passed to the current function. Also includes a little cleanup and a few comments in the other caller location areas. [Depends on: 65664](https://github.com/rust-lang/rust/pull/65664) [RFC 2091 text](https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md) [Tracking issue](https://github.com/rust-lang/rust/issues/47809) [Tracking doc](https://paper.dropbox.com/doc/track_rfc_2091_impl-notes--Anf1NwnIb0xcRv31YLIadyj0Ag-rwCdRc2fi2yvRZ7syGZ9q#:uid=863513134494965680023183&h2=TODO-actually-pass-location-to)
Diffstat (limited to 'src/libcore/panic.rs')
| -rw-r--r-- | src/libcore/panic.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index 99b372d92c8..e924ee20369 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -177,6 +177,60 @@ pub struct Location<'a> { } impl<'a> Location<'a> { + /// Returns the source location of the caller of this function. If that function's caller is + /// annotated then its call location will be returned, and so on up the stack to the first call + /// within a non-tracked function body. + /// + /// # Examples + /// + /// ``` + /// #![feature(track_caller)] + /// use core::panic::Location; + /// + /// /// Returns the [`Location`] at which it is called. + /// #[track_caller] + /// fn get_caller_location() -> &'static Location<'static> { + /// Location::caller() + /// } + /// + /// /// Returns a [`Location`] from within this function's definition. + /// fn get_just_one_location() -> &'static Location<'static> { + /// get_caller_location() + /// } + /// + /// let fixed_location = get_just_one_location(); + /// assert_eq!(fixed_location.file(), file!()); + /// assert_eq!(fixed_location.line(), 15); + /// assert_eq!(fixed_location.column(), 5); + /// + /// // running the same untracked function in a different location gives us the same result + /// let second_fixed_location = get_just_one_location(); + /// assert_eq!(fixed_location.file(), second_fixed_location.file()); + /// assert_eq!(fixed_location.line(), second_fixed_location.line()); + /// assert_eq!(fixed_location.column(), second_fixed_location.column()); + /// + /// let this_location = get_caller_location(); + /// assert_eq!(this_location.file(), file!()); + /// assert_eq!(this_location.line(), 29); + /// assert_eq!(this_location.column(), 21); + /// + /// // running the tracked function in a different location produces a different value + /// let another_location = get_caller_location(); + /// assert_eq!(this_location.file(), another_location.file()); + /// assert_ne!(this_location.line(), another_location.line()); + /// assert_ne!(this_location.column(), another_location.column()); + /// ``` + #[cfg(not(bootstrap))] + #[unstable(feature = "track_caller", + reason = "uses #[track_caller] which is not yet stable", + issue = "47809")] + #[track_caller] + pub const fn caller() -> &'static Location<'static> { + crate::intrinsics::caller_location() + } +} + +impl<'a> Location<'a> { #