]> git.proxmox.com Git - rustc.git/blame - library/core/src/panic/location.rs
New upstream version 1.62.1+dfsg1
[rustc.git] / library / core / src / panic / location.rs
CommitLineData
94222f64
XL
1use crate::fmt;
2
3/// A struct containing information about the location of a panic.
4///
5/// This structure is created by [`PanicInfo::location()`].
6///
7/// [`PanicInfo::location()`]: crate::panic::PanicInfo::location
8///
9/// # Examples
10///
11/// ```should_panic
12/// use std::panic;
13///
14/// panic::set_hook(Box::new(|panic_info| {
15/// if let Some(location) = panic_info.location() {
16/// println!("panic occurred in file '{}' at line {}", location.file(), location.line());
17/// } else {
18/// println!("panic occurred but can't get location information...");
19/// }
20/// }));
21///
22/// panic!("Normal panic");
23/// ```
24///
25/// # Comparisons
26///
27/// Comparisons for equality and ordering are made in file, line, then column priority.
28/// Files are compared as strings, not `Path`, which could be unexpected.
29/// See [`Location::file`]'s documentation for more discussion.
30#[lang = "panic_location"]
31#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
32#[stable(feature = "panic_hooks", since = "1.10.0")]
33pub struct Location<'a> {
34 file: &'a str,
35 line: u32,
36 col: u32,
37}
38
39impl<'a> Location<'a> {
40 /// Returns the source location of the caller of this function. If that function's caller is
41 /// annotated then its call location will be returned, and so on up the stack to the first call
42 /// within a non-tracked function body.
43 ///
44 /// # Examples
45 ///
46 /// ```
47 /// use std::panic::Location;
48 ///
49 /// /// Returns the [`Location`] at which it is called.
50 /// #[track_caller]
51 /// fn get_caller_location() -> &'static Location<'static> {
52 /// Location::caller()
53 /// }
54 ///
55 /// /// Returns a [`Location`] from within this function's definition.
56 /// fn get_just_one_location() -> &'static Location<'static> {
57 /// get_caller_location()
58 /// }
59 ///
60 /// let fixed_location = get_just_one_location();
61 /// assert_eq!(fixed_location.file(), file!());
62 /// assert_eq!(fixed_location.line(), 14);
63 /// assert_eq!(fixed_location.column(), 5);
64 ///
65 /// // running the same untracked function in a different location gives us the same result
66 /// let second_fixed_location = get_just_one_location();
67 /// assert_eq!(fixed_location.file(), second_fixed_location.file());
68 /// assert_eq!(fixed_location.line(), second_fixed_location.line());
69 /// assert_eq!(fixed_location.column(), second_fixed_location.column());
70 ///
71 /// let this_location = get_caller_location();
72 /// assert_eq!(this_location.file(), file!());
73 /// assert_eq!(this_location.line(), 28);
74 /// assert_eq!(this_location.column(), 21);
75 ///
76 /// // running the tracked function in a different location produces a different value
77 /// let another_location = get_caller_location();
78 /// assert_eq!(this_location.file(), another_location.file());
79 /// assert_ne!(this_location.line(), another_location.line());
80 /// assert_ne!(this_location.column(), another_location.column());
81 /// ```
3c0e092e 82 #[must_use]
94222f64
XL
83 #[stable(feature = "track_caller", since = "1.46.0")]
84 #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
85 #[track_caller]
5e7ed085 86 #[inline]
94222f64
XL
87 pub const fn caller() -> &'static Location<'static> {
88 crate::intrinsics::caller_location()
89 }
90
91 /// Returns the name of the source file from which the panic originated.
92 ///
93 /// # `&str`, not `&Path`
94 ///
95 /// The returned name refers to a source path on the compiling system, but it isn't valid to
96 /// represent this directly as a `&Path`. The compiled code may run on a different system with
97 /// a different `Path` implementation than the system providing the contents and this library
98 /// does not currently have a different "host path" type.
99 ///
100 /// The most surprising behavior occurs when "the same" file is reachable via multiple paths in
101 /// the module system (usually using the `#[path = "..."]` attribute or similar), which can
102 /// cause what appears to be identical code to return differing values from this function.
103 ///
104 /// # Cross-compilation
105 ///
106 /// This value is not suitable for passing to `Path::new` or similar constructors when the host
107 /// platform and target platform differ.
108 ///
109 /// # Examples
110 ///
111 /// ```should_panic
112 /// use std::panic;
113 ///
114 /// panic::set_hook(Box::new(|panic_info| {
115 /// if let Some(location) = panic_info.location() {
116 /// println!("panic occurred in file '{}'", location.file());
117 /// } else {
118 /// println!("panic occurred but can't get location information...");
119 /// }
120 /// }));
121 ///
122 /// panic!("Normal panic");
123 /// ```
3c0e092e 124 #[must_use]
94222f64 125 #[stable(feature = "panic_hooks", since = "1.10.0")]
04454e1e 126 #[inline]
94222f64
XL
127 pub fn file(&self) -> &str {
128 self.file
129 }
130
131 /// Returns the line number from which the panic originated.
132 ///
133 /// # Examples
134 ///
135 /// ```should_panic
136 /// use std::panic;
137 ///
138 /// panic::set_hook(Box::new(|panic_info| {
139 /// if let Some(location) = panic_info.location() {
140 /// println!("panic occurred at line {}", location.line());
141 /// } else {
142 /// println!("panic occurred but can't get location information...");
143 /// }
144 /// }));
145 ///
146 /// panic!("Normal panic");
147 /// ```
3c0e092e 148 #[must_use]
94222f64 149 #[stable(feature = "panic_hooks", since = "1.10.0")]
04454e1e 150 #[inline]
94222f64
XL
151 pub fn line(&self) -> u32 {
152 self.line
153 }
154
155 /// Returns the column from which the panic originated.
156 ///
157 /// # Examples
158 ///
159 /// ```should_panic
160 /// use std::panic;
161 ///
162 /// panic::set_hook(Box::new(|panic_info| {
163 /// if let Some(location) = panic_info.location() {
164 /// println!("panic occurred at column {}", location.column());
165 /// } else {
166 /// println!("panic occurred but can't get location information...");
167 /// }
168 /// }));
169 ///
170 /// panic!("Normal panic");
171 /// ```
3c0e092e 172 #[must_use]
94222f64 173 #[stable(feature = "panic_col", since = "1.25.0")]
04454e1e 174 #[inline]
94222f64
XL
175 pub fn column(&self) -> u32 {
176 self.col
177 }
178}
179
180#[unstable(
181 feature = "panic_internals",
182 reason = "internal details of the implementation of the `panic!` and related macros",
183 issue = "none"
184)]
185impl<'a> Location<'a> {
186 #[doc(hidden)]
187 pub const fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self {
188 Location { file, line, col }
189 }
190}
191
192#[stable(feature = "panic_hook_display", since = "1.26.0")]
193impl fmt::Display for Location<'_> {
194 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
195 write!(formatter, "{}:{}:{}", self.file, self.line, self.col)
196 }
197}