Skip to content

Commit dec8113

Browse files
committed
Return raw ptr instead of &CStr
1 parent 20f4a9b commit dec8113

File tree

2 files changed

+15
-17
lines changed

2 files changed

+15
-17
lines changed

library/core/src/panic/location.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::ffi::CStr;
1+
use crate::ffi::c_char;
22
use crate::fmt;
33
use crate::marker::PhantomData;
44

@@ -36,7 +36,7 @@ use crate::marker::PhantomData;
3636
pub struct Location<'a> {
3737
// A raw pointer is used rather than a reference because the pointer is valid for one more byte
3838
// than the length stored in this pointer; the additional byte is the NUL-terminator used by
39-
// `Location::file_with_nul`.
39+
// `Location::file_ptr`.
4040
filename: *const str,
4141
line: u32,
4242
col: u32,
@@ -135,27 +135,22 @@ impl<'a> Location<'a> {
135135
#[stable(feature = "panic_hooks", since = "1.10.0")]
136136
#[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")]
137137
pub const fn file(&self) -> &str {
138-
// SAFETY: The filename is valid.
138+
// SAFETY: The compiler generates a pointer to a valid readable filename.
139139
unsafe { &*self.filename }
140140
}
141141

142-
/// Returns the name of the source file as a nul-terminated `CStr`.
142+
/// Returns the name of the source file as a nul-terminated string.
143143
///
144144
/// This is useful for interop with APIs that expect C/C++ `__FILE__` or
145145
/// `std::source_location::file_name`, both of which return a nul-terminated `const char*`.
146+
///
147+
/// The pointer is guaranteed to reference the same string as [`Location::file`] with an
148+
/// additional nul-byte at the end.
146149
#[must_use]
147150
#[unstable(feature = "file_with_nul", issue = "141727")]
148151
#[inline]
149-
pub const fn file_with_nul(&self) -> &CStr {
150-
// SAFETY: The filename is valid for `filename_len+1` bytes, so this addition can't
151-
// overflow.
152-
let cstr_len = unsafe { crate::mem::size_of_val_raw(self.filename).unchecked_add(1) };
153-
154-
// SAFETY: The filename is valid for `filename_len+1` bytes.
155-
let slice = unsafe { crate::slice::from_raw_parts(self.filename as *const _, cstr_len) };
156-
157-
// SAFETY: The filename is guaranteed to have a trailing nul byte and no interior nul bytes.
158-
unsafe { CStr::from_bytes_with_nul_unchecked(slice) }
152+
pub const fn file_ptr(&self) -> *const c_char {
153+
self.filename as *const c_char
159154
}
160155

161156
/// Returns the line number from which the panic originated.

tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
//@ run-pass
22
#![feature(file_with_nul)]
33

4+
use std::ffi::CStr;
5+
46
#[track_caller]
57
const fn assert_file_has_trailing_zero() {
68
let caller = core::panic::Location::caller();
79
let file_str = caller.file();
8-
let file_with_nul = caller.file_with_nul();
10+
let file_ptr = caller.file_ptr();
11+
let file_with_nul = unsafe { CStr::from_ptr(file_ptr) };
912
if file_str.len() != file_with_nul.count_bytes() {
1013
panic!("mismatched lengths");
1114
}
12-
let trailing_byte: core::ffi::c_char = unsafe {
13-
*file_with_nul.as_ptr().offset(file_with_nul.count_bytes() as _)
15+
let trailing_byte = unsafe {
16+
*file_ptr.add(file_with_nul.count_bytes())
1417
};
1518
if trailing_byte != 0 {
1619
panic!("trailing byte was nonzero")

0 commit comments

Comments
 (0)