about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdam Perry <adam.n.perry@gmail.com>2019-11-10 13:11:25 -0800
committerAdam Perry <adam.n.perry@gmail.com>2019-12-05 21:08:35 -0800
commitbc6e66eb3aa432f422bc61cdb6f0e9c61025a6d5 (patch)
tree254b04e97979c62d5725ce3e3f7d7816829bb627
parentebaebd987f38227fe17cdc3eb23be819e4070429 (diff)
downloadrust-bc6e66eb3aa432f422bc61cdb6f0e9c61025a6d5.tar.gz
rust-bc6e66eb3aa432f422bc61cdb6f0e9c61025a6d5.zip
Implement core::panic::Location::caller using #[track_caller].
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/panic.rs54
-rw-r--r--src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs8
-rw-r--r--src/test/ui/rfc-2091-track-caller/const-caller-location.rs10
-rw-r--r--src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs12
5 files changed, 70 insertions, 15 deletions
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 188ea1a9631..8a514f1e78e 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -102,6 +102,7 @@
 #![feature(staged_api)]
 #![feature(std_internals)]
 #![feature(stmt_expr_attributes)]
+#![cfg_attr(not(bootstrap), feature(track_caller))]
 #![feature(transparent_unions)]
 #![feature(unboxed_closures)]
 #![feature(unsized_locals)]
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> {
     #![unstable(feature = "panic_internals",
                 reason = "internal details of the implementation of the `panic!` \
                           and related macros",
diff --git a/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs b/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
index 1c4d4666fa1..76e62b89ab8 100644
--- a/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
+++ b/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
@@ -1,18 +1,18 @@
 // run-pass
 
-#![feature(core_intrinsics)]
+#![feature(track_caller)]
 
 macro_rules! caller_location_from_macro {
-    () => (core::intrinsics::caller_location());
+    () => (core::panic::Location::caller());
 }
 
 fn main() {
-    let loc = core::intrinsics::caller_location();
+    let loc = core::panic::Location::caller();
     assert_eq!(loc.file(), file!());
     assert_eq!(loc.line(), 10);
     assert_eq!(loc.column(), 15);
 
-    // `caller_location()` in a macro should behave similarly to `file!` and `line!`,
+    // `Location::caller()` in a macro should behave similarly to `file!` and `line!`,
     // i.e. point to where the macro was invoked, instead of the macro itself.
     let loc2 = caller_location_from_macro!();
     assert_eq!(loc2.file(), file!());
diff --git a/src/test/ui/rfc-2091-track-caller/const-caller-location.rs b/src/test/ui/rfc-2091-track-caller/const-caller-location.rs
index e36790505e8..0614c52c660 100644
--- a/src/test/ui/rfc-2091-track-caller/const-caller-location.rs
+++ b/src/test/ui/rfc-2091-track-caller/const-caller-location.rs
@@ -1,20 +1,20 @@
 // run-pass
 
-#![feature(const_fn, core_intrinsics, track_caller)]
+#![feature(const_fn, track_caller)]
 
-use std::{intrinsics::caller_location, panic::Location};
+use std::panic::Location;
 
-const LOCATION: &Location = caller_location();
+const LOCATION: &Location = Location::caller();
 
 const TRACKED: &Location = tracked();
 #[track_caller]
 const fn tracked() -> &'static Location <'static> {
-    caller_location()
+    Location::caller()
 }
 
 const NESTED: &Location = nested_location();
 const fn nested_location() -> &'static Location<'static> {
-    caller_location()
+    Location::caller()
 }
 
 const CONTAINED: &Location = contained();
diff --git a/src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs b/src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs
index 525c07e1c3a..8436ee510a5 100644
--- a/src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs
+++ b/src/test/ui/rfc-2091-track-caller/track-caller-attribute.rs
@@ -1,16 +1,16 @@
 // run-pass
 
-#![feature(const_fn, core_intrinsics, track_caller)]
+#![feature(const_fn, track_caller)]
 
-use std::{intrinsics::caller_location, panic::Location};
+use std::panic::Location;
 
 #[track_caller]
-fn tracked() -> &'static Location <'static> {
-    caller_location()
+fn tracked() -> &'static Location<'static> {
+    Location::caller()
 }
 
 fn nested_intrinsic() -> &'static Location<'static> {
-    caller_location()
+    Location::caller()
 }
 
 fn nested_tracked() -> &'static Location<'static> {
@@ -18,7 +18,7 @@ fn nested_tracked() -> &'static Location<'static> {
 }
 
 fn main() {
-    let location = caller_location();
+    let location = Location::caller();
     assert_eq!(location.file(), file!());
     assert_eq!(location.line(), 21);
     assert_eq!(location.column(), 20);