summaryrefslogtreecommitdiffstats
path: root/library/alloc/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /library/alloc/src
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/alloc.rs9
-rw-r--r--library/alloc/src/borrow.rs1
-rw-r--r--library/alloc/src/boxed.rs20
-rw-r--r--library/alloc/src/collections/binary_heap/mod.rs6
-rw-r--r--library/alloc/src/collections/btree/dedup_sorted_iter.rs2
-rw-r--r--library/alloc/src/collections/btree/map.rs2
-rw-r--r--library/alloc/src/collections/btree/set.rs2
-rw-r--r--library/alloc/src/fmt.rs2
-rw-r--r--library/alloc/src/lib.rs7
-rw-r--r--library/alloc/src/raw_vec.rs19
-rw-r--r--library/alloc/src/rc.rs9
-rw-r--r--library/alloc/src/string.rs151
-rw-r--r--library/alloc/src/sync.rs9
-rw-r--r--library/alloc/src/vec/mod.rs16
14 files changed, 220 insertions, 35 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index a548de814..2499f1053 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -377,13 +377,20 @@ pub const fn handle_alloc_error(layout: Layout) -> ! {
panic!("allocation failed");
}
+ #[inline]
fn rt_error(layout: Layout) -> ! {
unsafe {
__rust_alloc_error_handler(layout.size(), layout.align());
}
}
- unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) }
+ #[cfg(not(feature = "panic_immediate_abort"))]
+ unsafe {
+ core::intrinsics::const_eval_select((layout,), ct_error, rt_error)
+ }
+
+ #[cfg(feature = "panic_immediate_abort")]
+ ct_error(layout)
}
// For alloc test `std::alloc::handle_alloc_error` can be used directly.
diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs
index 84331eba2..b6b6246ba 100644
--- a/library/alloc/src/borrow.rs
+++ b/library/alloc/src/borrow.rs
@@ -55,6 +55,7 @@ pub trait ToOwned {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "cloning is often expensive and is not expected to have side effects"]
+ #[cfg_attr(not(test), rustc_diagnostic_item = "to_owned_method")]
fn to_owned(&self) -> Self::Owned;
/// Uses borrowed data to replace owned data, usually by cloning.
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 96b93830f..25c63b425 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -159,7 +159,7 @@ use core::marker::Tuple;
use core::marker::Unsize;
use core::mem::{self, SizedTypeProperties};
use core::ops::{
- CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver,
+ CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DispatchFromDyn, Receiver,
};
use core::pin::Pin;
use core::ptr::{self, NonNull, Unique};
@@ -207,7 +207,7 @@ impl<T> Box<T> {
/// ```
/// let five = Box::new(5);
/// ```
- #[cfg(all(not(no_global_oom_handling)))]
+ #[cfg(not(no_global_oom_handling))]
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
@@ -2106,28 +2106,28 @@ impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
#[stable(feature = "pin", since = "1.33.0")]
impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {}
-#[unstable(feature = "generator_trait", issue = "43122")]
-impl<G: ?Sized + Generator<R> + Unpin, R, A: Allocator> Generator<R> for Box<G, A>
+#[unstable(feature = "coroutine_trait", issue = "43122")]
+impl<G: ?Sized + Coroutine<R> + Unpin, R, A: Allocator> Coroutine<R> for Box<G, A>
where
A: 'static,
{
type Yield = G::Yield;
type Return = G::Return;
- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
+ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> {
G::resume(Pin::new(&mut *self), arg)
}
}
-#[unstable(feature = "generator_trait", issue = "43122")]
-impl<G: ?Sized + Generator<R>, R, A: Allocator> Generator<R> for Pin<Box<G, A>>
+#[unstable(feature = "coroutine_trait", issue = "43122")]
+impl<G: ?Sized + Coroutine<R>, R, A: Allocator> Coroutine<R> for Pin<Box<G, A>>
where
A: 'static,
{
type Yield = G::Yield;
type Return = G::Return;
- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
+ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> {
G::resume((*self).as_mut(), arg)
}
}
@@ -2444,4 +2444,8 @@ impl<T: core::error::Error> core::error::Error for Box<T> {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
core::error::Error::source(&**self)
}
+
+ fn provide<'b>(&'b self, request: &mut core::error::Request<'b>) {
+ core::error::Error::provide(&**self, request);
+ }
}
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index 66573b90d..61c5950b0 100644
--- a/library/alloc/src/collections/binary_heap/mod.rs
+++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -434,8 +434,9 @@ impl<T: Ord> BinaryHeap<T> {
/// heap.push(4);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_binary_heap_constructor", issue = "112353")]
#[must_use]
- pub fn new() -> BinaryHeap<T> {
+ pub const fn new() -> BinaryHeap<T> {
BinaryHeap { data: vec![] }
}
@@ -477,8 +478,9 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
/// heap.push(4);
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
+ #[rustc_const_unstable(feature = "const_binary_heap_constructor", issue = "112353")]
#[must_use]
- pub fn new_in(alloc: A) -> BinaryHeap<T, A> {
+ pub const fn new_in(alloc: A) -> BinaryHeap<T, A> {
BinaryHeap { data: Vec::new_in(alloc) }
}
diff --git a/library/alloc/src/collections/btree/dedup_sorted_iter.rs b/library/alloc/src/collections/btree/dedup_sorted_iter.rs
index 17ee78045..cd6a88f32 100644
--- a/library/alloc/src/collections/btree/dedup_sorted_iter.rs
+++ b/library/alloc/src/collections/btree/dedup_sorted_iter.rs
@@ -1,6 +1,6 @@
use core::iter::Peekable;
-/// A iterator for deduping the key of a sorted iterator.
+/// An iterator for deduping the key of a sorted iterator.
/// When encountering the duplicated key, only the last key-value pair is yielded.
///
/// Used by [`BTreeMap::bulk_build_from_sorted_iter`][1].
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 5481b327d..4bdd96395 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -669,7 +669,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
/// map.insert(1, "a");
/// ```
#[unstable(feature = "btreemap_alloc", issue = "32838")]
- pub fn new_in(alloc: A) -> BTreeMap<K, V, A> {
+ pub const fn new_in(alloc: A) -> BTreeMap<K, V, A> {
BTreeMap { root: None, length: 0, alloc: ManuallyDrop::new(alloc), _marker: PhantomData }
}
}
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 9da230915..0e0355128 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -358,7 +358,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
/// let mut set: BTreeSet<i32> = BTreeSet::new_in(Global);
/// ```
#[unstable(feature = "btreemap_alloc", issue = "32838")]
- pub fn new_in(alloc: A) -> BTreeSet<T, A> {
+ pub const fn new_in(alloc: A) -> BTreeSet<T, A> {
BTreeSet { map: BTreeMap::new_in(alloc) }
}
diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs
index 1e2c35bf7..5b50ef7bf 100644
--- a/library/alloc/src/fmt.rs
+++ b/library/alloc/src/fmt.rs
@@ -555,6 +555,8 @@
pub use core::fmt::Alignment;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::fmt::Error;
+#[unstable(feature = "debug_closure_helpers", issue = "117729")]
+pub use core::fmt::FormatterFn;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::fmt::{write, Arguments};
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index f435f503f..d33c4418e 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -78,6 +78,8 @@
not(no_sync),
target_has_atomic = "ptr"
))]
+#![cfg_attr(not(bootstrap), doc(rust_logo))]
+#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
#![no_std]
#![needs_allocator]
// Lints:
@@ -113,7 +115,6 @@
#![feature(const_eval_select)]
#![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_maybe_uninit_write)]
-#![feature(const_maybe_uninit_zeroed)]
#![feature(const_pin)]
#![feature(const_refs_to_cell)]
#![feature(const_size_of_val)]
@@ -139,7 +140,7 @@
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(pattern)]
-#![feature(pointer_byte_offsets)]
+#![feature(ptr_addr_eq)]
#![feature(ptr_internals)]
#![feature(ptr_metadata)]
#![feature(ptr_sub_ptr)]
@@ -166,7 +167,7 @@
//
// Language features:
// tidy-alphabetical-start
-#![cfg_attr(not(test), feature(generator_trait))]
+#![cfg_attr(not(test), feature(coroutine_trait))]
#![cfg_attr(test, feature(panic_update_hook))]
#![cfg_attr(test, feature(test))]
#![feature(allocator_internals)]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 01b03de6a..817b93720 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -305,10 +305,13 @@ impl<T, A: Allocator> RawVec<T, A> {
/// The same as `reserve`, but returns on errors instead of panicking or aborting.
pub fn try_reserve(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
if self.needs_to_grow(len, additional) {
- self.grow_amortized(len, additional)
- } else {
- Ok(())
+ self.grow_amortized(len, additional)?;
+ }
+ unsafe {
+ // Inform the optimizer that the reservation has succeeded or wasn't needed
+ core::intrinsics::assume(!self.needs_to_grow(len, additional));
}
+ Ok(())
}
/// Ensures that the buffer contains at least enough space to hold `len +
@@ -339,7 +342,14 @@ impl<T, A: Allocator> RawVec<T, A> {
len: usize,
additional: usize,
) -> Result<(), TryReserveError> {
- if self.needs_to_grow(len, additional) { self.grow_exact(len, additional) } else { Ok(()) }
+ if self.needs_to_grow(len, additional) {
+ self.grow_exact(len, additional)?;
+ }
+ unsafe {
+ // Inform the optimizer that the reservation has succeeded or wasn't needed
+ core::intrinsics::assume(!self.needs_to_grow(len, additional));
+ }
+ Ok(())
}
/// Shrinks the buffer down to the specified capacity. If the given amount
@@ -530,6 +540,7 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
// ensure that the code generation related to these panics is minimal as there's
// only one location which panics rather than a bunch throughout the module.
#[cfg(not(no_global_oom_handling))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
fn capacity_overflow() -> ! {
panic!("capacity overflow");
}
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 38339117c..dd7876bed 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1304,7 +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)]
+ #[rustc_never_returns_null_ptr]
pub fn into_raw(this: Self) -> *const T {
let ptr = Self::as_ptr(&this);
mem::forget(this);
@@ -1328,7 +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)]
+ #[rustc_never_returns_null_ptr]
pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut RcBox<T> = NonNull::as_ptr(this.ptr);
@@ -1649,7 +1649,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
/// assert!(!Rc::ptr_eq(&five, &other_five));
/// ```
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
- this.ptr.as_ptr() as *const () == other.ptr.as_ptr() as *const ()
+ ptr::addr_eq(this.ptr.as_ptr(), other.ptr.as_ptr())
}
}
@@ -2701,6 +2701,7 @@ impl<T, I: iter::TrustedLen<Item = T>> ToRcSlice<T> for I {
///
/// [`upgrade`]: Weak::upgrade
#[stable(feature = "rc_weak", since = "1.4.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "RcWeak")]
pub struct Weak<
T: ?Sized,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
@@ -3146,7 +3147,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
#[must_use]
#[stable(feature = "weak_ptr_eq", since = "1.39.0")]
pub fn ptr_eq(&self, other: &Self) -> bool {
- ptr::eq(self.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ())
+ ptr::addr_eq(self.ptr.as_ptr(), other.ptr.as_ptr())
}
}
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index ed43244eb..4d6968157 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -714,6 +714,156 @@ impl String {
.collect()
}
+ /// Decode a UTF-16LEā€“encoded vector `v` into a `String`, returning [`Err`]
+ /// if `v` contains any invalid data.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(str_from_utf16_endian)]
+ /// // š¯„˛music
+ /// let v = &[0x34, 0xD8, 0x1E, 0xDD, 0x6d, 0x00, 0x75, 0x00,
+ /// 0x73, 0x00, 0x69, 0x00, 0x63, 0x00];
+ /// assert_eq!(String::from("š¯„˛music"),
+ /// String::from_utf16le(v).unwrap());
+ ///
+ /// // š¯„˛mu<invalid>ic
+ /// let v = &[0x34, 0xD8, 0x1E, 0xDD, 0x6d, 0x00, 0x75, 0x00,
+ /// 0x00, 0xD8, 0x69, 0x00, 0x63, 0x00];
+ /// assert!(String::from_utf16le(v).is_err());
+ /// ```
+ #[cfg(not(no_global_oom_handling))]
+ #[unstable(feature = "str_from_utf16_endian", issue = "116258")]
+ pub fn from_utf16le(v: &[u8]) -> Result<String, FromUtf16Error> {
+ if v.len() % 2 != 0 {
+ return Err(FromUtf16Error(()));
+ }
+ match (cfg!(target_endian = "little"), unsafe { v.align_to::<u16>() }) {
+ (true, ([], v, [])) => Self::from_utf16(v),
+ _ => char::decode_utf16(v.array_chunks::<2>().copied().map(u16::from_le_bytes))
+ .collect::<Result<_, _>>()
+ .map_err(|_| FromUtf16Error(())),
+ }
+ }
+
+ /// Decode a UTF-16LEā€“encoded slice `v` into a `String`, replacing
+ /// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
+ ///
+ /// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
+ /// `from_utf16le_lossy` returns a `String` since the UTF-16 to UTF-8
+ /// conversion requires a memory allocation.
+ ///
+ /// [`from_utf8_lossy`]: String::from_utf8_lossy
+ /// [`Cow<'a, str>`]: crate::borrow::Cow "borrow::Cow"
+ /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(str_from_utf16_endian)]
+ /// // š¯„˛mus<invalid>ic<invalid>
+ /// let v = &[0x34, 0xD8, 0x1E, 0xDD, 0x6d, 0x00, 0x75, 0x00,
+ /// 0x73, 0x00, 0x1E, 0xDD, 0x69, 0x00, 0x63, 0x00,
+ /// 0x34, 0xD8];
+ ///
+ /// assert_eq!(String::from("š¯„˛mus\u{FFFD}ic\u{FFFD}"),
+ /// String::from_utf16le_lossy(v));
+ /// ```
+ #[cfg(not(no_global_oom_handling))]
+ #[unstable(feature = "str_from_utf16_endian", issue = "116258")]
+ pub fn from_utf16le_lossy(v: &[u8]) -> String {
+ match (cfg!(target_endian = "little"), unsafe { v.align_to::<u16>() }) {
+ (true, ([], v, [])) => Self::from_utf16_lossy(v),
+ (true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}",
+ _ => {
+ let mut iter = v.array_chunks::<2>();
+ let string = char::decode_utf16(iter.by_ref().copied().map(u16::from_le_bytes))
+ .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
+ .collect();
+ if iter.remainder().is_empty() { string } else { string + "\u{FFFD}" }
+ }
+ }
+ }
+
+ /// Decode a UTF-16BEā€“encoded vector `v` into a `String`, returning [`Err`]
+ /// if `v` contains any invalid data.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(str_from_utf16_endian)]
+ /// // š¯„˛music
+ /// let v = &[0xD8, 0x34, 0xDD, 0x1E, 0x00, 0x6d, 0x00, 0x75,
+ /// 0x00, 0x73, 0x00, 0x69, 0x00, 0x63];
+ /// assert_eq!(String::from("š¯„˛music"),
+ /// String::from_utf16be(v).unwrap());
+ ///
+ /// // š¯„˛mu<invalid>ic
+ /// let v = &[0xD8, 0x34, 0xDD, 0x1E, 0x00, 0x6d, 0x00, 0x75,
+ /// 0xD8, 0x00, 0x00, 0x69, 0x00, 0x63];
+ /// assert!(String::from_utf16be(v).is_err());
+ /// ```
+ #[cfg(not(no_global_oom_handling))]
+ #[unstable(feature = "str_from_utf16_endian", issue = "116258")]
+ pub fn from_utf16be(v: &[u8]) -> Result<String, FromUtf16Error> {
+ if v.len() % 2 != 0 {
+ return Err(FromUtf16Error(()));
+ }
+ match (cfg!(target_endian = "big"), unsafe { v.align_to::<u16>() }) {
+ (true, ([], v, [])) => Self::from_utf16(v),
+ _ => char::decode_utf16(v.array_chunks::<2>().copied().map(u16::from_be_bytes))
+ .collect::<Result<_, _>>()
+ .map_err(|_| FromUtf16Error(())),
+ }
+ }
+
+ /// Decode a UTF-16BEā€“encoded slice `v` into a `String`, replacing
+ /// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
+ ///
+ /// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
+ /// `from_utf16le_lossy` returns a `String` since the UTF-16 to UTF-8
+ /// conversion requires a memory allocation.
+ ///
+ /// [`from_utf8_lossy`]: String::from_utf8_lossy
+ /// [`Cow<'a, str>`]: crate::borrow::Cow "borrow::Cow"
+ /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(str_from_utf16_endian)]
+ /// // š¯„˛mus<invalid>ic<invalid>
+ /// let v = &[0xD8, 0x34, 0xDD, 0x1E, 0x00, 0x6d, 0x00, 0x75,
+ /// 0x00, 0x73, 0xDD, 0x1E, 0x00, 0x69, 0x00, 0x63,
+ /// 0xD8, 0x34];
+ ///
+ /// assert_eq!(String::from("š¯„˛mus\u{FFFD}ic\u{FFFD}"),
+ /// String::from_utf16be_lossy(v));
+ /// ```
+ #[cfg(not(no_global_oom_handling))]
+ #[unstable(feature = "str_from_utf16_endian", issue = "116258")]
+ pub fn from_utf16be_lossy(v: &[u8]) -> String {
+ match (cfg!(target_endian = "big"), unsafe { v.align_to::<u16>() }) {
+ (true, ([], v, [])) => Self::from_utf16_lossy(v),
+ (true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}",
+ _ => {
+ let mut iter = v.array_chunks::<2>();
+ let string = char::decode_utf16(iter.by_ref().copied().map(u16::from_be_bytes))
+ .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
+ .collect();
+ if iter.remainder().is_empty() { string } else { string + "\u{FFFD}" }
+ }
+ }
+ }
+
/// Decomposes a `String` into its raw components.
///
/// Returns the raw pointer to the underlying data, the length of
@@ -2435,6 +2585,7 @@ pub trait ToString {
/// ```
#[rustc_conversion_suggestion]
#[stable(feature = "rust1", since = "1.0.0")]
+ #[cfg_attr(not(test), rustc_diagnostic_item = "to_string_method")]
fn to_string(&self) -> String;
}
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 838987f67..351e6c1a4 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -311,6 +311,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
///
/// [`upgrade`]: Weak::upgrade
#[stable(feature = "arc_weak", since = "1.4.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "ArcWeak")]
pub struct Weak<
T: ?Sized,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
@@ -1454,7 +1455,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)]
+ #[rustc_never_returns_null_ptr]
pub fn into_raw(this: Self) -> *const T {
let ptr = Self::as_ptr(&this);
mem::forget(this);
@@ -1479,7 +1480,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)]
+ #[rustc_never_returns_null_ptr]
pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
@@ -1778,7 +1779,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
#[must_use]
#[stable(feature = "ptr_eq", since = "1.17.0")]
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
- this.ptr.as_ptr() as *const () == other.ptr.as_ptr() as *const ()
+ ptr::addr_eq(this.ptr.as_ptr(), other.ptr.as_ptr())
}
}
@@ -2900,7 +2901,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
#[must_use]
#[stable(feature = "weak_ptr_eq", since = "1.39.0")]
pub fn ptr_eq(&self, other: &Self) -> bool {
- ptr::eq(self.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ())
+ ptr::addr_eq(self.ptr.as_ptr(), other.ptr.as_ptr())
}
}
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 56fc6bc40..6c78d65f1 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1258,7 +1258,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// [`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)]
+ #[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
@@ -1318,7 +1318,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// [`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)]
+ #[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
@@ -1447,7 +1447,8 @@ impl<T, A: Allocator> Vec<T, A> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap_remove(&mut self, index: usize) -> T {
#[cold]
- #[inline(never)]
+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+ #[track_caller]
fn assert_failed(index: usize, len: usize) -> ! {
panic!("swap_remove index (is {index}) should be < len (is {len})");
}
@@ -1488,7 +1489,8 @@ impl<T, A: Allocator> Vec<T, A> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn insert(&mut self, index: usize, element: T) {
#[cold]
- #[inline(never)]
+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+ #[track_caller]
fn assert_failed(index: usize, len: usize) -> ! {
panic!("insertion index (is {index}) should be <= len (is {len})");
}
@@ -1549,7 +1551,7 @@ impl<T, A: Allocator> Vec<T, A> {
#[track_caller]
pub fn remove(&mut self, index: usize) -> T {
#[cold]
- #[inline(never)]
+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[track_caller]
fn assert_failed(index: usize, len: usize) -> ! {
panic!("removal index (is {index}) should be < len (is {len})");
@@ -1956,6 +1958,7 @@ impl<T, A: Allocator> Vec<T, A> {
} else {
unsafe {
self.len -= 1;
+ core::intrinsics::assume(self.len < self.capacity());
Some(ptr::read(self.as_ptr().add(self.len())))
}
}
@@ -2147,7 +2150,8 @@ impl<T, A: Allocator> Vec<T, A> {
A: Clone,
{
#[cold]
- #[inline(never)]
+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+ #[track_caller]
fn assert_failed(at: usize, len: usize) -> ! {
panic!("`at` split index (is {at}) should be <= len (is {len})");
}