Skip to content

Commit 55f76d3

Browse files
committed
Return raw ptr instead of &CStr
1 parent cfed78e commit 55f76d3

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,
@@ -132,27 +132,22 @@ impl<'a> Location<'a> {
132132
#[stable(feature = "panic_hooks", since = "1.10.0")]
133133
#[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")]
134134
pub const fn file(&self) -> &str {
135-
// SAFETY: The filename is valid.
135+
// SAFETY: The compiler generates a pointer to a valid readable filename.
136136
unsafe { &*self.filename }
137137
}
138138

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

158153
/// 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)