diff options
| author | bors <bors@rust-lang.org> | 2025-06-05 10:21:20 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-06-05 10:21:20 +0000 |
| commit | c360e219f5a56631baa46065d28e9852ca7d4ce3 (patch) | |
| tree | 7193d135b42af795cea72addaba2df1de3ca1b15 /library | |
| parent | 425e142686242c7e73f5e32c79071ae266f0f355 (diff) | |
| parent | b541f93372c24bcbf036efc2b454cff6f6b8f8c5 (diff) | |
| download | rust-c360e219f5a56631baa46065d28e9852ca7d4ce3.tar.gz rust-c360e219f5a56631baa46065d28e9852ca7d4ce3.zip | |
Auto merge of #135054 - cramertj:file-cstr, r=m-ou-se
Add Location::file_with_nul This is useful for C/C++ APIs which expect the const char* returned from __FILE__ or std::source_location::file_name. ACP: https://github.com/rust-lang/libs-team/issues/466 Tracking issue: https://github.com/rust-lang/rust/issues/141727
Diffstat (limited to 'library')
| -rw-r--r-- | library/core/src/panic/location.rs | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs index 1ad5c07d15c..94cfd667ffa 100644 --- a/library/core/src/panic/location.rs +++ b/library/core/src/panic/location.rs @@ -1,3 +1,4 @@ +use crate::ffi::CStr; use crate::fmt; /// A struct containing information about the location of a panic. @@ -32,7 +33,12 @@ use crate::fmt; #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[stable(feature = "panic_hooks", since = "1.10.0")] pub struct Location<'a> { - file: &'a str, + // Note: this filename will have exactly one nul byte at its end, but otherwise + // it must never contain interior nul bytes. This is relied on for the conversion + // to `CStr` below. + // + // The prefix of the string without the trailing nul byte will be a regular UTF8 `str`. + file_bytes_with_nul: &'a [u8], line: u32, col: u32, } @@ -125,9 +131,24 @@ impl<'a> Location<'a> { #[must_use] #[stable(feature = "panic_hooks", since = "1.10.0")] #[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")] - #[inline] pub const fn file(&self) -> &str { - self.file + let str_len = self.file_bytes_with_nul.len() - 1; + // SAFETY: `file_bytes_with_nul` without the trailing nul byte is guaranteed to be + // valid UTF8. + unsafe { crate::str::from_raw_parts(self.file_bytes_with_nul.as_ptr(), str_len) } + } + + /// Returns the name of the source file as a nul-terminated `CStr`. + /// + /// This is useful for interop with APIs that expect C/C++ `__FILE__` or + /// `std::source_location::file_name`, both of which return a nul-terminated `const char*`. + #[must_use] + #[unstable(feature = "file_with_nul", issue = "141727")] + #[inline] + pub const fn file_with_nul(&self) -> &CStr { + // SAFETY: `file_bytes_with_nul` is guaranteed to have a trailing nul byte and no + // interior nul bytes. + unsafe { CStr::from_bytes_with_nul_unchecked(self.file_bytes_with_nul) } } /// Returns the line number from which the panic originated. @@ -181,22 +202,10 @@ impl<'a> Location<'a> { } } -#[unstable( - feature = "panic_internals", - reason = "internal details of the implementation of the `panic!` and related macros", - issue = "none" -)] -impl<'a> Location<'a> { - #[doc(hidden)] - pub const fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self { - Location { file, line, col } - } -} - #[stable(feature = "panic_hook_display", since = "1.26.0")] impl fmt::Display for Location<'_> { #[inline] fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "{}:{}:{}", self.file, self.line, self.col) + write!(formatter, "{}:{}:{}", self.file(), self.line, self.col) } } |
