diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
commit | e02c5b5930c2c9ba3e5423fe12e2ef0155017297 (patch) | |
tree | fd60ebbbb5299e16e5fca8c773ddb74f764760db /library/alloc | |
parent | Adding debian version 1.73.0+dfsg1-1. (diff) | |
download | rustc-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.rs | 32 | ||||
-rw-r--r-- | library/alloc/src/collections/vec_deque/mod.rs | 4 | ||||
-rw-r--r-- | library/alloc/src/fmt.rs | 4 | ||||
-rw-r--r-- | library/alloc/src/lib.rs | 6 | ||||
-rw-r--r-- | library/alloc/src/macros.rs | 21 | ||||
-rw-r--r-- | library/alloc/src/rc.rs | 23 | ||||
-rw-r--r-- | library/alloc/src/slice.rs | 2 | ||||
-rw-r--r-- | library/alloc/src/sync.rs | 31 | ||||
-rw-r--r-- | library/alloc/src/vec/mod.rs | 87 | ||||
-rw-r--r-- | library/alloc/tests/vec.rs | 11 |
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]); +} |