]> git.lizzy.rs Git - rust.git/blob - src/libcore/panic.rs
Move PanicInfo and Location to libcore
[rust.git] / src / libcore / panic.rs
1 // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Panic support in the standard library.
12
13 #![unstable(feature = "core_panic_info",
14             reason = "newly available in libcore",
15             issue = "44489")]
16
17 use any::Any;
18
19 /// A struct providing information about a panic.
20 ///
21 /// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`]
22 /// function.
23 ///
24 /// [`set_hook`]: ../../std/panic/fn.set_hook.html
25 ///
26 /// # Examples
27 ///
28 /// ```should_panic
29 /// use std::panic;
30 ///
31 /// panic::set_hook(Box::new(|panic_info| {
32 ///     println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap());
33 /// }));
34 ///
35 /// panic!("Normal panic");
36 /// ```
37 #[stable(feature = "panic_hooks", since = "1.10.0")]
38 #[derive(Debug)]
39 pub struct PanicInfo<'a> {
40     payload: &'a (Any + Send),
41     location: Location<'a>,
42 }
43
44 impl<'a> PanicInfo<'a> {
45     #![unstable(feature = "panic_internals",
46                 reason = "internal details of the implementation of the `panic!` \
47                           and related macros",
48                 issue = "0")]
49     #[doc(hidden)]
50     pub fn internal_constructor(payload: &'a (Any + Send), location: Location<'a>,) -> Self {
51         PanicInfo { payload, location }
52     }
53
54     /// Returns the payload associated with the panic.
55     ///
56     /// This will commonly, but not always, be a `&'static str` or [`String`].
57     ///
58     /// [`String`]: ../../std/string/struct.String.html
59     ///
60     /// # Examples
61     ///
62     /// ```should_panic
63     /// use std::panic;
64     ///
65     /// panic::set_hook(Box::new(|panic_info| {
66     ///     println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap());
67     /// }));
68     ///
69     /// panic!("Normal panic");
70     /// ```
71     #[stable(feature = "panic_hooks", since = "1.10.0")]
72     pub fn payload(&self) -> &(Any + Send) {
73         self.payload
74     }
75
76     /// Returns information about the location from which the panic originated,
77     /// if available.
78     ///
79     /// This method will currently always return [`Some`], but this may change
80     /// in future versions.
81     ///
82     /// [`Some`]: ../../std/option/enum.Option.html#variant.Some
83     ///
84     /// # Examples
85     ///
86     /// ```should_panic
87     /// use std::panic;
88     ///
89     /// panic::set_hook(Box::new(|panic_info| {
90     ///     if let Some(location) = panic_info.location() {
91     ///         println!("panic occurred in file '{}' at line {}", location.file(),
92     ///             location.line());
93     ///     } else {
94     ///         println!("panic occurred but can't get location information...");
95     ///     }
96     /// }));
97     ///
98     /// panic!("Normal panic");
99     /// ```
100     #[stable(feature = "panic_hooks", since = "1.10.0")]
101     pub fn location(&self) -> Option<&Location> {
102         // NOTE: If this is changed to sometimes return None,
103         // deal with that case in std::panicking::default_hook.
104         Some(&self.location)
105     }
106 }
107
108 /// A struct containing information about the location of a panic.
109 ///
110 /// This structure is created by the [`location`] method of [`PanicInfo`].
111 ///
112 /// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location
113 /// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html
114 ///
115 /// # Examples
116 ///
117 /// ```should_panic
118 /// use std::panic;
119 ///
120 /// panic::set_hook(Box::new(|panic_info| {
121 ///     if let Some(location) = panic_info.location() {
122 ///         println!("panic occurred in file '{}' at line {}", location.file(), location.line());
123 ///     } else {
124 ///         println!("panic occurred but can't get location information...");
125 ///     }
126 /// }));
127 ///
128 /// panic!("Normal panic");
129 /// ```
130 #[derive(Debug)]
131 #[stable(feature = "panic_hooks", since = "1.10.0")]
132 pub struct Location<'a> {
133     file: &'a str,
134     line: u32,
135     col: u32,
136 }
137
138 impl<'a> Location<'a> {
139     #![unstable(feature = "panic_internals",
140                 reason = "internal details of the implementation of the `panic!` \
141                           and related macros",
142                 issue = "0")]
143     #[doc(hidden)]
144     pub fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self {
145         Location { file, line, col }
146     }
147
148     /// Returns the name of the source file from which the panic originated.
149     ///
150     /// # Examples
151     ///
152     /// ```should_panic
153     /// use std::panic;
154     ///
155     /// panic::set_hook(Box::new(|panic_info| {
156     ///     if let Some(location) = panic_info.location() {
157     ///         println!("panic occurred in file '{}'", location.file());
158     ///     } else {
159     ///         println!("panic occurred but can't get location information...");
160     ///     }
161     /// }));
162     ///
163     /// panic!("Normal panic");
164     /// ```
165     #[stable(feature = "panic_hooks", since = "1.10.0")]
166     pub fn file(&self) -> &str {
167         self.file
168     }
169
170     /// Returns the line number from which the panic originated.
171     ///
172     /// # Examples
173     ///
174     /// ```should_panic
175     /// use std::panic;
176     ///
177     /// panic::set_hook(Box::new(|panic_info| {
178     ///     if let Some(location) = panic_info.location() {
179     ///         println!("panic occurred at line {}", location.line());
180     ///     } else {
181     ///         println!("panic occurred but can't get location information...");
182     ///     }
183     /// }));
184     ///
185     /// panic!("Normal panic");
186     /// ```
187     #[stable(feature = "panic_hooks", since = "1.10.0")]
188     pub fn line(&self) -> u32 {
189         self.line
190     }
191
192     /// Returns the column from which the panic originated.
193     ///
194     /// # Examples
195     ///
196     /// ```should_panic
197     /// use std::panic;
198     ///
199     /// panic::set_hook(Box::new(|panic_info| {
200     ///     if let Some(location) = panic_info.location() {
201     ///         println!("panic occurred at column {}", location.column());
202     ///     } else {
203     ///         println!("panic occurred but can't get location information...");
204     ///     }
205     /// }));
206     ///
207     /// panic!("Normal panic");
208     /// ```
209     #[stable(feature = "panic_col", since = "1.25")]
210     pub fn column(&self) -> u32 {
211         self.col
212     }
213 }