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

`}

`