diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs
index 6a64eaf576bb9..f143e5578717f 100644
--- a/library/alloc/src/ffi/c_str.rs
+++ b/library/alloc/src/ffi/c_str.rs
@@ -41,6 +41,7 @@ use crate::sync::Arc;
/// or anything that implements [Into]<[Vec]<[u8]>>
(for
/// example, you can build a `CString` straight out of a [`String`] or
/// a &[str]
, since both implement that trait).
+/// You can create a `CString` from a literal with `CString::from(c"Text")`.
///
/// The [`CString::new`] method will actually check that the provided &[[u8]]
/// does not have 0 bytes in the middle, and return an error if it
@@ -1069,27 +1070,22 @@ impl CStr {
///
/// # Examples
///
- /// Calling `to_string_lossy` on a `CStr` containing valid UTF-8:
+ /// Calling `to_string_lossy` on a `CStr` containing valid UTF-8. The leading
+ /// `c` on the string literal denotes a `CStr`.
///
/// ```
/// use std::borrow::Cow;
- /// use std::ffi::CStr;
///
- /// let cstr = CStr::from_bytes_with_nul(b"Hello World\0")
- /// .expect("CStr::from_bytes_with_nul failed");
- /// assert_eq!(cstr.to_string_lossy(), Cow::Borrowed("Hello World"));
+ /// assert_eq!(c"Hello World".to_string_lossy(), Cow::Borrowed("Hello World"));
/// ```
///
/// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8:
///
/// ```
/// use std::borrow::Cow;
- /// use std::ffi::CStr;
///
- /// let cstr = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0")
- /// .expect("CStr::from_bytes_with_nul failed");
/// assert_eq!(
- /// cstr.to_string_lossy(),
+ /// c"Hello \xF0\x90\x80World".to_string_lossy(),
/// Cow::Owned(String::from("Hello �World")) as Cow<'_, str>
/// );
/// ```
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index aefb30463d33b..297f52e756bc6 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -23,28 +23,32 @@ use crate::str;
///
/// This type represents a borrowed reference to a nul-terminated
/// array of bytes. It can be constructed safely from a &[[u8]]
-/// slice, or unsafely from a raw `*const c_char`. It can then be
-/// converted to a Rust &[str]
by performing UTF-8 validation, or
-/// into an owned `CString`.
+/// slice, or unsafely from a raw `*const c_char`. It can be expressed as a
+/// literal in the form `c"Hello world"`.
+///
+/// The `CStr` can then be converted to a Rust &[str]
by performing
+/// UTF-8 validation, or into an owned `CString`.
///
/// `&CStr` is to `CString` as &[str]
is to `String`: the former
/// in each pair are borrowed references; the latter are owned
/// strings.
///
/// Note that this structure does **not** have a guaranteed layout (the `repr(transparent)`
-/// notwithstanding) and is not recommended to be placed in the signatures of FFI functions.
-/// Instead, safe wrappers of FFI functions may leverage the unsafe [`CStr::from_ptr`] constructor
-/// to provide a safe interface to other consumers.
+/// notwithstanding) and should not be placed in the signatures of FFI functions.
+/// Instead, safe wrappers of FFI functions may leverage [`CStr::as_ptr`] and the unsafe
+/// [`CStr::from_ptr`] constructor to provide a safe interface to other consumers.
///
/// # Examples
///
/// Inspecting a foreign C string:
///
-/// ```ignore (extern-declaration)
+/// ```
/// use std::ffi::CStr;
/// use std::os::raw::c_char;
///
+/// # /* Extern functions are awkward in doc comments - fake it instead
/// extern "C" { fn my_string() -> *const c_char; }
+/// # */ unsafe extern "C" fn my_string() -> *const c_char { c"hello".as_ptr() }
///
/// unsafe {
/// let slice = CStr::from_ptr(my_string());
@@ -54,12 +58,14 @@ use crate::str;
///
/// Passing a Rust-originating C string:
///
-/// ```ignore (extern-declaration)
+/// ```
/// use std::ffi::{CString, CStr};
/// use std::os::raw::c_char;
///
/// fn work(data: &CStr) {
+/// # /* Extern functions are awkward in doc comments - fake it instead
/// extern "C" { fn work_with(data: *const c_char); }
+/// # */ unsafe extern "C" fn work_with(s: *const c_char) {}
///
/// unsafe { work_with(data.as_ptr()) }
/// }
@@ -70,11 +76,13 @@ use crate::str;
///
/// Converting a foreign C string into a Rust `String`:
///
-/// ```ignore (extern-declaration)
+/// ```
/// use std::ffi::CStr;
/// use std::os::raw::c_char;
///
+/// # /* Extern functions are awkward in doc comments - fake it instead
/// extern "C" { fn my_string() -> *const c_char; }
+/// # */ unsafe extern "C" fn my_string() -> *const c_char { c"hello".as_ptr() }
///
/// fn my_string_safe() -> String {
/// let cstr = unsafe { CStr::from_ptr(my_string()) };
@@ -241,16 +249,16 @@ impl CStr {
///
/// # Examples
///
- /// ```ignore (extern-declaration)
+ /// ```
/// use std::ffi::{c_char, CStr};
///
- /// extern "C" {
- /// fn my_string() -> *const c_char;
+ /// fn my_string() -> *const c_char {
+ /// c"hello".as_ptr()
/// }
///
/// unsafe {
/// let slice = CStr::from_ptr(my_string());
- /// println!("string returned: {}", slice.to_str().unwrap());
+ /// assert_eq!(slice.to_str().unwrap(), "hello");
/// }
/// ```
///
@@ -264,6 +272,8 @@ impl CStr {
/// BYTES.as_ptr().cast()
/// };
/// const HELLO: &CStr = unsafe { CStr::from_ptr(HELLO_PTR) };
+ ///
+ /// assert_eq!(c"Hello, world!", HELLO);
/// ```
///
/// [valid]: core::ptr#safety
@@ -549,6 +559,7 @@ impl CStr {
///
/// let empty_cstr = CStr::from_bytes_with_nul(b"\0")?;
/// assert!(empty_cstr.is_empty());
+ /// assert!(c"".is_empty());
/// # Ok(())
/// # }
/// ```