about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2018-01-23 16:31:53 +0100
committerSimon Sapin <simon.sapin@exyr.org>2018-01-23 16:38:26 +0100
commit2f98f4b12b8fd5d93ffff3d7b98931b3f1f2b07a (patch)
treea6aad25ef4ae1b91c9ff51df6033959f87426788 /src/libcore
parent48a7ea9c4095e3218df39832dfc51a456534ecc9 (diff)
downloadrust-2f98f4b12b8fd5d93ffff3d7b98931b3f1f2b07a.tar.gz
rust-2f98f4b12b8fd5d93ffff3d7b98931b3f1f2b07a.zip
Move PanicInfo and Location to libcore
Per https://rust-lang.github.io/rfcs/2070-panic-implementation.html
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/panic.rs213
2 files changed, 214 insertions, 0 deletions
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index d5190b65863..11476a05dd3 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -158,6 +158,7 @@ pub mod array;
 pub mod sync;
 pub mod cell;
 pub mod char;
+pub mod panic;
 pub mod panicking;
 pub mod iter;
 pub mod option;
diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs
new file mode 100644
index 00000000000..dbfe531063b
--- /dev/null
+++ b/src/libcore/panic.rs
@@ -0,0 +1,213 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Panic support in the standard library.
+
+#![unstable(feature = "core_panic_info",
+            reason = "newly available in libcore",
+            issue = "44489")]
+
+use any::Any;
+
+/// A struct providing information about a panic.
+///
+/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`]
+/// function.
+///
+/// [`set_hook`]: ../../std/panic/fn.set_hook.html
+///
+/// # Examples
+///
+/// ```should_panic
+/// use std::panic;
+///
+/// panic::set_hook(Box::new(|panic_info| {
+///     println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap());
+/// }));
+///
+/// panic!("Normal panic");
+/// ```
+#[stable(feature = "panic_hooks", since = "1.10.0")]
+#[derive(Debug)]
+pub struct PanicInfo<'a> {
+    payload: &'a (Any + Send),
+    location: Location<'a>,
+}
+
+impl<'a> PanicInfo<'a> {
+    #![unstable(feature = "panic_internals",
+                reason = "internal details of the implementation of the `panic!` \
+                          and related macros",
+                issue = "0")]
+    #[doc(hidden)]
+    pub fn internal_constructor(payload: &'a (Any + Send), location: Location<'a>,) -> Self {
+        PanicInfo { payload, location }
+    }
+
+    /// Returns the payload associated with the panic.
+    ///
+    /// This will commonly, but not always, be a `&'static str` or [`String`].
+    ///
+    /// [`String`]: ../../std/string/struct.String.html
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap());
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
+    pub fn payload(&self) -> &(Any + Send) {
+        self.payload
+    }
+
+    /// Returns information about the location from which the panic originated,
+    /// if available.
+    ///
+    /// This method will currently always return [`Some`], but this may change
+    /// in future versions.
+    ///
+    /// [`Some`]: ../../std/option/enum.Option.html#variant.Some
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     if let Some(location) = panic_info.location() {
+    ///         println!("panic occurred in file '{}' at line {}", location.file(),
+    ///             location.line());
+    ///     } else {
+    ///         println!("panic occurred but can't get location information...");
+    ///     }
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
+    pub fn location(&self) -> Option<&Location> {
+        // NOTE: If this is changed to sometimes return None,
+        // deal with that case in std::panicking::default_hook.
+        Some(&self.location)
+    }
+}
+
+/// A struct containing information about the location of a panic.
+///
+/// This structure is created by the [`location`] method of [`PanicInfo`].
+///
+/// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location
+/// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html
+///
+/// # Examples
+///
+/// ```should_panic
+/// use std::panic;
+///
+/// panic::set_hook(Box::new(|panic_info| {
+///     if let Some(location) = panic_info.location() {
+///         println!("panic occurred in file '{}' at line {}", location.file(), location.line());
+///     } else {
+///         println!("panic occurred but can't get location information...");
+///     }
+/// }));
+///
+/// panic!("Normal panic");
+/// ```
+#[derive(Debug)]
+#[stable(feature = "panic_hooks", since = "1.10.0")]
+pub struct Location<'a> {
+    file: &'a str,
+    line: u32,
+    col: u32,
+}
+
+impl<'a> Location<'a> {
+    #![unstable(feature = "panic_internals",
+                reason = "internal details of the implementation of the `panic!` \
+                          and related macros",
+                issue = "0")]
+    #[doc(hidden)]
+    pub fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self {
+        Location { file, line, col }
+    }
+
+    /// Returns the name of the source file from which the panic originated.
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     if let Some(location) = panic_info.location() {
+    ///         println!("panic occurred in file '{}'", location.file());
+    ///     } else {
+    ///         println!("panic occurred but can't get location information...");
+    ///     }
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
+    pub fn file(&self) -> &str {
+        self.file
+    }
+
+    /// Returns the line number from which the panic originated.
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     if let Some(location) = panic_info.location() {
+    ///         println!("panic occurred at line {}", location.line());
+    ///     } else {
+    ///         println!("panic occurred but can't get location information...");
+    ///     }
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
+    pub fn line(&self) -> u32 {
+        self.line
+    }
+
+    /// Returns the column from which the panic originated.
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     if let Some(location) = panic_info.location() {
+    ///         println!("panic occurred at column {}", location.column());
+    ///     } else {
+    ///         println!("panic occurred but can't get location information...");
+    ///     }
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_col", since = "1.25")]
+    pub fn column(&self) -> u32 {
+        self.col
+    }
+}