summaryrefslogtreecommitdiffstats
path: root/library/alloc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:36 +0000
commite02c5b5930c2c9ba3e5423fe12e2ef0155017297 (patch)
treefd60ebbbb5299e16e5fca8c773ddb74f764760db /library/alloc
parentAdding debian version 1.73.0+dfsg1-1. (diff)
downloadrustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.tar.xz
rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/alloc')
-rw-r--r--library/alloc/src/alloc.rs32
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs4
-rw-r--r--library/alloc/src/fmt.rs4
-rw-r--r--library/alloc/src/lib.rs6
-rw-r--r--library/alloc/src/macros.rs21
-rw-r--r--library/alloc/src/rc.rs23
-rw-r--r--library/alloc/src/slice.rs2
-rw-r--r--library/alloc/src/sync.rs31
-rw-r--r--library/alloc/src/vec/mod.rs87
-rw-r--r--library/alloc/tests/vec.rs11
10 files changed, 189 insertions, 32 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 5205ed9fb..a548de814 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -343,18 +343,31 @@ extern "Rust" {
fn __rust_alloc_error_handler(size: usize, align: usize) -> !;
}
-/// Abort on memory allocation error or failure.
+/// Signal a memory allocation error.
///
-/// Callers of memory allocation APIs wishing to abort computation
+/// Callers of memory allocation APIs wishing to cease execution
/// in response to an allocation error are encouraged to call this function,
-/// rather than directly invoking `panic!` or similar.
+/// rather than directly invoking [`panic!`] or similar.
///
-/// The default behavior of this function is to print a message to standard error
-/// and abort the process.
-/// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
+/// This function is guaranteed to diverge (not return normally with a value), but depending on
+/// global configuration, it may either panic (resulting in unwinding or aborting as per
+/// configuration for all panics), or abort the process (with no unwinding).
+///
+/// The default behavior is:
+///
+/// * If the binary links against `std` (typically the case), then
+/// print a message to standard error and abort the process.
+/// This behavior can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
+/// Future versions of Rust may panic by default instead.
+///
+/// * If the binary does not link against `std` (all of its crates are marked
+/// [`#![no_std]`][no_std]), then call [`panic!`] with a message.
+/// [The panic handler] applies as to any panic.
///
/// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
/// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
+/// [The panic handler]: https://doc.rust-lang.org/reference/runtime.html#the-panic_handler-attribute
+/// [no_std]: https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute
#[stable(feature = "global_alloc", since = "1.28.0")]
#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
#[cfg(all(not(no_global_oom_handling), not(test)))]
@@ -395,9 +408,10 @@ pub mod __alloc_error_handler {
if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
panic!("memory allocation of {size} bytes failed")
} else {
- core::panicking::panic_nounwind_fmt(format_args!(
- "memory allocation of {size} bytes failed"
- ))
+ core::panicking::panic_nounwind_fmt(
+ format_args!("memory allocation of {size} bytes failed"),
+ /* force_no_backtrace */ false,
+ )
}
}
}
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 5965ec2af..4ef8af9b0 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -1015,8 +1015,8 @@ impl<T, A: Allocator> VecDeque<T, A> {
/// Shortens the deque, keeping the first `len` elements and dropping
/// the rest.
///
- /// If `len` is greater than the deque's current length, this has no
- /// effect.
+ /// If `len` is greater or equal to the deque's current length, this has
+ /// no effect.
///
/// # Examples
///
diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs
index fb8d00e8d..1e2c35bf7 100644
--- a/library/alloc/src/fmt.rs
+++ b/library/alloc/src/fmt.rs
@@ -177,8 +177,8 @@
//! These are all flags altering the behavior of the formatter.
//!
//! * `+` - This is intended for numeric types and indicates that the sign
-//! should always be printed. Positive signs are never printed by
-//! default, and the negative sign is only printed by default for signed values.
+//! should always be printed. By default only the negative sign of signed values
+//! is printed, and the sign of positive or unsigned values is omitted.
//! This flag indicates that the correct sign (`+` or `-`) should always be printed.
//! * `-` - Currently not used
//! * `#` - This flag indicates that the "alternate" form of printing should
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index ffe6d6373..f435f503f 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -88,8 +88,8 @@
#![warn(missing_docs)]
#![allow(explicit_outlives_requirements)]
#![warn(multiple_supertrait_upcastable)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), allow(rustdoc::redundant_explicit_links))]
+#![allow(internal_features)]
+#![allow(rustdoc::redundant_explicit_links)]
//
// Library features:
// tidy-alphabetical-start
@@ -120,6 +120,7 @@
#![feature(const_waker)]
#![feature(core_intrinsics)]
#![feature(core_panic)]
+#![feature(deprecated_suggestion)]
#![feature(dispatch_from_dyn)]
#![feature(error_generic_member_access)]
#![feature(error_in_core)]
@@ -143,7 +144,6 @@
#![feature(ptr_metadata)]
#![feature(ptr_sub_ptr)]
#![feature(receiver_trait)]
-#![feature(saturating_int_impl)]
#![feature(set_ptr_value)]
#![feature(sized_type_properties)]
#![feature(slice_from_ptr_range)]
diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs
index 4c6ae8f25..0f767df60 100644
--- a/library/alloc/src/macros.rs
+++ b/library/alloc/src/macros.rs
@@ -79,23 +79,28 @@ macro_rules! vec {
///
/// The first argument `format!` receives is a format string. This must be a string
/// literal. The power of the formatting string is in the `{}`s contained.
-///
/// Additional parameters passed to `format!` replace the `{}`s within the
/// formatting string in the order given unless named or positional parameters
-/// are used; see [`std::fmt`] for more information.
+/// are used.
+///
+/// See [the formatting syntax documentation in `std::fmt`](../std/fmt/index.html)
+/// for details.
///
/// A common use for `format!` is concatenation and interpolation of strings.
/// The same convention is used with [`print!`] and [`write!`] macros,
-/// depending on the intended destination of the string.
+/// depending on the intended destination of the string; all these macros internally use [`format_args!`].
///
/// To convert a single value to a string, use the [`to_string`] method. This
/// will use the [`Display`] formatting trait.
///
-/// [`std::fmt`]: ../std/fmt/index.html
+/// To concatenate literals into a `&'static str`, use the [`concat!`] macro.
+///
/// [`print!`]: ../std/macro.print.html
/// [`write!`]: core::write
+/// [`format_args!`]: core::format_args
/// [`to_string`]: crate::string::ToString
/// [`Display`]: core::fmt::Display
+/// [`concat!`]: core::concat
///
/// # Panics
///
@@ -106,11 +111,11 @@ macro_rules! vec {
/// # Examples
///
/// ```
-/// format!("test");
-/// format!("hello {}", "world!");
-/// format!("x = {}, y = {y}", 10, y = 30);
+/// format!("test"); // => "test"
+/// format!("hello {}", "world!"); // => "hello world!"
+/// format!("x = {}, y = {val}", 10, val = 30); // => "x = 10, y = 30"
/// let (x, y) = (1, 2);
-/// format!("{x} + {y} = 3");
+/// format!("{x} + {y} = 3"); // => "1 + 2 = 3"
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index c485680f9..38339117c 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1304,6 +1304,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
/// assert_eq!(unsafe { &*x_ptr }, "hello");
/// ```
#[stable(feature = "rc_raw", since = "1.17.0")]
+ #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
pub fn into_raw(this: Self) -> *const T {
let ptr = Self::as_ptr(&this);
mem::forget(this);
@@ -1327,6 +1328,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
/// assert_eq!(unsafe { &*x_ptr }, "hello");
/// ```
#[stable(feature = "weak_into_raw", since = "1.45.0")]
+ #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut RcBox<T> = NonNull::as_ptr(this.ptr);
@@ -2407,6 +2409,27 @@ impl<T> From<T> for Rc<T> {
}
#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "shared_from_array", since = "1.74.0")]
+impl<T, const N: usize> From<[T; N]> for Rc<[T]> {
+ /// Converts a [`[T; N]`](prim@array) into an `Rc<[T]>`.
+ ///
+ /// The conversion moves the array into a newly allocated `Rc`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use std::rc::Rc;
+ /// let original: [i32; 3] = [1, 2, 3];
+ /// let shared: Rc<[i32]> = Rc::from(original);
+ /// assert_eq!(&[1, 2, 3], &shared[..]);
+ /// ```
+ #[inline]
+ fn from(v: [T; N]) -> Rc<[T]> {
+ Rc::<[T; N]>::from(v)
+ }
+}
+
+#[cfg(not(no_global_oom_handling))]
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<T: Clone> From<&[T]> for Rc<[T]> {
/// Allocate a reference-counted slice and fill it by cloning `v`'s items.
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 093dcbbe8..aa3b7b7e1 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -592,7 +592,7 @@ impl<T> [T] {
/// ```
#[rustc_allow_incoherent_impl]
#[stable(feature = "rust1", since = "1.0.0")]
- #[deprecated(since = "1.3.0", note = "renamed to join")]
+ #[deprecated(since = "1.3.0", note = "renamed to join", suggestion = "join")]
pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
where
Self: Join<Separator>,
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index d3b755844..838987f67 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -1454,6 +1454,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
/// ```
#[must_use = "losing the pointer will leak memory"]
#[stable(feature = "rc_raw", since = "1.17.0")]
+ #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
pub fn into_raw(this: Self) -> *const T {
let ptr = Self::as_ptr(&this);
mem::forget(this);
@@ -1478,6 +1479,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
/// ```
#[must_use]
#[stable(feature = "rc_as_ptr", since = "1.45.0")]
+ #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
@@ -1616,7 +1618,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
#[must_use]
#[stable(feature = "arc_counts", since = "1.15.0")]
pub fn weak_count(this: &Self) -> usize {
- let cnt = this.inner().weak.load(Acquire);
+ let cnt = this.inner().weak.load(Relaxed);
// If the weak count is currently locked, the value of the
// count was 0 just before taking the lock.
if cnt == usize::MAX { 0 } else { cnt - 1 }
@@ -1646,7 +1648,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
#[must_use]
#[stable(feature = "arc_counts", since = "1.15.0")]
pub fn strong_count(this: &Self) -> usize {
- this.inner().strong.load(Acquire)
+ this.inner().strong.load(Relaxed)
}
/// Increments the strong reference count on the `Arc<T>` associated with the
@@ -2801,7 +2803,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
#[must_use]
#[stable(feature = "weak_counts", since = "1.41.0")]
pub fn strong_count(&self) -> usize {
- if let Some(inner) = self.inner() { inner.strong.load(Acquire) } else { 0 }
+ if let Some(inner) = self.inner() { inner.strong.load(Relaxed) } else { 0 }
}
/// Gets an approximation of the number of `Weak` pointers pointing to this
@@ -2820,7 +2822,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
pub fn weak_count(&self) -> usize {
if let Some(inner) = self.inner() {
let weak = inner.weak.load(Acquire);
- let strong = inner.strong.load(Acquire);
+ let strong = inner.strong.load(Relaxed);
if strong == 0 {
0
} else {
@@ -3268,6 +3270,27 @@ impl<T> From<T> for Arc<T> {
}
#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "shared_from_array", since = "1.74.0")]
+impl<T, const N: usize> From<[T; N]> for Arc<[T]> {
+ /// Converts a [`[T; N]`](prim@array) into an `Arc<[T]>`.
+ ///
+ /// The conversion moves the array into a newly allocated `Arc`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use std::sync::Arc;
+ /// let original: [i32; 3] = [1, 2, 3];
+ /// let shared: Arc<[i32]> = Arc::from(original);
+ /// assert_eq!(&[1, 2, 3], &shared[..]);
+ /// ```
+ #[inline]
+ fn from(v: [T; N]) -> Arc<[T]> {
+ Arc::<[T; N]>::from(v)
+ }
+}
+
+#[cfg(not(no_global_oom_handling))]
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<T: Clone> From<&[T]> for Arc<[T]> {
/// Allocate a reference-counted slice and fill it by cloning `v`'s items.
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index e45ddc789..56fc6bc40 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1110,8 +1110,8 @@ impl<T, A: Allocator> Vec<T, A> {
/// Shortens the vector, keeping the first `len` elements and dropping
/// the rest.
///
- /// If `len` is greater than the vector's current length, this has no
- /// effect.
+ /// If `len` is greater or equal to the vector's current length, this has
+ /// no effect.
///
/// The [`drain`] method can emulate `truncate`, but causes the excess
/// elements to be returned instead of dropped.
@@ -1218,6 +1218,15 @@ impl<T, A: Allocator> Vec<T, A> {
/// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
/// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
///
+ /// This method guarantees that for the purpose of the aliasing model, this method
+ /// does not materialize a reference to the underlying slice, and thus the returned pointer
+ /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
+ /// Note that calling other methods that materialize mutable references to the slice,
+ /// or mutable references to specific elements you are planning on accessing through this pointer,
+ /// as well as writing to those elements, may still invalidate this pointer.
+ /// See the second example below for how this guarantee can be used.
+ ///
+ ///
/// # Examples
///
/// ```
@@ -1231,8 +1240,25 @@ impl<T, A: Allocator> Vec<T, A> {
/// }
/// ```
///
+ /// Due to the aliasing guarantee, the following code is legal:
+ ///
+ /// ```rust
+ /// unsafe {
+ /// let mut v = vec![0, 1, 2];
+ /// let ptr1 = v.as_ptr();
+ /// let _ = ptr1.read();
+ /// let ptr2 = v.as_mut_ptr().offset(2);
+ /// ptr2.write(2);
+ /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+ /// // because it mutated a different element:
+ /// let _ = ptr1.read();
+ /// }
+ /// ```
+ ///
/// [`as_mut_ptr`]: Vec::as_mut_ptr
+ /// [`as_ptr`]: Vec::as_ptr
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
+ #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
#[inline]
pub fn as_ptr(&self) -> *const T {
// We shadow the slice method of the same name to avoid going through
@@ -1248,6 +1274,15 @@ impl<T, A: Allocator> Vec<T, A> {
/// Modifying the vector may cause its buffer to be reallocated,
/// which would also make any pointers to it invalid.
///
+ /// This method guarantees that for the purpose of the aliasing model, this method
+ /// does not materialize a reference to the underlying slice, and thus the returned pointer
+ /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
+ /// Note that calling other methods that materialize references to the slice,
+ /// or references to specific elements you are planning on accessing through this pointer,
+ /// may still invalidate this pointer.
+ /// See the second example below for how this guarantee can be used.
+ ///
+ ///
/// # Examples
///
/// ```
@@ -1265,7 +1300,25 @@ impl<T, A: Allocator> Vec<T, A> {
/// }
/// assert_eq!(&*x, &[0, 1, 2, 3]);
/// ```
+ ///
+ /// Due to the aliasing guarantee, the following code is legal:
+ ///
+ /// ```rust
+ /// unsafe {
+ /// let mut v = vec![0];
+ /// let ptr1 = v.as_mut_ptr();
+ /// ptr1.write(1);
+ /// let ptr2 = v.as_mut_ptr();
+ /// ptr2.write(2);
+ /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+ /// ptr1.write(3);
+ /// }
+ /// ```
+ ///
+ /// [`as_mut_ptr`]: Vec::as_mut_ptr
+ /// [`as_ptr`]: Vec::as_ptr
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
+ #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut T {
// We shadow the slice method of the same name to avoid going through
@@ -3102,6 +3155,36 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
}
#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "vec_from_array_ref", since = "1.74.0")]
+impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> {
+ /// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(Vec::from(&[1, 2, 3]), vec![1, 2, 3]);
+ /// ```
+ fn from(s: &[T; N]) -> Vec<T> {
+ Self::from(s.as_slice())
+ }
+}
+
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "vec_from_array_ref", since = "1.74.0")]
+impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T> {
+ /// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]);
+ /// ```
+ fn from(s: &mut [T; N]) -> Vec<T> {
+ Self::from(s.as_mut_slice())
+ }
+}
+
+#[cfg(not(no_global_oom_handling))]
#[stable(feature = "vec_from_array", since = "1.44.0")]
impl<T, const N: usize> From<[T; N]> for Vec<T> {
/// Allocate a `Vec<T>` and move `s`'s items into it.
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 183dd8e6e..d44dcfbf6 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -2499,7 +2499,6 @@ fn test_into_flattened_size_overflow() {
let _ = v.into_flattened();
}
-#[cfg(not(bootstrap))]
#[test]
fn test_box_zero_allocator() {
use core::{alloc::AllocError, cell::RefCell};
@@ -2563,3 +2562,13 @@ fn test_box_zero_allocator() {
// Ensure all ZSTs have been freed.
assert!(alloc.state.borrow().0.is_empty());
}
+
+#[test]
+fn test_vec_from_array_ref() {
+ assert_eq!(Vec::from(&[1, 2, 3]), vec![1, 2, 3]);
+}
+
+#[test]
+fn test_vec_from_array_mut_ref() {
+ assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]);
+}