pub mod sync;
pub mod cell;
pub mod char;
+pub mod panic;
pub mod panicking;
pub mod iter;
pub mod option;
--- /dev/null
+// 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
+ }
+}
#![feature(on_unimplemented)]
#![feature(oom)]
#![feature(optin_builtin_traits)]
+#![feature(panic_internals)]
#![feature(panic_unwind)]
#![feature(peek)]
#![feature(placement_in_syntax)]
use thread::Result;
#[stable(feature = "panic_hooks", since = "1.10.0")]
-pub use panicking::{take_hook, set_hook, PanicInfo, Location};
+pub use panicking::{take_hook, set_hook};
+
+#[stable(feature = "panic_hooks", since = "1.10.0")]
+pub use core::panic::{PanicInfo, Location};
/// A marker trait which represents "panic safe" types in Rust.
///
use any::Any;
use cell::RefCell;
+use core::panic::{PanicInfo, Location};
use fmt;
use intrinsics;
use mem;
}
}
-/// 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> {
- /// 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> {
- 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> {
- /// 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
- }
-}
-
fn default_hook(info: &PanicInfo) {
#[cfg(feature = "backtrace")]
use sys_common::backtrace;
}
};
- let file = info.location.file;
- let line = info.location.line;
- let col = info.location.col;
+ let location = info.location().unwrap(); // The current implementation always returns Some
+ let file = location.file();
+ let line = location.line();
+ let col = location.column();
- let msg = match info.payload.downcast_ref::<&'static str>() {
+ let msg = match info.payload().downcast_ref::<&'static str>() {
Some(s) => *s,
- None => match info.payload.downcast_ref::<String>() {
+ None => match info.payload().downcast_ref::<String>() {
Some(s) => &s[..],
None => "Box<Any>",
}
}
unsafe {
- let info = PanicInfo {
- payload: &*msg,
- location: Location {
- file,
- line,
- col,
- },
- };
+ let info = PanicInfo::internal_constructor(
+ &*msg,
+ Location::internal_constructor(file, line, col),
+ );
HOOK_LOCK.read();
match HOOK {
Hook::Default => default_hook(&info),