diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 12484462f82f4..01e279b6d04fa 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1617,7 +1617,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let post = format!(", consider renaming `{}` into `{snippet}`", suggestion.candidate);
(span, snippet, post)
} else {
- (span, suggestion.candidate.to_string(), String::new())
+ (span, suggestion.candidate.to_ident_string(), String::new())
};
let msg = match suggestion.target {
SuggestionTarget::SimilarlyNamed => format!(
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(())
/// # }
/// ```
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index e9eeb3153307f..73bb256518d89 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -358,6 +358,54 @@ impl *const T {
if self.is_null() { None } else { unsafe { Some(&*self) } }
}
+ /// Returns a shared reference to the value behind the pointer.
+ /// If the pointer may be null or the value may be uninitialized, [`as_uninit_ref`] must be used instead.
+ /// If the pointer may be null, but the value is known to have been initialized, [`as_ref`] must be used instead.
+ ///
+ /// [`as_ref`]: #method.as_ref
+ /// [`as_uninit_ref`]: #method.as_uninit_ref
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that all of the following is true:
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferenceable" in the sense defined in [the module documentation].
+ ///
+ /// * The pointer must point to an initialized instance of `T`.
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, while this reference exists, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
+ ///
+ /// This applies even if the result of this method is unused!
+ /// (The part about being initialized is not yet fully decided, but until
+ /// it is, the only safe approach is to ensure that they are indeed initialized.)
+ ///
+ /// [the module documentation]: crate::ptr#safety
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(ptr_as_ref_unchecked)]
+ /// let ptr: *const u8 = &10u8 as *const u8;
+ ///
+ /// unsafe {
+ /// println!("We got back the value: {}!", ptr.as_ref_unchecked());
+ /// }
+ /// ```
+ // FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
+ #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
+ #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+ #[inline]
+ #[must_use]
+ pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
+ // SAFETY: the caller must guarantee that `self` is valid for a reference
+ unsafe { &*self }
+ }
+
/// Returns `None` if the pointer is null, or else returns a shared reference to
/// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
/// that the value has to be initialized.
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index c5a188dc7d4f2..b67930503e015 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -367,6 +367,57 @@ impl *mut T {
if self.is_null() { None } else { unsafe { Some(&*self) } }
}
+ /// Returns a shared reference to the value behind the pointer.
+ /// If the pointer may be null or the value may be uninitialized, [`as_uninit_ref`] must be used instead.
+ /// If the pointer may be null, but the value is known to have been initialized, [`as_ref`] must be used instead.
+ ///
+ /// For the mutable counterpart see [`as_mut_unchecked`].
+ ///
+ /// [`as_ref`]: #method.as_ref
+ /// [`as_uninit_ref`]: #method.as_uninit_ref
+ /// [`as_mut_unchecked`]: #method.as_mut_unchecked
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that all of the following is true:
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferenceable" in the sense defined in [the module documentation].
+ ///
+ /// * The pointer must point to an initialized instance of `T`.
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, while this reference exists, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
+ ///
+ /// This applies even if the result of this method is unused!
+ /// (The part about being initialized is not yet fully decided, but until
+ /// it is, the only safe approach is to ensure that they are indeed initialized.)
+ ///
+ /// [the module documentation]: crate::ptr#safety
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(ptr_as_ref_unchecked)]
+ /// let ptr: *mut u8 = &mut 10u8 as *mut u8;
+ ///
+ /// unsafe {
+ /// println!("We got back the value: {}!", ptr.as_ref_unchecked());
+ /// }
+ /// ```
+ // FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
+ #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
+ #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+ #[inline]
+ #[must_use]
+ pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
+ // SAFETY: the caller must guarantee that `self` is valid for a reference
+ unsafe { &*self }
+ }
+
/// Returns `None` if the pointer is null, or else returns a shared reference to
/// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
/// that the value has to be initialized.
@@ -688,6 +739,58 @@ impl *mut T {
if self.is_null() { None } else { unsafe { Some(&mut *self) } }
}
+ /// Returns a unique reference to the value behind the pointer.
+ /// If the pointer may be null or the value may be uninitialized, [`as_uninit_mut`] must be used instead.
+ /// If the pointer may be null, but the value is known to have been initialized, [`as_mut`] must be used instead.
+ ///
+ /// For the shared counterpart see [`as_ref_unchecked`].
+ ///
+ /// [`as_mut`]: #method.as_mut
+ /// [`as_uninit_mut`]: #method.as_uninit_mut
+ /// [`as_ref_unchecked`]: #method.as_mut_unchecked
+ ///
+ /// # Safety
+ ///
+ /// When calling this method, you have to ensure that all of the following is true:
+ ///
+ /// * The pointer must be properly aligned.
+ ///
+ /// * It must be "dereferenceable" in the sense defined in [the module documentation].
+ ///
+ /// * The pointer must point to an initialized instance of `T`.
+ ///
+ /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
+ /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
+ /// In particular, while this reference exists, the memory the pointer points to must
+ /// not get mutated (except inside `UnsafeCell`).
+ ///
+ /// This applies even if the result of this method is unused!
+ /// (The part about being initialized is not yet fully decided, but until
+ /// it is, the only safe approach is to ensure that they are indeed initialized.)
+ ///
+ /// [the module documentation]: crate::ptr#safety
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(ptr_as_ref_unchecked)]
+ /// let mut s = [1, 2, 3];
+ /// let ptr: *mut u32 = s.as_mut_ptr();
+ /// let first_value = unsafe { ptr.as_mut_unchecked() };
+ /// *first_value = 4;
+ /// # assert_eq!(s, [4, 2, 3]);
+ /// println!("{s:?}"); // It'll print: "[4, 2, 3]".
+ /// ```
+ // FIXME: mention it in the docs for `as_mut` and `as_uninit_mut` once stabilized.
+ #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
+ #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+ #[inline]
+ #[must_use]
+ pub const unsafe fn as_mut_unchecked<'a>(self) -> &'a mut T {
+ // SAFETY: the caller must guarantee that `self` is valid for a reference
+ unsafe { &mut *self }
+ }
+
/// Returns `None` if the pointer is null, or else returns a unique reference to
/// the value wrapped in `Some`. In contrast to [`as_mut`], this does not require
/// that the value has to be initialized.
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 78494b866b108..72f6a3b773bb5 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -1437,10 +1437,10 @@ impl TryFromFloatSecsError {
const fn description(&self) -> &'static str {
match self.kind {
TryFromFloatSecsErrorKind::Negative => {
- "can not convert float seconds to Duration: value is negative"
+ "cannot convert float seconds to Duration: value is negative"
}
TryFromFloatSecsErrorKind::OverflowOrNan => {
- "can not convert float seconds to Duration: value is either too big or NaN"
+ "cannot convert float seconds to Duration: value is either too big or NaN"
}
}
}
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index dc0e302a81088..b98fbbf762fa2 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -353,6 +353,12 @@ fn default_alloc_error_hook(layout: Layout) {
if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
panic!("memory allocation of {} bytes failed", layout.size());
} else {
+ // This is the default path taken on OOM, and the only path taken on stable with std.
+ // Crucially, it does *not* call any user-defined code, and therefore users do not have to
+ // worry about allocation failure causing reentrancy issues. That makes it different from
+ // the default `__rdl_oom` defined in alloc (i.e., the default alloc error handler that is
+ // called when there is no `#[alloc_error_handler]`), which triggers a regular panic and
+ // thus can invoke a user-defined panic hook, executing arbitrary user-defined code.
rtprintpanic!("memory allocation of {} bytes failed\n", layout.size());
}
}
diff --git a/tests/ui/span/suggestion-raw-68962.rs b/tests/ui/span/suggestion-raw-68962.rs
new file mode 100644
index 0000000000000..0b581308f6628
--- /dev/null
+++ b/tests/ui/span/suggestion-raw-68962.rs
@@ -0,0 +1,11 @@
+fn r#fn() {}
+
+fn main() {
+ let r#final = 1;
+
+ // Should correctly suggest variable defined using raw identifier.
+ fina; //~ ERROR cannot find value
+
+ // Should correctly suggest function defined using raw identifier.
+ f(); //~ ERROR cannot find function
+}
diff --git a/tests/ui/span/suggestion-raw-68962.stderr b/tests/ui/span/suggestion-raw-68962.stderr
new file mode 100644
index 0000000000000..2e25f5cbdf58d
--- /dev/null
+++ b/tests/ui/span/suggestion-raw-68962.stderr
@@ -0,0 +1,18 @@
+error[E0425]: cannot find value `fina` in this scope
+ --> $DIR/suggestion-raw-68962.rs:7:5
+ |
+LL | fina;
+ | ^^^^ help: a local variable with a similar name exists: `r#final`
+
+error[E0425]: cannot find function `f` in this scope
+ --> $DIR/suggestion-raw-68962.rs:10:5
+ |
+LL | fn r#fn() {}
+ | --------- similarly named function `r#fn` defined here
+...
+LL | f();
+ | ^ help: a function with a similar name exists: `r#fn`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.