Skip to content

Commit 8f7bc81

Browse files
authored
Unrolled build for rust-lang#124593
Rollup merge of rust-lang#124593 - GKFX:cstr-literals-in-api-docs, r=workingjubilee Describe and use CStr literals in CStr and CString docs Mention CStr literals in the description of both types, and use them in some of the code samples for CStr. This is intended to make C string literals more discoverable. Additionally, I don't think the orange "This example is not tested" warnings are very encouraging, so I have made the examples on `CStr` build.
2 parents 0d7b2fb + 0e0042f commit 8f7bc81

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

library/alloc/src/ffi/c_str.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use crate::sync::Arc;
4141
/// or anything that implements <code>[Into]<[Vec]<[u8]>></code> (for
4242
/// example, you can build a `CString` straight out of a [`String`] or
4343
/// a <code>&[str]</code>, since both implement that trait).
44+
/// You can create a `CString` from a literal with `CString::from(c"Text")`.
4445
///
4546
/// The [`CString::new`] method will actually check that the provided <code>&[[u8]]</code>
4647
/// does not have 0 bytes in the middle, and return an error if it
@@ -1069,27 +1070,22 @@ impl CStr {
10691070
///
10701071
/// # Examples
10711072
///
1072-
/// Calling `to_string_lossy` on a `CStr` containing valid UTF-8:
1073+
/// Calling `to_string_lossy` on a `CStr` containing valid UTF-8. The leading
1074+
/// `c` on the string literal denotes a `CStr`.
10731075
///
10741076
/// ```
10751077
/// use std::borrow::Cow;
1076-
/// use std::ffi::CStr;
10771078
///
1078-
/// let cstr = CStr::from_bytes_with_nul(b"Hello World\0")
1079-
/// .expect("CStr::from_bytes_with_nul failed");
1080-
/// assert_eq!(cstr.to_string_lossy(), Cow::Borrowed("Hello World"));
1079+
/// assert_eq!(c"Hello World".to_string_lossy(), Cow::Borrowed("Hello World"));
10811080
/// ```
10821081
///
10831082
/// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8:
10841083
///
10851084
/// ```
10861085
/// use std::borrow::Cow;
1087-
/// use std::ffi::CStr;
10881086
///
1089-
/// let cstr = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0")
1090-
/// .expect("CStr::from_bytes_with_nul failed");
10911087
/// assert_eq!(
1092-
/// cstr.to_string_lossy(),
1088+
/// c"Hello \xF0\x90\x80World".to_string_lossy(),
10931089
/// Cow::Owned(String::from("Hello �World")) as Cow<'_, str>
10941090
/// );
10951091
/// ```

library/core/src/ffi/c_str.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,32 @@ use crate::str;
2323
///
2424
/// This type represents a borrowed reference to a nul-terminated
2525
/// array of bytes. It can be constructed safely from a <code>&[[u8]]</code>
26-
/// slice, or unsafely from a raw `*const c_char`. It can then be
27-
/// converted to a Rust <code>&[str]</code> by performing UTF-8 validation, or
28-
/// into an owned `CString`.
26+
/// slice, or unsafely from a raw `*const c_char`. It can be expressed as a
27+
/// literal in the form `c"Hello world"`.
28+
///
29+
/// The `CStr` can then be converted to a Rust <code>&[str]</code> by performing
30+
/// UTF-8 validation, or into an owned `CString`.
2931
///
3032
/// `&CStr` is to `CString` as <code>&[str]</code> is to `String`: the former
3133
/// in each pair are borrowed references; the latter are owned
3234
/// strings.
3335
///
3436
/// Note that this structure does **not** have a guaranteed layout (the `repr(transparent)`
35-
/// notwithstanding) and is not recommended to be placed in the signatures of FFI functions.
36-
/// Instead, safe wrappers of FFI functions may leverage the unsafe [`CStr::from_ptr`] constructor
37-
/// to provide a safe interface to other consumers.
37+
/// notwithstanding) and should not be placed in the signatures of FFI functions.
38+
/// Instead, safe wrappers of FFI functions may leverage [`CStr::as_ptr`] and the unsafe
39+
/// [`CStr::from_ptr`] constructor to provide a safe interface to other consumers.
3840
///
3941
/// # Examples
4042
///
4143
/// Inspecting a foreign C string:
4244
///
43-
/// ```ignore (extern-declaration)
45+
/// ```
4446
/// use std::ffi::CStr;
4547
/// use std::os::raw::c_char;
4648
///
49+
/// # /* Extern functions are awkward in doc comments - fake it instead
4750
/// extern "C" { fn my_string() -> *const c_char; }
51+
/// # */ unsafe extern "C" fn my_string() -> *const c_char { c"hello".as_ptr() }
4852
///
4953
/// unsafe {
5054
/// let slice = CStr::from_ptr(my_string());
@@ -54,12 +58,14 @@ use crate::str;
5458
///
5559
/// Passing a Rust-originating C string:
5660
///
57-
/// ```ignore (extern-declaration)
61+
/// ```
5862
/// use std::ffi::{CString, CStr};
5963
/// use std::os::raw::c_char;
6064
///
6165
/// fn work(data: &CStr) {
66+
/// # /* Extern functions are awkward in doc comments - fake it instead
6267
/// extern "C" { fn work_with(data: *const c_char); }
68+
/// # */ unsafe extern "C" fn work_with(s: *const c_char) {}
6369
///
6470
/// unsafe { work_with(data.as_ptr()) }
6571
/// }
@@ -70,11 +76,13 @@ use crate::str;
7076
///
7177
/// Converting a foreign C string into a Rust `String`:
7278
///
73-
/// ```ignore (extern-declaration)
79+
/// ```
7480
/// use std::ffi::CStr;
7581
/// use std::os::raw::c_char;
7682
///
83+
/// # /* Extern functions are awkward in doc comments - fake it instead
7784
/// extern "C" { fn my_string() -> *const c_char; }
85+
/// # */ unsafe extern "C" fn my_string() -> *const c_char { c"hello".as_ptr() }
7886
///
7987
/// fn my_string_safe() -> String {
8088
/// let cstr = unsafe { CStr::from_ptr(my_string()) };
@@ -241,16 +249,16 @@ impl CStr {
241249
///
242250
/// # Examples
243251
///
244-
/// ```ignore (extern-declaration)
252+
/// ```
245253
/// use std::ffi::{c_char, CStr};
246254
///
247-
/// extern "C" {
248-
/// fn my_string() -> *const c_char;
255+
/// fn my_string() -> *const c_char {
256+
/// c"hello".as_ptr()
249257
/// }
250258
///
251259
/// unsafe {
252260
/// let slice = CStr::from_ptr(my_string());
253-
/// println!("string returned: {}", slice.to_str().unwrap());
261+
/// assert_eq!(slice.to_str().unwrap(), "hello");
254262
/// }
255263
/// ```
256264
///
@@ -264,6 +272,8 @@ impl CStr {
264272
/// BYTES.as_ptr().cast()
265273
/// };
266274
/// const HELLO: &CStr = unsafe { CStr::from_ptr(HELLO_PTR) };
275+
///
276+
/// assert_eq!(c"Hello, world!", HELLO);
267277
/// ```
268278
///
269279
/// [valid]: core::ptr#safety
@@ -549,6 +559,7 @@ impl CStr {
549559
///
550560
/// let empty_cstr = CStr::from_bytes_with_nul(b"\0")?;
551561
/// assert!(empty_cstr.is_empty());
562+
/// assert!(c"".is_empty());
552563
/// # Ok(())
553564
/// # }
554565
/// ```

0 commit comments

Comments
 (0)