Auto merge of #135054 - cramertj:file-cstr, r= · rust-lang/rust@35c365c (original) (raw)
``
1
`+
#[cfg(not(bootstrap))]
`
``
2
`+
use crate::ffi::CStr;
`
1
3
`use crate::fmt;
`
2
4
``
3
5
`/// A struct containing information about the location of a panic.
`
`@@ -32,7 +34,16 @@ use crate::fmt;
`
32
34
`#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
`
33
35
`#[stable(feature = "panic_hooks", since = "1.10.0")]
`
34
36
`pub struct Location<'a> {
`
``
37
`+
#[cfg(bootstrap)]
`
35
38
`file: &'a str,
`
``
39
+
``
40
`+
// Note: this filename will have exactly one nul byte at its end, but otherwise
`
``
41
`+
// it must never contain interior nul bytes. This is relied on for the conversion
`
``
42
`` +
// to CStr
below.
``
``
43
`+
//
`
``
44
`` +
// The prefix of the string without the trailing nul byte will be a regular UTF8 str
.
``
``
45
`+
#[cfg(not(bootstrap))]
`
``
46
`+
file_bytes_with_nul: &'a [u8],
`
36
47
`line: u32,
`
37
48
`col: u32,
`
38
49
`}
`
`@@ -125,9 +136,33 @@ impl<'a> Location<'a> {
`
125
136
`#[must_use]
`
126
137
`#[stable(feature = "panic_hooks", since = "1.10.0")]
`
127
138
`#[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")]
`
128
``
`-
#[inline]
`
129
139
`pub const fn file(&self) -> &str {
`
130
``
`-
self.file
`
``
140
`+
#[cfg(bootstrap)]
`
``
141
`+
{
`
``
142
`+
self.file
`
``
143
`+
}
`
``
144
+
``
145
`+
#[cfg(not(bootstrap))]
`
``
146
`+
{
`
``
147
`+
let str_len = self.file_bytes_with_nul.len() - 1;
`
``
148
`` +
// SAFETY: file_bytes_with_nul
without the trailing nul byte is guaranteed to be
``
``
149
`+
// valid UTF8.
`
``
150
`+
unsafe { crate::str::from_raw_parts(self.file_bytes_with_nul.as_ptr(), str_len) }
`
``
151
`+
}
`
``
152
`+
}
`
``
153
+
``
154
`` +
/// Returns the name of the source file as a nul-terminated CStr
.
``
``
155
`+
///
`
``
156
`` +
/// This is useful for interop with APIs that expect C/C++ __FILE__
or
``
``
157
`` +
/// std::source_location::file_name
, both of which return a nul-terminated const char*
.
``
``
158
`+
#[cfg(not(bootstrap))]
`
``
159
`+
#[must_use]
`
``
160
`+
#[unstable(feature = "file_with_nul", issue = "none")]
`
``
161
`+
#[inline]
`
``
162
`+
pub const fn file_with_nul(&self) -> &CStr {
`
``
163
`` +
// SAFETY: file_bytes_with_nul
is guaranteed to have a trailing nul byte and no
``
``
164
`+
// interior nul bytes.
`
``
165
`+
unsafe { CStr::from_bytes_with_nul_unchecked(self.file_bytes_with_nul) }
`
131
166
`}
`
132
167
``
133
168
`/// Returns the line number from which the panic originated.
`
`@@ -181,22 +216,10 @@ impl<'a> Location<'a> {
`
181
216
`}
`
182
217
`}
`
183
218
``
184
``
`-
#[unstable(
`
185
``
`-
feature = "panic_internals",
`
186
``
`` -
reason = "internal details of the implementation of the panic!
and related macros",
``
187
``
`-
issue = "none"
`
188
``
`-
)]
`
189
``
`-
impl<'a> Location<'a> {
`
190
``
`-
#[doc(hidden)]
`
191
``
`-
pub const fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self {
`
192
``
`-
Location { file, line, col }
`
193
``
`-
}
`
194
``
`-
}
`
195
``
-
196
219
`#[stable(feature = "panic_hook_display", since = "1.26.0")]
`
197
220
`impl fmt::Display for Location<'_> {
`
198
221
`#[inline]
`
199
222
`fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
`
200
``
`-
write!(formatter, "{}:{}:{}", self.file, self.line, self.col)
`
``
223
`+
write!(formatter, "{}:{}:{}", self.file(), self.line, self.col)
`
201
224
`}
`
202
225
`}
`