about summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@users.noreply.github.com>2024-12-23 10:12:23 +0000
committerGitHub <noreply@github.com>2024-12-23 10:12:23 +0000
commit8dbdcc03ebfd5d3c21671d8a021669dc79d93038 (patch)
treee61d058d30fdd35c4a306fde5be669b08092a4fd /library/alloc/src
parent63a3c394617b114a8fa6e54401700b3adee65a7d (diff)
parent0180d2d16f5f5d60384a594568a98a6e6f8eea59 (diff)
Merge pull request #18746 from lnicola/sync-from-rust
minor: Sync from downstream
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/alloc.rs3
-rw-r--r--library/alloc/src/alloc/tests.rs30
-rw-r--r--library/alloc/src/boxed.rs9
-rw-r--r--library/alloc/src/collections/binary_heap/mod.rs6
-rw-r--r--library/alloc/src/collections/binary_heap/tests.rs580
-rw-r--r--library/alloc/src/collections/linked_list.rs9
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs23
-rw-r--r--library/alloc/src/ffi/c_str.rs3
-rw-r--r--library/alloc/src/ffi/c_str/tests.rs226
-rw-r--r--library/alloc/src/lib.rs4
-rw-r--r--library/alloc/src/rc.rs255
-rw-r--r--library/alloc/src/slice.rs2
-rw-r--r--library/alloc/src/string.rs69
-rw-r--r--library/alloc/src/sync.rs5
-rw-r--r--library/alloc/src/sync/tests.rs717
-rw-r--r--library/alloc/src/tests.rs140
-rw-r--r--library/alloc/src/vec/extract_if.rs50
-rw-r--r--library/alloc/src/vec/mod.rs89
18 files changed, 390 insertions, 1830 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 04b7315e650..ae34fc65326 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -10,9 +10,6 @@ use core::hint;
 #[cfg(not(test))]
 use core::ptr::{self, NonNull};
 
-#[cfg(test)]
-mod tests;
-
 extern "Rust" {
     // These are the magic symbols to call the global allocator. rustc generates
     // them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute
diff --git a/library/alloc/src/alloc/tests.rs b/library/alloc/src/alloc/tests.rs
deleted file mode 100644
index 5d6077f057a..00000000000
--- a/library/alloc/src/alloc/tests.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-use super::*;
-
-extern crate test;
-use test::Bencher;
-
-use crate::boxed::Box;
-
-#[test]
-fn allocate_zeroed() {
-    unsafe {
-        let layout = Layout::from_size_align(1024, 1).unwrap();
-        let ptr =
-            Global.allocate_zeroed(layout.clone()).unwrap_or_else(|_| handle_alloc_error(layout));
-
-        let mut i = ptr.as_non_null_ptr().as_ptr();
-        let end = i.add(layout.size());
-        while i < end {
-            assert_eq!(*i, 0);
-            i = i.add(1);
-        }
-        Global.deallocate(ptr.as_non_null_ptr(), layout);
-    }
-}
-
-#[bench]
-fn alloc_owned_small(b: &mut Bencher) {
-    b.iter(|| {
-        let _: Box<_> = Box::new(10);
-    })
-}
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index e0f94428cfa..23b85fbd4eb 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1985,7 +1985,8 @@ impl<Args: Tuple, F: Fn<Args> + ?Sized, A: Allocator> Fn<Args> for Box<F, A> {
     }
 }
 
-#[unstable(feature = "async_fn_traits", issue = "none")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args> for Box<F, A> {
     type Output = F::Output;
     type CallOnceFuture = F::CallOnceFuture;
@@ -1995,7 +1996,8 @@ impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args>
     }
 }
 
-#[unstable(feature = "async_fn_traits", issue = "none")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> for Box<F, A> {
     type CallRefFuture<'a>
         = F::CallRefFuture<'a>
@@ -2007,7 +2009,8 @@ impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> f
     }
 }
 
-#[unstable(feature = "async_fn_traits", issue = "none")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 impl<Args: Tuple, F: AsyncFn<Args> + ?Sized, A: Allocator> AsyncFn<Args> for Box<F, A> {
     extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> {
         F::async_call(self, args)
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index 5d3997e14e3..965fd63a529 100644
--- a/library/alloc/src/collections/binary_heap/mod.rs
+++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -155,9 +155,6 @@ use crate::collections::TryReserveError;
 use crate::slice;
 use crate::vec::{self, AsVecIntoIter, Vec};
 
-#[cfg(test)]
-mod tests;
-
 /// A priority queue implemented with a binary heap.
 ///
 /// This will be a max-heap.
@@ -534,8 +531,7 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
     /// heap.push(1);
     /// heap.push(5);
     /// heap.push(2);
-    /// {
-    ///     let mut val = heap.peek_mut().unwrap();
+    /// if let Some(mut val) = heap.peek_mut() {
     ///     *val = 0;
     /// }
     /// assert_eq!(heap.peek(), Some(&2));
diff --git a/library/alloc/src/collections/binary_heap/tests.rs b/library/alloc/src/collections/binary_heap/tests.rs
deleted file mode 100644
index ad0a020a1a9..00000000000
--- a/library/alloc/src/collections/binary_heap/tests.rs
+++ /dev/null
@@ -1,580 +0,0 @@
-use std::panic::{AssertUnwindSafe, catch_unwind};
-
-use super::*;
-use crate::boxed::Box;
-use crate::testing::crash_test::{CrashTestDummy, Panic};
-
-#[test]
-fn test_iterator() {
-    let data = vec![5, 9, 3];
-    let iterout = [9, 5, 3];
-    let heap = BinaryHeap::from(data);
-    let mut i = 0;
-    for el in &heap {
-        assert_eq!(*el, iterout[i]);
-        i += 1;
-    }
-}
-
-#[test]
-fn test_iter_rev_cloned_collect() {
-    let data = vec![5, 9, 3];
-    let iterout = vec![3, 5, 9];
-    let pq = BinaryHeap::from(data);
-
-    let v: Vec<_> = pq.iter().rev().cloned().collect();
-    assert_eq!(v, iterout);
-}
-
-#[test]
-fn test_into_iter_collect() {
-    let data = vec![5, 9, 3];
-    let iterout = vec![9, 5, 3];
-    let pq = BinaryHeap::from(data);
-
-    let v: Vec<_> = pq.into_iter().collect();
-    assert_eq!(v, iterout);
-}
-
-#[test]
-fn test_into_iter_size_hint() {
-    let data = vec![5, 9];
-    let pq = BinaryHeap::from(data);
-
-    let mut it = pq.into_iter();
-
-    assert_eq!(it.size_hint(), (2, Some(2)));
-    assert_eq!(it.next(), Some(9));
-
-    assert_eq!(it.size_hint(), (1, Some(1)));
-    assert_eq!(it.next(), Some(5));
-
-    assert_eq!(it.size_hint(), (0, Some(0)));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_into_iter_rev_collect() {
-    let data = vec![5, 9, 3];
-    let iterout = vec![3, 5, 9];
-    let pq = BinaryHeap::from(data);
-
-    let v: Vec<_> = pq.into_iter().rev().collect();
-    assert_eq!(v, iterout);
-}
-
-#[test]
-fn test_into_iter_sorted_collect() {
-    let heap = BinaryHeap::from(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
-    let it = heap.into_iter_sorted();
-    let sorted = it.collect::<Vec<_>>();
-    assert_eq!(sorted, vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 1, 1, 0]);
-}
-
-#[test]
-fn test_drain_sorted_collect() {
-    let mut heap = BinaryHeap::from(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
-    let it = heap.drain_sorted();
-    let sorted = it.collect::<Vec<_>>();
-    assert_eq!(sorted, vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 1, 1, 0]);
-}
-
-fn check_exact_size_iterator<I: ExactSizeIterator>(len: usize, it: I) {
-    let mut it = it;
-
-    for i in 0..it.len() {
-        let (lower, upper) = it.size_hint();
-        assert_eq!(Some(lower), upper);
-        assert_eq!(lower, len - i);
-        assert_eq!(it.len(), len - i);
-        it.next();
-    }
-    assert_eq!(it.len(), 0);
-    assert!(it.is_empty());
-}
-
-#[test]
-fn test_exact_size_iterator() {
-    let heap = BinaryHeap::from(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
-    check_exact_size_iterator(heap.len(), heap.iter());
-    check_exact_size_iterator(heap.len(), heap.clone().into_iter());
-    check_exact_size_iterator(heap.len(), heap.clone().into_iter_sorted());
-    check_exact_size_iterator(heap.len(), heap.clone().drain());
-    check_exact_size_iterator(heap.len(), heap.clone().drain_sorted());
-}
-
-fn check_trusted_len<I: TrustedLen>(len: usize, it: I) {
-    let mut it = it;
-    for i in 0..len {
-        let (lower, upper) = it.size_hint();
-        if upper.is_some() {
-            assert_eq!(Some(lower), upper);
-            assert_eq!(lower, len - i);
-        }
-        it.next();
-    }
-}
-
-#[test]
-fn test_trusted_len() {
-    let heap = BinaryHeap::from(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
-    check_trusted_len(heap.len(), heap.clone().into_iter_sorted());
-    check_trusted_len(heap.len(), heap.clone().drain_sorted());
-}
-
-#[test]
-fn test_peek_and_pop() {
-    let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
-    let mut sorted = data.clone();
-    sorted.sort();
-    let mut heap = BinaryHeap::from(data);
-    while !heap.is_empty() {
-        assert_eq!(heap.peek().unwrap(), sorted.last().unwrap());
-        assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
-    }
-}
-
-#[test]
-fn test_peek_mut() {
-    let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
-    let mut heap = BinaryHeap::from(data);
-    assert_eq!(heap.peek(), Some(&10));
-    {
-        let mut top = heap.peek_mut().unwrap();
-        *top -= 2;
-    }
-    assert_eq!(heap.peek(), Some(&9));
-}
-
-#[test]
-fn test_peek_mut_leek() {
-    let data = vec![4, 2, 7];
-    let mut heap = BinaryHeap::from(data);
-    let mut max = heap.peek_mut().unwrap();
-    *max = -1;
-
-    // The PeekMut object's Drop impl would have been responsible for moving the
-    // -1 out of the max position of the BinaryHeap, but we don't run it.
-    mem::forget(max);
-
-    // Absent some mitigation like leak amplification, the -1 would incorrectly
-    // end up in the last position of the returned Vec, with the rest of the
-    // heap's original contents in front of it in sorted order.
-    let sorted_vec = heap.into_sorted_vec();
-    assert!(sorted_vec.is_sorted(), "{:?}", sorted_vec);
-}
-
-#[test]
-fn test_peek_mut_pop() {
-    let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
-    let mut heap = BinaryHeap::from(data);
-    assert_eq!(heap.peek(), Some(&10));
-    {
-        let mut top = heap.peek_mut().unwrap();
-        *top -= 2;
-        assert_eq!(PeekMut::pop(top), 8);
-    }
-    assert_eq!(heap.peek(), Some(&9));
-}
-
-#[test]
-fn test_push() {
-    let mut heap = BinaryHeap::from(vec![2, 4, 9]);
-    assert_eq!(heap.len(), 3);
-    assert!(*heap.peek().unwrap() == 9);
-    heap.push(11);
-    assert_eq!(heap.len(), 4);
-    assert!(*heap.peek().unwrap() == 11);
-    heap.push(5);
-    assert_eq!(heap.len(), 5);
-    assert!(*heap.peek().unwrap() == 11);
-    heap.push(27);
-    assert_eq!(heap.len(), 6);
-    assert!(*heap.peek().unwrap() == 27);
-    heap.push(3);
-    assert_eq!(heap.len(), 7);
-    assert!(*heap.peek().unwrap() == 27);
-    heap.push(103);
-    assert_eq!(heap.len(), 8);
-    assert!(*heap.peek().unwrap() == 103);
-}
-
-#[test]
-fn test_push_unique() {
-    let mut heap = BinaryHeap::<Box<_>>::from(vec![Box::new(2), Box::new(4), Box::new(9)]);
-    assert_eq!(heap.len(), 3);
-    assert!(**heap.peek().unwrap() == 9);
-    heap.push(Box::new(11));
-    assert_eq!(heap.len(), 4);
-    assert!(**heap.peek().unwrap() == 11);
-    heap.push(Box::new(5));
-    assert_eq!(heap.len(), 5);
-    assert!(**heap.peek().unwrap() == 11);
-    heap.push(Box::new(27));
-    assert_eq!(heap.len(), 6);
-    assert!(**heap.peek().unwrap() == 27);
-    heap.push(Box::new(3));
-    assert_eq!(heap.len(), 7);
-    assert!(**heap.peek().unwrap() == 27);
-    heap.push(Box::new(103));
-    assert_eq!(heap.len(), 8);
-    assert!(**heap.peek().unwrap() == 103);
-}
-
-fn check_to_vec(mut data: Vec<i32>) {
-    let heap = BinaryHeap::from(data.clone());
-    let mut v = heap.clone().into_vec();
-    v.sort();
-    data.sort();
-
-    assert_eq!(v, data);
-    assert_eq!(heap.into_sorted_vec(), data);
-}
-
-#[test]
-fn test_to_vec() {
-    check_to_vec(vec![]);
-    check_to_vec(vec![5]);
-    check_to_vec(vec![3, 2]);
-    check_to_vec(vec![2, 3]);
-    check_to_vec(vec![5, 1, 2]);
-    check_to_vec(vec![1, 100, 2, 3]);
-    check_to_vec(vec![1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
-    check_to_vec(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
-    check_to_vec(vec![9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
-    check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
-    check_to_vec(vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
-    check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
-    check_to_vec(vec![5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
-}
-
-#[test]
-fn test_in_place_iterator_specialization() {
-    let src: Vec<usize> = vec![1, 2, 3];
-    let src_ptr = src.as_ptr();
-    let heap: BinaryHeap<_> = src.into_iter().map(std::convert::identity).collect();
-    let heap_ptr = heap.iter().next().unwrap() as *const usize;
-    assert_eq!(src_ptr, heap_ptr);
-    let sink: Vec<_> = heap.into_iter().map(std::convert::identity).collect();
-    let sink_ptr = sink.as_ptr();
-    assert_eq!(heap_ptr, sink_ptr);
-}
-
-#[test]
-fn test_empty_pop() {
-    let mut heap = BinaryHeap::<i32>::new();
-    assert!(heap.pop().is_none());
-}
-
-#[test]
-fn test_empty_peek() {
-    let empty = BinaryHeap::<i32>::new();
-    assert!(empty.peek().is_none());
-}
-
-#[test]
-fn test_empty_peek_mut() {
-    let mut empty = BinaryHeap::<i32>::new();
-    assert!(empty.peek_mut().is_none());
-}
-
-#[test]
-fn test_from_iter() {
-    let xs = vec![9, 8, 7, 6, 5, 4, 3, 2, 1];
-
-    let mut q: BinaryHeap<_> = xs.iter().rev().cloned().collect();
-
-    for &x in &xs {
-        assert_eq!(q.pop().unwrap(), x);
-    }
-}
-
-#[test]
-fn test_drain() {
-    let mut q: BinaryHeap<_> = [9, 8, 7, 6, 5, 4, 3, 2, 1].iter().cloned().collect();
-
-    assert_eq!(q.drain().take(5).count(), 5);
-
-    assert!(q.is_empty());
-}
-
-#[test]
-fn test_drain_sorted() {
-    let mut q: BinaryHeap<_> = [9, 8, 7, 6, 5, 4, 3, 2, 1].iter().cloned().collect();
-
-    assert_eq!(q.drain_sorted().take(5).collect::<Vec<_>>(), vec![9, 8, 7, 6, 5]);
-
-    assert!(q.is_empty());
-}
-
-#[test]
-#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
-fn test_drain_sorted_leak() {
-    let d0 = CrashTestDummy::new(0);
-    let d1 = CrashTestDummy::new(1);
-    let d2 = CrashTestDummy::new(2);
-    let d3 = CrashTestDummy::new(3);
-    let d4 = CrashTestDummy::new(4);
-    let d5 = CrashTestDummy::new(5);
-    let mut q = BinaryHeap::from(vec![
-        d0.spawn(Panic::Never),
-        d1.spawn(Panic::Never),
-        d2.spawn(Panic::Never),
-        d3.spawn(Panic::InDrop),
-        d4.spawn(Panic::Never),
-        d5.spawn(Panic::Never),
-    ]);
-
-    catch_unwind(AssertUnwindSafe(|| drop(q.drain_sorted()))).unwrap_err();
-
-    assert_eq!(d0.dropped(), 1);
-    assert_eq!(d1.dropped(), 1);
-    assert_eq!(d2.dropped(), 1);
-    assert_eq!(d3.dropped(), 1);
-    assert_eq!(d4.dropped(), 1);
-    assert_eq!(d5.dropped(), 1);
-    assert!(q.is_empty());
-}
-
-#[test]
-fn test_drain_forget() {
-    let a = CrashTestDummy::new(0);
-    let b = CrashTestDummy::new(1);
-    let c = CrashTestDummy::new(2);
-    let mut q =
-        BinaryHeap::from(vec![a.spawn(Panic::Never), b.spawn(Panic::Never), c.spawn(Panic::Never)]);
-
-    catch_unwind(AssertUnwindSafe(|| {
-        let mut it = q.drain();
-        it.next();
-        mem::forget(it);
-    }))
-    .unwrap();
-    // Behavior after leaking is explicitly unspecified and order is arbitrary,
-    // so it's fine if these start failing, but probably worth knowing.
-    assert!(q.is_empty());
-    assert_eq!(a.dropped() + b.dropped() + c.dropped(), 1);
-    assert_eq!(a.dropped(), 0);
-    assert_eq!(b.dropped(), 0);
-    assert_eq!(c.dropped(), 1);
-    drop(q);
-    assert_eq!(a.dropped(), 0);
-    assert_eq!(b.dropped(), 0);
-    assert_eq!(c.dropped(), 1);
-}
-
-#[test]
-fn test_drain_sorted_forget() {
-    let a = CrashTestDummy::new(0);
-    let b = CrashTestDummy::new(1);
-    let c = CrashTestDummy::new(2);
-    let mut q =
-        BinaryHeap::from(vec![a.spawn(Panic::Never), b.spawn(Panic::Never), c.spawn(Panic::Never)]);
-
-    catch_unwind(AssertUnwindSafe(|| {
-        let mut it = q.drain_sorted();
-        it.next();
-        mem::forget(it);
-    }))
-    .unwrap();
-    // Behavior after leaking is explicitly unspecified,
-    // so it's fine if these start failing, but probably worth knowing.
-    assert_eq!(q.len(), 2);
-    assert_eq!(a.dropped(), 0);
-    assert_eq!(b.dropped(), 0);
-    assert_eq!(c.dropped(), 1);
-    drop(q);
-    assert_eq!(a.dropped(), 1);
-    assert_eq!(b.dropped(), 1);
-    assert_eq!(c.dropped(), 1);
-}
-
-#[test]
-fn test_extend_ref() {
-    let mut a = BinaryHeap::new();
-    a.push(1);
-    a.push(2);
-
-    a.extend(&[3, 4, 5]);
-
-    assert_eq!(a.len(), 5);
-    assert_eq!(a.into_sorted_vec(), [1, 2, 3, 4, 5]);
-
-    let mut a = BinaryHeap::new();
-    a.push(1);
-    a.push(2);
-    let mut b = BinaryHeap::new();
-    b.push(3);
-    b.push(4);
-    b.push(5);
-
-    a.extend(&b);
-
-    assert_eq!(a.len(), 5);
-    assert_eq!(a.into_sorted_vec(), [1, 2, 3, 4, 5]);
-}
-
-#[test]
-fn test_append() {
-    let mut a = BinaryHeap::from(vec![-10, 1, 2, 3, 3]);
-    let mut b = BinaryHeap::from(vec![-20, 5, 43]);
-
-    a.append(&mut b);
-
-    assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
-    assert!(b.is_empty());
-}
-
-#[test]
-fn test_append_to_empty() {
-    let mut a = BinaryHeap::new();
-    let mut b = BinaryHeap::from(vec![-20, 5, 43]);
-
-    a.append(&mut b);
-
-    assert_eq!(a.into_sorted_vec(), [-20, 5, 43]);
-    assert!(b.is_empty());
-}
-
-#[test]
-fn test_extend_specialization() {
-    let mut a = BinaryHeap::from(vec![-10, 1, 2, 3, 3]);
-    let b = BinaryHeap::from(vec![-20, 5, 43]);
-
-    a.extend(b);
-
-    assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
-}
-
-#[allow(dead_code)]
-fn assert_covariance() {
-    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
-        d
-    }
-}
-
-#[test]
-fn test_retain() {
-    let mut a = BinaryHeap::from(vec![100, 10, 50, 1, 2, 20, 30]);
-    a.retain(|&x| x != 2);
-
-    // Check that 20 moved into 10's place.
-    assert_eq!(a.clone().into_vec(), [100, 20, 50, 1, 10, 30]);
-
-    a.retain(|_| true);
-
-    assert_eq!(a.clone().into_vec(), [100, 20, 50, 1, 10, 30]);
-
-    a.retain(|&x| x < 50);
-
-    assert_eq!(a.clone().into_vec(), [30, 20, 10, 1]);
-
-    a.retain(|_| false);
-
-    assert!(a.is_empty());
-}
-
-#[test]
-#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
-fn test_retain_catch_unwind() {
-    let mut heap = BinaryHeap::from(vec![3, 1, 2]);
-
-    // Removes the 3, then unwinds out of retain.
-    let _ = catch_unwind(AssertUnwindSafe(|| {
-        heap.retain(|e| {
-            if *e == 1 {
-                panic!();
-            }
-            false
-        });
-    }));
-
-    // Naively this would be [1, 2] (an invalid heap) if BinaryHeap delegates to
-    // Vec's retain impl and then does not rebuild the heap after that unwinds.
-    assert_eq!(heap.into_vec(), [2, 1]);
-}
-
-// old binaryheap failed this test
-//
-// Integrity means that all elements are present after a comparison panics,
-// even if the order might not be correct.
-//
-// Destructors must be called exactly once per element.
-// FIXME: re-enable emscripten once it can unwind again
-#[test]
-#[cfg(not(target_os = "emscripten"))]
-#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
-fn panic_safe() {
-    use std::cmp;
-    use std::panic::{self, AssertUnwindSafe};
-    use std::sync::atomic::{AtomicUsize, Ordering};
-
-    use rand::seq::SliceRandom;
-
-    static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
-
-    #[derive(Eq, PartialEq, Ord, Clone, Debug)]
-    struct PanicOrd<T>(T, bool);
-
-    impl<T> Drop for PanicOrd<T> {
-        fn drop(&mut self) {
-            // update global drop count
-            DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
-        }
-    }
-
-    impl<T: PartialOrd> PartialOrd for PanicOrd<T> {
-        fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
-            if self.1 || other.1 {
-                panic!("Panicking comparison");
-            }
-            self.0.partial_cmp(&other.0)
-        }
-    }
-    let mut rng = crate::test_helpers::test_rng();
-    const DATASZ: usize = 32;
-    // Miri is too slow
-    let ntest = if cfg!(miri) { 1 } else { 10 };
-
-    // don't use 0 in the data -- we want to catch the zeroed-out case.
-    let data = (1..=DATASZ).collect::<Vec<_>>();
-
-    // since it's a fuzzy test, run several tries.
-    for _ in 0..ntest {
-        for i in 1..=DATASZ {
-            DROP_COUNTER.store(0, Ordering::SeqCst);
-
-            let mut panic_ords: Vec<_> =
-                data.iter().filter(|&&x| x != i).map(|&x| PanicOrd(x, false)).collect();
-            let panic_item = PanicOrd(i, true);
-
-            // heapify the sane items
-            panic_ords.shuffle(&mut rng);
-            let mut heap = BinaryHeap::from(panic_ords);
-            let inner_data;
-
-            {
-                // push the panicking item to the heap and catch the panic
-                let thread_result = {
-                    let mut heap_ref = AssertUnwindSafe(&mut heap);
-                    panic::catch_unwind(move || {
-                        heap_ref.push(panic_item);
-                    })
-                };
-                assert!(thread_result.is_err());
-
-                // Assert no elements were dropped
-                let drops = DROP_COUNTER.load(Ordering::SeqCst);
-                assert!(drops == 0, "Must not drop items. drops={}", drops);
-                inner_data = heap.clone().into_vec();
-                drop(heap);
-            }
-            let drops = DROP_COUNTER.load(Ordering::SeqCst);
-            assert_eq!(drops, DATASZ);
-
-            let mut data_sorted = inner_data.into_iter().map(|p| p.0).collect::<Vec<_>>();
-            data_sorted.sort();
-            assert_eq!(data_sorted, data);
-        }
-    }
-}
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index ca0ea1ec8b2..13168b7a39f 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1939,9 +1939,7 @@ pub struct ExtractIf<
     T: 'a,
     F: 'a,
     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
-> where
-    F: FnMut(&mut T) -> bool,
-{
+> {
     list: &'a mut LinkedList<T, A>,
     it: Option<NonNull<Node<T>>>,
     pred: F,
@@ -1979,10 +1977,7 @@ where
 }
 
 #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")]
-impl<T: fmt::Debug, F> fmt::Debug for ExtractIf<'_, T, F>
-where
-    F: FnMut(&mut T) -> bool,
-{
+impl<T: fmt::Debug, F> fmt::Debug for ExtractIf<'_, T, F> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("ExtractIf").field(&self.list).finish()
     }
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index cf51a84bb6f..0b6a55297e1 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -1869,7 +1869,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
     ///
     /// # Panics
     ///
-    /// Panics if `index` is greater than deque's length
+    /// Panics if `index` is strictly greater than deque's length
     ///
     /// # Examples
     ///
@@ -1884,6 +1884,9 @@ impl<T, A: Allocator> VecDeque<T, A> {
     ///
     /// vec_deque.insert(1, 'd');
     /// assert_eq!(vec_deque, &['a', 'd', 'b', 'c']);
+    ///
+    /// vec_deque.insert(4, 'e');
+    /// assert_eq!(vec_deque, &['a', 'd', 'b', 'c', 'e']);
     /// ```
     #[stable(feature = "deque_extras_15", since = "1.5.0")]
     #[track_caller]
@@ -1928,13 +1931,13 @@ impl<T, A: Allocator> VecDeque<T, A> {
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
-    /// buf.push_back(1);
-    /// buf.push_back(2);
-    /// buf.push_back(3);
-    /// assert_eq!(buf, [1, 2, 3]);
+    /// buf.push_back('a');
+    /// buf.push_back('b');
+    /// buf.push_back('c');
+    /// assert_eq!(buf, ['a', 'b', 'c']);
     ///
-    /// assert_eq!(buf.remove(1), Some(2));
-    /// assert_eq!(buf, [1, 3]);
+    /// assert_eq!(buf.remove(1), Some('b'));
+    /// assert_eq!(buf, ['a', 'c']);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_confusables("delete", "take")]
@@ -1982,10 +1985,10 @@ impl<T, A: Allocator> VecDeque<T, A> {
     /// ```
     /// use std::collections::VecDeque;
     ///
-    /// let mut buf: VecDeque<_> = [1, 2, 3].into();
+    /// let mut buf: VecDeque<_> = ['a', 'b', 'c'].into();
     /// let buf2 = buf.split_off(1);
-    /// assert_eq!(buf, [1]);
-    /// assert_eq!(buf2, [2, 3]);
+    /// assert_eq!(buf, ['a']);
+    /// assert_eq!(buf2, ['b', 'c']);
     /// ```
     #[inline]
     #[must_use = "use `.truncate()` if you don't need the other half"]
diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs
index 9c074383a5e..c7d6d8a55c2 100644
--- a/library/alloc/src/ffi/c_str.rs
+++ b/library/alloc/src/ffi/c_str.rs
@@ -1,8 +1,5 @@
 //! [`CString`] and its related types.
 
-#[cfg(test)]
-mod tests;
-
 use core::borrow::Borrow;
 use core::ffi::{CStr, c_char};
 use core::num::NonZero;
diff --git a/library/alloc/src/ffi/c_str/tests.rs b/library/alloc/src/ffi/c_str/tests.rs
deleted file mode 100644
index d6b797347c2..00000000000
--- a/library/alloc/src/ffi/c_str/tests.rs
+++ /dev/null
@@ -1,226 +0,0 @@
-use core::assert_matches::assert_matches;
-use core::ffi::FromBytesUntilNulError;
-#[allow(deprecated)]
-use core::hash::SipHasher13 as DefaultHasher;
-use core::hash::{Hash, Hasher};
-
-use super::*;
-
-#[test]
-fn c_to_rust() {
-    let data = b"123\0";
-    let ptr = data.as_ptr() as *const c_char;
-    unsafe {
-        assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123");
-        assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0");
-    }
-}
-
-#[test]
-fn simple() {
-    let s = CString::new("1234").unwrap();
-    assert_eq!(s.as_bytes(), b"1234");
-    assert_eq!(s.as_bytes_with_nul(), b"1234\0");
-}
-
-#[test]
-fn build_with_zero1() {
-    assert!(CString::new(&b"\0"[..]).is_err());
-}
-#[test]
-fn build_with_zero2() {
-    assert!(CString::new(vec![0]).is_err());
-}
-
-#[test]
-fn formatted() {
-    let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap();
-    assert_eq!(format!("{s:?}"), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#);
-}
-
-#[test]
-fn borrowed() {
-    unsafe {
-        let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
-        assert_eq!(s.to_bytes(), b"12");
-        assert_eq!(s.to_bytes_with_nul(), b"12\0");
-    }
-}
-
-#[test]
-fn to_owned() {
-    let data = b"123\0";
-    let ptr = data.as_ptr() as *const c_char;
-
-    let owned = unsafe { CStr::from_ptr(ptr).to_owned() };
-    assert_eq!(owned.as_bytes_with_nul(), data);
-}
-
-#[test]
-fn equal_hash() {
-    let data = b"123\xE2\xFA\xA6\0";
-    let ptr = data.as_ptr() as *const c_char;
-    let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) };
-
-    #[allow(deprecated)]
-    let mut s = DefaultHasher::new();
-    cstr.hash(&mut s);
-    let cstr_hash = s.finish();
-    #[allow(deprecated)]
-    let mut s = DefaultHasher::new();
-    CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s);
-    let cstring_hash = s.finish();
-
-    assert_eq!(cstr_hash, cstring_hash);
-}
-
-#[test]
-fn from_bytes_with_nul() {
-    let data = b"123\0";
-    let cstr = CStr::from_bytes_with_nul(data);
-    assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..]));
-    let cstr = CStr::from_bytes_with_nul(data);
-    assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..]));
-
-    unsafe {
-        let cstr = CStr::from_bytes_with_nul(data);
-        let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
-        assert_eq!(cstr, Ok(cstr_unchecked));
-    }
-}
-
-#[test]
-fn from_bytes_with_nul_unterminated() {
-    let data = b"123";
-    let cstr = CStr::from_bytes_with_nul(data);
-    assert!(cstr.is_err());
-}
-
-#[test]
-fn from_bytes_with_nul_interior() {
-    let data = b"1\023\0";
-    let cstr = CStr::from_bytes_with_nul(data);
-    assert!(cstr.is_err());
-}
-
-#[test]
-fn cstr_from_bytes_until_nul() {
-    // Test an empty slice. This should fail because it
-    // does not contain a nul byte.
-    let b = b"";
-    assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. }));
-
-    // Test a non-empty slice, that does not contain a nul byte.
-    let b = b"hello";
-    assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. }));
-
-    // Test an empty nul-terminated string
-    let b = b"\0";
-    let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
-    assert_eq!(r.to_bytes(), b"");
-
-    // Test a slice with the nul byte in the middle
-    let b = b"hello\0world!";
-    let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
-    assert_eq!(r.to_bytes(), b"hello");
-
-    // Test a slice with the nul byte at the end
-    let b = b"hello\0";
-    let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
-    assert_eq!(r.to_bytes(), b"hello");
-
-    // Test a slice with two nul bytes at the end
-    let b = b"hello\0\0";
-    let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
-    assert_eq!(r.to_bytes(), b"hello");
-
-    // Test a slice containing lots of nul bytes
-    let b = b"\0\0\0\0";
-    let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
-    assert_eq!(r.to_bytes(), b"");
-}
-
-#[test]
-fn into_boxed() {
-    let orig: &[u8] = b"Hello, world!\0";
-    let cstr = CStr::from_bytes_with_nul(orig).unwrap();
-    let boxed: Box<CStr> = Box::from(cstr);
-    let cstring = cstr.to_owned().into_boxed_c_str().into_c_string();
-    assert_eq!(cstr, &*boxed);
-    assert_eq!(&*boxed, &*cstring);
-    assert_eq!(&*cstring, cstr);
-}
-
-#[test]
-fn boxed_default() {
-    let boxed = <Box<CStr>>::default();
-    assert_eq!(boxed.to_bytes_with_nul(), &[0]);
-}
-
-#[test]
-fn test_c_str_clone_into() {
-    let mut c_string = c"lorem".to_owned();
-    let c_ptr = c_string.as_ptr();
-    let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap();
-    c_str.clone_into(&mut c_string);
-    assert_eq!(c_str, c_string.as_c_str());
-    // The exact same size shouldn't have needed to move its allocation
-    assert_eq!(c_ptr, c_string.as_ptr());
-}
-
-#[test]
-fn into_rc() {
-    let orig: &[u8] = b"Hello, world!\0";
-    let cstr = CStr::from_bytes_with_nul(orig).unwrap();
-    let rc: Rc<CStr> = Rc::from(cstr);
-    let arc: Arc<CStr> = Arc::from(cstr);
-
-    assert_eq!(&*rc, cstr);
-    assert_eq!(&*arc, cstr);
-
-    let rc2: Rc<CStr> = Rc::from(cstr.to_owned());
-    let arc2: Arc<CStr> = Arc::from(cstr.to_owned());
-
-    assert_eq!(&*rc2, cstr);
-    assert_eq!(&*arc2, cstr);
-}
-
-#[test]
-fn cstr_const_constructor() {
-    const CSTR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0") };
-
-    assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
-}
-
-#[test]
-fn cstr_index_from() {
-    let original = b"Hello, world!\0";
-    let cstr = CStr::from_bytes_with_nul(original).unwrap();
-    let result = CStr::from_bytes_with_nul(&original[7..]).unwrap();
-
-    assert_eq!(&cstr[7..], result);
-}
-
-#[test]
-#[should_panic]
-fn cstr_index_from_empty() {
-    let original = b"Hello, world!\0";
-    let cstr = CStr::from_bytes_with_nul(original).unwrap();
-    let _ = &cstr[original.len()..];
-}
-
-#[test]
-fn c_string_from_empty_string() {
-    let original = "";
-    let cstring = CString::new(original).unwrap();
-    assert_eq!(original.as_bytes(), cstring.as_bytes());
-    assert_eq!([b'\0'], cstring.as_bytes_with_nul());
-}
-
-#[test]
-fn c_str_from_empty_string() {
-    let original = b"\0";
-    let cstr = CStr::from_bytes_with_nul(original).unwrap();
-    assert_eq!([] as [u8; 0], cstr.to_bytes());
-    assert_eq!([b'\0'], cstr.to_bytes_with_nul());
-}
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 927c3aa23b9..40759cb0ba8 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -91,6 +91,7 @@
 //
 // Library features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(async_closure))]
 #![cfg_attr(test, feature(str_as_str))]
 #![feature(alloc_layout_extra)]
 #![feature(allocator_api)]
@@ -99,7 +100,6 @@
 #![feature(array_windows)]
 #![feature(ascii_char)]
 #![feature(assert_matches)]
-#![feature(async_closure)]
 #![feature(async_fn_traits)]
 #![feature(async_iterator)]
 #![feature(box_uninit_write)]
@@ -239,8 +239,6 @@ pub mod string;
 pub mod sync;
 #[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync)))]
 pub mod task;
-#[cfg(test)]
-mod tests;
 pub mod vec;
 
 #[doc(hidden)]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 7aa1457b1df..b7ec3af9818 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -795,7 +795,7 @@ impl<T, A: Allocator> Rc<T, A> {
         let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into();
         let init_ptr: NonNull<RcInner<T>> = uninit_ptr.cast();
 
-        let weak = Weak { ptr: init_ptr, alloc: alloc };
+        let weak = Weak { ptr: init_ptr, alloc };
 
         // It's important we don't give up ownership of the weak pointer, or
         // else the memory might be freed by the time `data_fn` returns. If
@@ -2232,12 +2232,20 @@ impl<T: ?Sized, A: Allocator> Deref for Rc<T, A> {
 #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
 unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Rc<T, A> {}
 
+//#[unstable(feature = "unique_rc_arc", issue = "112566")]
+#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
+unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for UniqueRc<T, A> {}
+
 #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
 unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {}
 
 #[unstable(feature = "deref_pure_trait", issue = "87121")]
 unsafe impl<T: ?Sized, A: Allocator> DerefPure for Rc<T, A> {}
 
+//#[unstable(feature = "unique_rc_arc", issue = "112566")]
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl<T: ?Sized, A: Allocator> DerefPure for UniqueRc<T, A> {}
+
 #[unstable(feature = "legacy_receiver_trait", issue = "none")]
 impl<T: ?Sized> LegacyReceiver for Rc<T> {}
 
@@ -3684,7 +3692,6 @@ fn data_offset_align(align: usize) -> usize {
 /// previous example, `UniqueRc` allows for more flexibility in the construction of cyclic data,
 /// including fallible or async constructors.
 #[unstable(feature = "unique_rc_arc", issue = "112566")]
-#[derive(Debug)]
 pub struct UniqueRc<
     T: ?Sized,
     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
@@ -3694,12 +3701,253 @@ pub struct UniqueRc<
     alloc: A,
 }
 
+// Not necessary for correctness since `UniqueRc` contains `NonNull`,
+// but having an explicit negative impl is nice for documentation purposes
+// and results in nicer error messages.
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> !Send for UniqueRc<T, A> {}
+
+// Not necessary for correctness since `UniqueRc` contains `NonNull`,
+// but having an explicit negative impl is nice for documentation purposes
+// and results in nicer error messages.
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> !Sync for UniqueRc<T, A> {}
+
 #[unstable(feature = "unique_rc_arc", issue = "112566")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<UniqueRc<U, A>>
     for UniqueRc<T, A>
 {
 }
 
+//#[unstable(feature = "unique_rc_arc", issue = "112566")]
+#[unstable(feature = "dispatch_from_dyn", issue = "none")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<UniqueRc<U>> for UniqueRc<T> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + fmt::Display, A: Allocator> fmt::Display for UniqueRc<T, A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + fmt::Debug, A: Allocator> fmt::Debug for UniqueRc<T, A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(&**self, f)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> fmt::Pointer for UniqueRc<T, A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Pointer::fmt(&(&raw const **self), f)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> borrow::Borrow<T> for UniqueRc<T, A> {
+    fn borrow(&self) -> &T {
+        &**self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> borrow::BorrowMut<T> for UniqueRc<T, A> {
+    fn borrow_mut(&mut self) -> &mut T {
+        &mut **self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> AsRef<T> for UniqueRc<T, A> {
+    fn as_ref(&self) -> &T {
+        &**self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> AsMut<T> for UniqueRc<T, A> {
+    fn as_mut(&mut self) -> &mut T {
+        &mut **self
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized, A: Allocator> Unpin for UniqueRc<T, A> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for UniqueRc<T, A> {
+    /// Equality for two `UniqueRc`s.
+    ///
+    /// Two `UniqueRc`s are equal if their inner values are equal.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five == UniqueRc::new(5));
+    /// ```
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        PartialEq::eq(&**self, &**other)
+    }
+
+    /// Inequality for two `UniqueRc`s.
+    ///
+    /// Two `UniqueRc`s are not equal if their inner values are not equal.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five != UniqueRc::new(6));
+    /// ```
+    #[inline]
+    fn ne(&self, other: &Self) -> bool {
+        PartialEq::ne(&**self, &**other)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for UniqueRc<T, A> {
+    /// Partial comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `partial_cmp()` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    /// use std::cmp::Ordering;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&UniqueRc::new(6)));
+    /// ```
+    #[inline(always)]
+    fn partial_cmp(&self, other: &UniqueRc<T, A>) -> Option<Ordering> {
+        (**self).partial_cmp(&**other)
+    }
+
+    /// Less-than comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `<` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five < UniqueRc::new(6));
+    /// ```
+    #[inline(always)]
+    fn lt(&self, other: &UniqueRc<T, A>) -> bool {
+        **self < **other
+    }
+
+    /// 'Less than or equal to' comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `<=` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five <= UniqueRc::new(5));
+    /// ```
+    #[inline(always)]
+    fn le(&self, other: &UniqueRc<T, A>) -> bool {
+        **self <= **other
+    }
+
+    /// Greater-than comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `>` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five > UniqueRc::new(4));
+    /// ```
+    #[inline(always)]
+    fn gt(&self, other: &UniqueRc<T, A>) -> bool {
+        **self > **other
+    }
+
+    /// 'Greater than or equal to' comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `>=` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert!(five >= UniqueRc::new(5));
+    /// ```
+    #[inline(always)]
+    fn ge(&self, other: &UniqueRc<T, A>) -> bool {
+        **self >= **other
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + Ord, A: Allocator> Ord for UniqueRc<T, A> {
+    /// Comparison for two `UniqueRc`s.
+    ///
+    /// The two are compared by calling `cmp()` on their inner values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unique_rc_arc)]
+    /// use std::rc::UniqueRc;
+    /// use std::cmp::Ordering;
+    ///
+    /// let five = UniqueRc::new(5);
+    ///
+    /// assert_eq!(Ordering::Less, five.cmp(&UniqueRc::new(6)));
+    /// ```
+    #[inline]
+    fn cmp(&self, other: &UniqueRc<T, A>) -> Ordering {
+        (**self).cmp(&**other)
+    }
+}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + Eq, A: Allocator> Eq for UniqueRc<T, A> {}
+
+#[unstable(feature = "unique_rc_arc", issue = "112566")]
+impl<T: ?Sized + Hash, A: Allocator> Hash for UniqueRc<T, A> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (**self).hash(state);
+    }
+}
+
 // Depends on A = Global
 impl<T> UniqueRc<T> {
     /// Creates a new `UniqueRc`.
@@ -3791,9 +4039,6 @@ impl<T: ?Sized, A: Allocator> Deref for UniqueRc<T, A> {
     }
 }
 
-#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
-unsafe impl<T: ?Sized> PinCoerceUnsized for UniqueRc<T> {}
-
 #[unstable(feature = "unique_rc_arc", issue = "112566")]
 impl<T: ?Sized, A: Allocator> DerefMut for UniqueRc<T, A> {
     fn deref_mut(&mut self) -> &mut T {
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index e3c7835f1d1..edc8d99f2f9 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -27,6 +27,8 @@ pub use core::slice::ArrayChunksMut;
 pub use core::slice::ArrayWindows;
 #[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
 pub use core::slice::EscapeAscii;
+#[unstable(feature = "get_many_mut", issue = "104642")]
+pub use core::slice::GetManyMutError;
 #[stable(feature = "slice_get_slice", since = "1.28.0")]
 pub use core::slice::SliceIndex;
 #[cfg(not(no_global_oom_handling))]
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index c5378d78d59..23d060d2158 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2675,12 +2675,25 @@ pub trait ToString {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: fmt::Display + ?Sized> ToString for T {
+    #[inline]
+    fn to_string(&self) -> String {
+        <Self as SpecToString>::spec_to_string(self)
+    }
+}
+
+#[cfg(not(no_global_oom_handling))]
+trait SpecToString {
+    fn spec_to_string(&self) -> String;
+}
+
+#[cfg(not(no_global_oom_handling))]
+impl<T: fmt::Display + ?Sized> SpecToString for T {
     // A common guideline is to not inline generic functions. However,
     // removing `#[inline]` from this method causes non-negligible regressions.
     // See <https://github.com/rust-lang/rust/pull/74852>, the last attempt
     // to try to remove it.
     #[inline]
-    default fn to_string(&self) -> String {
+    default fn spec_to_string(&self) -> String {
         let mut buf = String::new();
         let mut formatter =
             core::fmt::Formatter::new(&mut buf, core::fmt::FormattingOptions::new());
@@ -2691,42 +2704,34 @@ impl<T: fmt::Display + ?Sized> ToString for T {
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[unstable(feature = "ascii_char", issue = "110998")]
-impl ToString for core::ascii::Char {
+impl SpecToString for core::ascii::Char {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         self.as_str().to_owned()
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "char_to_string_specialization", since = "1.46.0")]
-impl ToString for char {
+impl SpecToString for char {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         String::from(self.encode_utf8(&mut [0; 4]))
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "bool_to_string_specialization", since = "1.68.0")]
-impl ToString for bool {
+impl SpecToString for bool {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         String::from(if *self { "true" } else { "false" })
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "u8_to_string_specialization", since = "1.54.0")]
-impl ToString for u8 {
+impl SpecToString for u8 {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         let mut buf = String::with_capacity(3);
         let mut n = *self;
         if n >= 10 {
@@ -2742,12 +2747,10 @@ impl ToString for u8 {
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "i8_to_string_specialization", since = "1.54.0")]
-impl ToString for i8 {
+impl SpecToString for i8 {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         let mut buf = String::with_capacity(4);
         if self.is_negative() {
             buf.push('-');
@@ -2788,11 +2791,9 @@ macro_rules! to_string_expr_wrap_in_deref {
 macro_rules! to_string_str {
     {$($($x:ident)*),+} => {
         $(
-            #[doc(hidden)]
-            #[stable(feature = "str_to_string_specialization", since = "1.9.0")]
-            impl ToString for to_string_str_wrap_in_ref!($($x)*) {
+            impl SpecToString for to_string_str_wrap_in_ref!($($x)*) {
                 #[inline]
-                fn to_string(&self) -> String {
+                fn spec_to_string(&self) -> String {
                     String::from(to_string_expr_wrap_in_deref!(self ; $($x)*))
                 }
             }
@@ -2816,32 +2817,26 @@ to_string_str! {
     x,
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "cow_str_to_string_specialization", since = "1.17.0")]
-impl ToString for Cow<'_, str> {
+impl SpecToString for Cow<'_, str> {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         self[..].to_owned()
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "string_to_string_specialization", since = "1.17.0")]
-impl ToString for String {
+impl SpecToString for String {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         self.to_owned()
     }
 }
 
-#[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "fmt_arguments_to_string_specialization", since = "1.71.0")]
-impl ToString for fmt::Arguments<'_> {
+impl SpecToString for fmt::Arguments<'_> {
     #[inline]
-    fn to_string(&self) -> String {
+    fn spec_to_string(&self) -> String {
         crate::fmt::format(*self)
     }
 }
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index b8bdd298c27..9be0b3e3e88 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -39,9 +39,6 @@ use crate::string::String;
 #[cfg(not(no_global_oom_handling))]
 use crate::vec::Vec;
 
-#[cfg(test)]
-mod tests;
-
 /// A soft limit on the amount of references that may be made to an `Arc`.
 ///
 /// Going above this limit will abort your program (although not
@@ -787,7 +784,7 @@ impl<T, A: Allocator> Arc<T, A> {
         let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into();
         let init_ptr: NonNull<ArcInner<T>> = uninit_ptr.cast();
 
-        let weak = Weak { ptr: init_ptr, alloc: alloc };
+        let weak = Weak { ptr: init_ptr, alloc };
 
         // It's important we don't give up ownership of the weak pointer, or
         // else the memory might be freed by the time `data_fn` returns. If
diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs
deleted file mode 100644
index de5816fda97..00000000000
--- a/library/alloc/src/sync/tests.rs
+++ /dev/null
@@ -1,717 +0,0 @@
-use std::clone::Clone;
-use std::mem::MaybeUninit;
-use std::option::Option::None;
-use std::sync::Mutex;
-use std::sync::atomic::AtomicUsize;
-use std::sync::atomic::Ordering::SeqCst;
-use std::sync::mpsc::channel;
-use std::thread;
-
-use super::*;
-
-struct Canary(*mut AtomicUsize);
-
-impl Drop for Canary {
-    fn drop(&mut self) {
-        unsafe {
-            match *self {
-                Canary(c) => {
-                    (*c).fetch_add(1, SeqCst);
-                }
-            }
-        }
-    }
-}
-
-struct AllocCanary<'a>(&'a AtomicUsize);
-
-impl<'a> AllocCanary<'a> {
-    fn new(counter: &'a AtomicUsize) -> Self {
-        counter.fetch_add(1, SeqCst);
-        Self(counter)
-    }
-}
-
-unsafe impl Allocator for AllocCanary<'_> {
-    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
-        std::alloc::Global.allocate(layout)
-    }
-
-    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
-        unsafe { std::alloc::Global.deallocate(ptr, layout) }
-    }
-}
-
-impl Clone for AllocCanary<'_> {
-    fn clone(&self) -> Self {
-        Self::new(self.0)
-    }
-}
-
-impl Drop for AllocCanary<'_> {
-    fn drop(&mut self) {
-        self.0.fetch_sub(1, SeqCst);
-    }
-}
-
-#[test]
-#[cfg_attr(target_os = "emscripten", ignore)]
-fn manually_share_arc() {
-    let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    let arc_v = Arc::new(v);
-
-    let (tx, rx) = channel();
-
-    let _t = thread::spawn(move || {
-        let arc_v: Arc<Vec<i32>> = rx.recv().unwrap();
-        assert_eq!((*arc_v)[3], 4);
-    });
-
-    tx.send(arc_v.clone()).unwrap();
-
-    assert_eq!((*arc_v)[2], 3);
-    assert_eq!((*arc_v)[4], 5);
-}
-
-#[test]
-fn test_arc_get_mut() {
-    let mut x = Arc::new(3);
-    *Arc::get_mut(&mut x).unwrap() = 4;
-    assert_eq!(*x, 4);
-    let y = x.clone();
-    assert!(Arc::get_mut(&mut x).is_none());
-    drop(y);
-    assert!(Arc::get_mut(&mut x).is_some());
-    let _w = Arc::downgrade(&x);
-    assert!(Arc::get_mut(&mut x).is_none());
-}
-
-#[test]
-fn weak_counts() {
-    assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
-    assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
-
-    let a = Arc::new(0);
-    let w = Arc::downgrade(&a);
-    assert_eq!(Weak::strong_count(&w), 1);
-    assert_eq!(Weak::weak_count(&w), 1);
-    let w2 = w.clone();
-    assert_eq!(Weak::strong_count(&w), 1);
-    assert_eq!(Weak::weak_count(&w), 2);
-    assert_eq!(Weak::strong_count(&w2), 1);
-    assert_eq!(Weak::weak_count(&w2), 2);
-    drop(w);
-    assert_eq!(Weak::strong_count(&w2), 1);
-    assert_eq!(Weak::weak_count(&w2), 1);
-    let a2 = a.clone();
-    assert_eq!(Weak::strong_count(&w2), 2);
-    assert_eq!(Weak::weak_count(&w2), 1);
-    drop(a2);
-    drop(a);
-    assert_eq!(Weak::strong_count(&w2), 0);
-    assert_eq!(Weak::weak_count(&w2), 0);
-    drop(w2);
-}
-
-#[test]
-fn try_unwrap() {
-    let x = Arc::new(3);
-    assert_eq!(Arc::try_unwrap(x), Ok(3));
-    let x = Arc::new(4);
-    let _y = x.clone();
-    assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4)));
-    let x = Arc::new(5);
-    let _w = Arc::downgrade(&x);
-    assert_eq!(Arc::try_unwrap(x), Ok(5));
-}
-
-#[test]
-fn into_inner() {
-    for _ in 0..100
-    // ^ Increase chances of hitting potential race conditions
-    {
-        let x = Arc::new(3);
-        let y = Arc::clone(&x);
-        let r_thread = std::thread::spawn(|| Arc::into_inner(x));
-        let s_thread = std::thread::spawn(|| Arc::into_inner(y));
-        let r = r_thread.join().expect("r_thread panicked");
-        let s = s_thread.join().expect("s_thread panicked");
-        assert!(
-            matches!((r, s), (None, Some(3)) | (Some(3), None)),
-            "assertion failed: unexpected result `{:?}`\
-            \n  expected `(None, Some(3))` or `(Some(3), None)`",
-            (r, s),
-        );
-    }
-
-    let x = Arc::new(3);
-    assert_eq!(Arc::into_inner(x), Some(3));
-
-    let x = Arc::new(4);
-    let y = Arc::clone(&x);
-    assert_eq!(Arc::into_inner(x), None);
-    assert_eq!(Arc::into_inner(y), Some(4));
-
-    let x = Arc::new(5);
-    let _w = Arc::downgrade(&x);
-    assert_eq!(Arc::into_inner(x), Some(5));
-}
-
-#[test]
-fn into_from_raw() {
-    let x = Arc::new(Box::new("hello"));
-    let y = x.clone();
-
-    let x_ptr = Arc::into_raw(x);
-    drop(y);
-    unsafe {
-        assert_eq!(**x_ptr, "hello");
-
-        let x = Arc::from_raw(x_ptr);
-        assert_eq!(**x, "hello");
-
-        assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello"));
-    }
-}
-
-#[test]
-fn test_into_from_raw_unsized() {
-    use std::fmt::Display;
-    use std::string::ToString;
-
-    let arc: Arc<str> = Arc::from("foo");
-
-    let ptr = Arc::into_raw(arc.clone());
-    let arc2 = unsafe { Arc::from_raw(ptr) };
-
-    assert_eq!(unsafe { &*ptr }, "foo");
-    assert_eq!(arc, arc2);
-
-    let arc: Arc<dyn Display> = Arc::new(123);
-
-    let ptr = Arc::into_raw(arc.clone());
-    let arc2 = unsafe { Arc::from_raw(ptr) };
-
-    assert_eq!(unsafe { &*ptr }.to_string(), "123");
-    assert_eq!(arc2.to_string(), "123");
-}
-
-#[test]
-fn into_from_weak_raw() {
-    let x = Arc::new(Box::new("hello"));
-    let y = Arc::downgrade(&x);
-
-    let y_ptr = Weak::into_raw(y);
-    unsafe {
-        assert_eq!(**y_ptr, "hello");
-
-        let y = Weak::from_raw(y_ptr);
-        let y_up = Weak::upgrade(&y).unwrap();
-        assert_eq!(**y_up, "hello");
-        drop(y_up);
-
-        assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello"));
-    }
-}
-
-#[test]
-fn test_into_from_weak_raw_unsized() {
-    use std::fmt::Display;
-    use std::string::ToString;
-
-    let arc: Arc<str> = Arc::from("foo");
-    let weak: Weak<str> = Arc::downgrade(&arc);
-
-    let ptr = Weak::into_raw(weak.clone());
-    let weak2 = unsafe { Weak::from_raw(ptr) };
-
-    assert_eq!(unsafe { &*ptr }, "foo");
-    assert!(weak.ptr_eq(&weak2));
-
-    let arc: Arc<dyn Display> = Arc::new(123);
-    let weak: Weak<dyn Display> = Arc::downgrade(&arc);
-
-    let ptr = Weak::into_raw(weak.clone());
-    let weak2 = unsafe { Weak::from_raw(ptr) };
-
-    assert_eq!(unsafe { &*ptr }.to_string(), "123");
-    assert!(weak.ptr_eq(&weak2));
-}
-
-#[test]
-fn test_cowarc_clone_make_mut() {
-    let mut cow0 = Arc::new(75);
-    let mut cow1 = cow0.clone();
-    let mut cow2 = cow1.clone();
-
-    assert!(75 == *Arc::make_mut(&mut cow0));
-    assert!(75 == *Arc::make_mut(&mut cow1));
-    assert!(75 == *Arc::make_mut(&mut cow2));
-
-    *Arc::make_mut(&mut cow0) += 1;
-    *Arc::make_mut(&mut cow1) += 2;
-    *Arc::make_mut(&mut cow2) += 3;
-
-    assert!(76 == *cow0);
-    assert!(77 == *cow1);
-    assert!(78 == *cow2);
-
-    // none should point to the same backing memory
-    assert!(*cow0 != *cow1);
-    assert!(*cow0 != *cow2);
-    assert!(*cow1 != *cow2);
-}
-
-#[test]
-fn test_cowarc_clone_unique2() {
-    let mut cow0 = Arc::new(75);
-    let cow1 = cow0.clone();
-    let cow2 = cow1.clone();
-
-    assert!(75 == *cow0);
-    assert!(75 == *cow1);
-    assert!(75 == *cow2);
-
-    *Arc::make_mut(&mut cow0) += 1;
-    assert!(76 == *cow0);
-    assert!(75 == *cow1);
-    assert!(75 == *cow2);
-
-    // cow1 and cow2 should share the same contents
-    // cow0 should have a unique reference
-    assert!(*cow0 != *cow1);
-    assert!(*cow0 != *cow2);
-    assert!(*cow1 == *cow2);
-}
-
-#[test]
-fn test_cowarc_clone_weak() {
-    let mut cow0 = Arc::new(75);
-    let cow1_weak = Arc::downgrade(&cow0);
-
-    assert!(75 == *cow0);
-    assert!(75 == *cow1_weak.upgrade().unwrap());
-
-    *Arc::make_mut(&mut cow0) += 1;
-
-    assert!(76 == *cow0);
-    assert!(cow1_weak.upgrade().is_none());
-}
-
-#[test]
-fn test_live() {
-    let x = Arc::new(5);
-    let y = Arc::downgrade(&x);
-    assert!(y.upgrade().is_some());
-}
-
-#[test]
-fn test_dead() {
-    let x = Arc::new(5);
-    let y = Arc::downgrade(&x);
-    drop(x);
-    assert!(y.upgrade().is_none());
-}
-
-#[test]
-fn weak_self_cyclic() {
-    struct Cycle {
-        x: Mutex<Option<Weak<Cycle>>>,
-    }
-
-    let a = Arc::new(Cycle { x: Mutex::new(None) });
-    let b = Arc::downgrade(&a.clone());
-    *a.x.lock().unwrap() = Some(b);
-
-    // hopefully we don't double-free (or leak)...
-}
-
-#[test]
-fn drop_arc() {
-    let mut canary = AtomicUsize::new(0);
-    let x = Arc::new(Canary(&mut canary as *mut AtomicUsize));
-    drop(x);
-    assert!(canary.load(Acquire) == 1);
-}
-
-#[test]
-fn drop_arc_weak() {
-    let mut canary = AtomicUsize::new(0);
-    let arc = Arc::new(Canary(&mut canary as *mut AtomicUsize));
-    let arc_weak = Arc::downgrade(&arc);
-    assert!(canary.load(Acquire) == 0);
-    drop(arc);
-    assert!(canary.load(Acquire) == 1);
-    drop(arc_weak);
-}
-
-#[test]
-fn test_strong_count() {
-    let a = Arc::new(0);
-    assert!(Arc::strong_count(&a) == 1);
-    let w = Arc::downgrade(&a);
-    assert!(Arc::strong_count(&a) == 1);
-    let b = w.upgrade().expect("");
-    assert!(Arc::strong_count(&b) == 2);
-    assert!(Arc::strong_count(&a) == 2);
-    drop(w);
-    drop(a);
-    assert!(Arc::strong_count(&b) == 1);
-    let c = b.clone();
-    assert!(Arc::strong_count(&b) == 2);
-    assert!(Arc::strong_count(&c) == 2);
-}
-
-#[test]
-fn test_weak_count() {
-    let a = Arc::new(0);
-    assert!(Arc::strong_count(&a) == 1);
-    assert!(Arc::weak_count(&a) == 0);
-    let w = Arc::downgrade(&a);
-    assert!(Arc::strong_count(&a) == 1);
-    assert!(Arc::weak_count(&a) == 1);
-    let x = w.clone();
-    assert!(Arc::weak_count(&a) == 2);
-    drop(w);
-    drop(x);
-    assert!(Arc::strong_count(&a) == 1);
-    assert!(Arc::weak_count(&a) == 0);
-    let c = a.clone();
-    assert!(Arc::strong_count(&a) == 2);
-    assert!(Arc::weak_count(&a) == 0);
-    let d = Arc::downgrade(&c);
-    assert!(Arc::weak_count(&c) == 1);
-    assert!(Arc::strong_count(&c) == 2);
-
-    drop(a);
-    drop(c);
-    drop(d);
-}
-
-#[test]
-fn show_arc() {
-    let a = Arc::new(5);
-    assert_eq!(format!("{a:?}"), "5");
-}
-
-// Make sure deriving works with Arc<T>
-#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
-struct _Foo {
-    inner: Arc<i32>,
-}
-
-#[test]
-fn test_unsized() {
-    let x: Arc<[i32]> = Arc::new([1, 2, 3]);
-    assert_eq!(format!("{x:?}"), "[1, 2, 3]");
-    let y = Arc::downgrade(&x.clone());
-    drop(x);
-    assert!(y.upgrade().is_none());
-}
-
-#[test]
-fn test_maybe_thin_unsized() {
-    // If/when custom thin DSTs exist, this test should be updated to use one
-    use std::ffi::CStr;
-
-    let x: Arc<CStr> = Arc::from(c"swordfish");
-    assert_eq!(format!("{x:?}"), "\"swordfish\"");
-    let y: Weak<CStr> = Arc::downgrade(&x);
-    drop(x);
-
-    // At this point, the weak points to a dropped DST
-    assert!(y.upgrade().is_none());
-    // But we still need to be able to get the alloc layout to drop.
-    // CStr has no drop glue, but custom DSTs might, and need to work.
-    drop(y);
-}
-
-#[test]
-fn test_from_owned() {
-    let foo = 123;
-    let foo_arc = Arc::from(foo);
-    assert!(123 == *foo_arc);
-}
-
-#[test]
-fn test_new_weak() {
-    let foo: Weak<usize> = Weak::new();
-    assert!(foo.upgrade().is_none());
-}
-
-#[test]
-fn test_ptr_eq() {
-    let five = Arc::new(5);
-    let same_five = five.clone();
-    let other_five = Arc::new(5);
-
-    assert!(Arc::ptr_eq(&five, &same_five));
-    assert!(!Arc::ptr_eq(&five, &other_five));
-}
-
-#[test]
-#[cfg_attr(target_os = "emscripten", ignore)]
-fn test_weak_count_locked() {
-    let mut a = Arc::new(atomic::AtomicBool::new(false));
-    let a2 = a.clone();
-    let t = thread::spawn(move || {
-        // Miri is too slow
-        let count = if cfg!(miri) { 1000 } else { 1000000 };
-        for _i in 0..count {
-            Arc::get_mut(&mut a);
-        }
-        a.store(true, SeqCst);
-    });
-
-    while !a2.load(SeqCst) {
-        let n = Arc::weak_count(&a2);
-        assert!(n < 2, "bad weak count: {}", n);
-        #[cfg(miri)] // Miri's scheduler does not guarantee liveness, and thus needs this hint.
-        std::hint::spin_loop();
-    }
-    t.join().unwrap();
-}
-
-#[test]
-fn test_from_str() {
-    let r: Arc<str> = Arc::from("foo");
-
-    assert_eq!(&r[..], "foo");
-}
-
-#[test]
-fn test_copy_from_slice() {
-    let s: &[u32] = &[1, 2, 3];
-    let r: Arc<[u32]> = Arc::from(s);
-
-    assert_eq!(&r[..], [1, 2, 3]);
-}
-
-#[test]
-fn test_clone_from_slice() {
-    #[derive(Clone, Debug, Eq, PartialEq)]
-    struct X(u32);
-
-    let s: &[X] = &[X(1), X(2), X(3)];
-    let r: Arc<[X]> = Arc::from(s);
-
-    assert_eq!(&r[..], s);
-}
-
-#[test]
-#[should_panic]
-fn test_clone_from_slice_panic() {
-    use std::string::{String, ToString};
-
-    struct Fail(u32, String);
-
-    impl Clone for Fail {
-        fn clone(&self) -> Fail {
-            if self.0 == 2 {
-                panic!();
-            }
-            Fail(self.0, self.1.clone())
-        }
-    }
-
-    let s: &[Fail] =
-        &[Fail(0, "foo".to_string()), Fail(1, "bar".to_string()), Fail(2, "baz".to_string())];
-
-    // Should panic, but not cause memory corruption
-    let _r: Arc<[Fail]> = Arc::from(s);
-}
-
-#[test]
-fn test_from_box() {
-    let b: Box<u32> = Box::new(123);
-    let r: Arc<u32> = Arc::from(b);
-
-    assert_eq!(*r, 123);
-}
-
-#[test]
-fn test_from_box_str() {
-    use std::string::String;
-
-    let s = String::from("foo").into_boxed_str();
-    let r: Arc<str> = Arc::from(s);
-
-    assert_eq!(&r[..], "foo");
-}
-
-#[test]
-fn test_from_box_slice() {
-    let s = vec![1, 2, 3].into_boxed_slice();
-    let r: Arc<[u32]> = Arc::from(s);
-
-    assert_eq!(&r[..], [1, 2, 3]);
-}
-
-#[test]
-fn test_from_box_trait() {
-    use std::fmt::Display;
-    use std::string::ToString;
-
-    let b: Box<dyn Display> = Box::new(123);
-    let r: Arc<dyn Display> = Arc::from(b);
-
-    assert_eq!(r.to_string(), "123");
-}
-
-#[test]
-fn test_from_box_trait_zero_sized() {
-    use std::fmt::Debug;
-
-    let b: Box<dyn Debug> = Box::new(());
-    let r: Arc<dyn Debug> = Arc::from(b);
-
-    assert_eq!(format!("{r:?}"), "()");
-}
-
-#[test]
-fn test_from_vec() {
-    let v = vec![1, 2, 3];
-    let r: Arc<[u32]> = Arc::from(v);
-
-    assert_eq!(&r[..], [1, 2, 3]);
-}
-
-#[test]
-fn test_downcast() {
-    use std::any::Any;
-
-    let r1: Arc<dyn Any + Send + Sync> = Arc::new(i32::MAX);
-    let r2: Arc<dyn Any + Send + Sync> = Arc::new("abc");
-
-    assert!(r1.clone().downcast::<u32>().is_err());
-
-    let r1i32 = r1.downcast::<i32>();
-    assert!(r1i32.is_ok());
-    assert_eq!(r1i32.unwrap(), Arc::new(i32::MAX));
-
-    assert!(r2.clone().downcast::<i32>().is_err());
-
-    let r2str = r2.downcast::<&'static str>();
-    assert!(r2str.is_ok());
-    assert_eq!(r2str.unwrap(), Arc::new("abc"));
-}
-
-#[test]
-fn test_array_from_slice() {
-    let v = vec![1, 2, 3];
-    let r: Arc<[u32]> = Arc::from(v);
-
-    let a: Result<Arc<[u32; 3]>, _> = r.clone().try_into();
-    assert!(a.is_ok());
-
-    let a: Result<Arc<[u32; 2]>, _> = r.clone().try_into();
-    assert!(a.is_err());
-}
-
-#[test]
-fn test_arc_cyclic_with_zero_refs() {
-    struct ZeroRefs {
-        inner: Weak<ZeroRefs>,
-    }
-    let zero_refs = Arc::new_cyclic(|inner| {
-        assert_eq!(inner.strong_count(), 0);
-        assert!(inner.upgrade().is_none());
-        ZeroRefs { inner: Weak::new() }
-    });
-
-    assert_eq!(Arc::strong_count(&zero_refs), 1);
-    assert_eq!(Arc::weak_count(&zero_refs), 0);
-    assert_eq!(zero_refs.inner.strong_count(), 0);
-    assert_eq!(zero_refs.inner.weak_count(), 0);
-}
-
-#[test]
-fn test_arc_new_cyclic_one_ref() {
-    struct OneRef {
-        inner: Weak<OneRef>,
-    }
-    let one_ref = Arc::new_cyclic(|inner| {
-        assert_eq!(inner.strong_count(), 0);
-        assert!(inner.upgrade().is_none());
-        OneRef { inner: inner.clone() }
-    });
-
-    assert_eq!(Arc::strong_count(&one_ref), 1);
-    assert_eq!(Arc::weak_count(&one_ref), 1);
-
-    let one_ref2 = Weak::upgrade(&one_ref.inner).unwrap();
-    assert!(Arc::ptr_eq(&one_ref, &one_ref2));
-
-    assert_eq!(Arc::strong_count(&one_ref), 2);
-    assert_eq!(Arc::weak_count(&one_ref), 1);
-}
-
-#[test]
-fn test_arc_cyclic_two_refs() {
-    struct TwoRefs {
-        inner1: Weak<TwoRefs>,
-        inner2: Weak<TwoRefs>,
-    }
-    let two_refs = Arc::new_cyclic(|inner| {
-        assert_eq!(inner.strong_count(), 0);
-        assert!(inner.upgrade().is_none());
-
-        let inner1 = inner.clone();
-        let inner2 = inner1.clone();
-
-        TwoRefs { inner1, inner2 }
-    });
-
-    assert_eq!(Arc::strong_count(&two_refs), 1);
-    assert_eq!(Arc::weak_count(&two_refs), 2);
-
-    let two_refs1 = Weak::upgrade(&two_refs.inner1).unwrap();
-    assert!(Arc::ptr_eq(&two_refs, &two_refs1));
-
-    let two_refs2 = Weak::upgrade(&two_refs.inner2).unwrap();
-    assert!(Arc::ptr_eq(&two_refs, &two_refs2));
-
-    assert_eq!(Arc::strong_count(&two_refs), 3);
-    assert_eq!(Arc::weak_count(&two_refs), 2);
-}
-
-/// Test for Arc::drop bug (https://github.com/rust-lang/rust/issues/55005)
-#[test]
-#[cfg(miri)] // relies on Stacked Borrows in Miri
-fn arc_drop_dereferenceable_race() {
-    // The bug seems to take up to 700 iterations to reproduce with most seeds (tested 0-9).
-    for _ in 0..750 {
-        let arc_1 = Arc::new(());
-        let arc_2 = arc_1.clone();
-        let thread = thread::spawn(|| drop(arc_2));
-        // Spin a bit; makes the race more likely to appear
-        let mut i = 0;
-        while i < 256 {
-            i += 1;
-        }
-        drop(arc_1);
-        thread.join().unwrap();
-    }
-}
-
-#[test]
-fn arc_doesnt_leak_allocator() {
-    let counter = AtomicUsize::new(0);
-
-    {
-        let arc: Arc<dyn Any + Send + Sync, _> = Arc::new_in(5usize, AllocCanary::new(&counter));
-        drop(arc.downcast::<usize>().unwrap());
-
-        let arc: Arc<dyn Any + Send + Sync, _> = Arc::new_in(5usize, AllocCanary::new(&counter));
-        drop(unsafe { arc.downcast_unchecked::<usize>() });
-
-        let arc = Arc::new_in(MaybeUninit::<usize>::new(5usize), AllocCanary::new(&counter));
-        drop(unsafe { arc.assume_init() });
-
-        let arc: Arc<[MaybeUninit<usize>], _> =
-            Arc::new_zeroed_slice_in(5, AllocCanary::new(&counter));
-        drop(unsafe { arc.assume_init() });
-    }
-
-    assert_eq!(counter.load(SeqCst), 0);
-}
diff --git a/library/alloc/src/tests.rs b/library/alloc/src/tests.rs
deleted file mode 100644
index b95d11cb07e..00000000000
--- a/library/alloc/src/tests.rs
+++ /dev/null
@@ -1,140 +0,0 @@
-//! Test for `boxed` mod.
-
-use core::any::Any;
-use core::ops::Deref;
-use std::boxed::Box;
-
-#[test]
-fn test_owned_clone() {
-    let a = Box::new(5);
-    let b: Box<i32> = a.clone();
-    assert!(a == b);
-}
-
-#[derive(Debug, PartialEq, Eq)]
-struct Test;
-
-#[test]
-fn any_move() {
-    let a = Box::new(8) as Box<dyn Any>;
-    let b = Box::new(Test) as Box<dyn Any>;
-
-    let a: Box<i32> = a.downcast::<i32>().unwrap();
-    assert_eq!(*a, 8);
-
-    let b: Box<Test> = b.downcast::<Test>().unwrap();
-    assert_eq!(*b, Test);
-
-    let a = Box::new(8) as Box<dyn Any>;
-    let b = Box::new(Test) as Box<dyn Any>;
-
-    assert!(a.downcast::<Box<i32>>().is_err());
-    assert!(b.downcast::<Box<Test>>().is_err());
-}
-
-#[test]
-fn test_show() {
-    let a = Box::new(8) as Box<dyn Any>;
-    let b = Box::new(Test) as Box<dyn Any>;
-    let a_str = format!("{a:?}");
-    let b_str = format!("{b:?}");
-    assert_eq!(a_str, "Any { .. }");
-    assert_eq!(b_str, "Any { .. }");
-
-    static EIGHT: usize = 8;
-    static TEST: Test = Test;
-    let a = &EIGHT as &dyn Any;
-    let b = &TEST as &dyn Any;
-    let s = format!("{a:?}");
-    assert_eq!(s, "Any { .. }");
-    let s = format!("{b:?}");
-    assert_eq!(s, "Any { .. }");
-}
-
-#[test]
-fn deref() {
-    fn homura<T: Deref<Target = i32>>(_: T) {}
-    homura(Box::new(765));
-}
-
-#[test]
-fn raw_sized() {
-    let x = Box::new(17);
-    let p = Box::into_raw(x);
-    unsafe {
-        assert_eq!(17, *p);
-        *p = 19;
-        let y = Box::from_raw(p);
-        assert_eq!(19, *y);
-    }
-}
-
-#[test]
-fn raw_trait() {
-    trait Foo {
-        fn get(&self) -> u32;
-        fn set(&mut self, value: u32);
-    }
-
-    struct Bar(u32);
-
-    impl Foo for Bar {
-        fn get(&self) -> u32 {
-            self.0
-        }
-
-        fn set(&mut self, value: u32) {
-            self.0 = value;
-        }
-    }
-
-    let x: Box<dyn Foo> = Box::new(Bar(17));
-    let p = Box::into_raw(x);
-    unsafe {
-        assert_eq!(17, (*p).get());
-        (*p).set(19);
-        let y: Box<dyn Foo> = Box::from_raw(p);
-        assert_eq!(19, y.get());
-    }
-}
-
-#[test]
-fn f64_slice() {
-    let slice: &[f64] = &[-1.0, 0.0, 1.0, f64::INFINITY];
-    let boxed: Box<[f64]> = Box::from(slice);
-    assert_eq!(&*boxed, slice)
-}
-
-#[test]
-fn i64_slice() {
-    let slice: &[i64] = &[i64::MIN, -2, -1, 0, 1, 2, i64::MAX];
-    let boxed: Box<[i64]> = Box::from(slice);
-    assert_eq!(&*boxed, slice)
-}
-
-#[test]
-fn str_slice() {
-    let s = "Hello, world!";
-    let boxed: Box<str> = Box::from(s);
-    assert_eq!(&*boxed, s)
-}
-
-#[test]
-fn boxed_slice_from_iter() {
-    let iter = 0..100;
-    let boxed: Box<[u32]> = iter.collect();
-    assert_eq!(boxed.len(), 100);
-    assert_eq!(boxed[7], 7);
-}
-
-#[test]
-fn test_array_from_slice() {
-    let v = vec![1, 2, 3];
-    let r: Box<[u32]> = v.into_boxed_slice();
-
-    let a: Result<Box<[u32; 3]>, _> = r.clone().try_into();
-    assert!(a.is_ok());
-
-    let a: Result<Box<[u32; 2]>, _> = r.clone().try_into();
-    assert!(a.is_err());
-}
diff --git a/library/alloc/src/vec/extract_if.rs b/library/alloc/src/vec/extract_if.rs
index 72d51e89044..4db13981596 100644
--- a/library/alloc/src/vec/extract_if.rs
+++ b/library/alloc/src/vec/extract_if.rs
@@ -1,3 +1,4 @@
+use core::ops::{Range, RangeBounds};
 use core::{ptr, slice};
 
 use super::Vec;
@@ -14,7 +15,7 @@ use crate::alloc::{Allocator, Global};
 /// #![feature(extract_if)]
 ///
 /// let mut v = vec![0, 1, 2];
-/// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(|x| *x % 2 == 0);
+/// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(.., |x| *x % 2 == 0);
 /// ```
 #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")]
 #[derive(Debug)]
@@ -24,24 +25,32 @@ pub struct ExtractIf<
     T,
     F,
     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
-> where
-    F: FnMut(&mut T) -> bool,
-{
-    pub(super) vec: &'a mut Vec<T, A>,
+> {
+    vec: &'a mut Vec<T, A>,
     /// The index of the item that will be inspected by the next call to `next`.
-    pub(super) idx: usize,
+    idx: usize,
+    /// Elements at and beyond this point will be retained. Must be equal or smaller than `old_len`.
+    end: usize,
     /// The number of items that have been drained (removed) thus far.
-    pub(super) del: usize,
+    del: usize,
     /// The original length of `vec` prior to draining.
-    pub(super) old_len: usize,
+    old_len: usize,
     /// The filter test predicate.
-    pub(super) pred: F,
+    pred: F,
 }
 
-impl<T, F, A: Allocator> ExtractIf<'_, T, F, A>
-where
-    F: FnMut(&mut T) -> bool,
-{
+impl<'a, T, F, A: Allocator> ExtractIf<'a, T, F, A> {
+    pub(super) fn new<R: RangeBounds<usize>>(vec: &'a mut Vec<T, A>, pred: F, range: R) -> Self {
+        let old_len = vec.len();
+        let Range { start, end } = slice::range(range, ..old_len);
+
+        // Guard against the vec getting leaked (leak amplification)
+        unsafe {
+            vec.set_len(0);
+        }
+        ExtractIf { vec, idx: start, del: 0, end, old_len, pred }
+    }
+
     /// Returns a reference to the underlying allocator.
     #[unstable(feature = "allocator_api", issue = "32838")]
     #[inline]
@@ -59,7 +68,7 @@ where
 
     fn next(&mut self) -> Option<T> {
         unsafe {
-            while self.idx < self.old_len {
+            while self.idx < self.end {
                 let i = self.idx;
                 let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len);
                 let drained = (self.pred)(&mut v[i]);
@@ -82,24 +91,15 @@ where
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (0, Some(self.old_len - self.idx))
+        (0, Some(self.end - self.idx))
     }
 }
 
 #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")]
-impl<T, F, A: Allocator> Drop for ExtractIf<'_, T, F, A>
-where
-    F: FnMut(&mut T) -> bool,
-{
+impl<T, F, A: Allocator> Drop for ExtractIf<'_, T, F, A> {
     fn drop(&mut self) {
         unsafe {
             if self.idx < self.old_len && self.del > 0 {
-                // This is a pretty messed up state, and there isn't really an
-                // obviously right thing to do. We don't want to keep trying
-                // to execute `pred`, so we just backshift all the unprocessed
-                // elements and tell the vec that they still exist. The backshift
-                // is required to prevent a double-drop of the last successfully
-                // drained item prior to a panic in the predicate.
                 let ptr = self.vec.as_mut_ptr();
                 let src = ptr.add(self.idx);
                 let dst = src.sub(self.del);
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 457be3ae77f..3a706d5f36b 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -56,7 +56,6 @@
 #[cfg(not(no_global_oom_handling))]
 use core::cmp;
 use core::cmp::Ordering;
-use core::fmt;
 use core::hash::{Hash, Hasher};
 #[cfg(not(no_global_oom_handling))]
 use core::iter;
@@ -65,6 +64,7 @@ use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
 use core::ops::{self, Index, IndexMut, Range, RangeBounds};
 use core::ptr::{self, NonNull};
 use core::slice::{self, SliceIndex};
+use core::{fmt, intrinsics};
 
 #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")]
 pub use self::extract_if::ExtractIf;
@@ -1824,7 +1824,10 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// # Examples
     ///
-    /// This method can be useful for situations in which the vector
+    /// See [`spare_capacity_mut()`] for an example with safe
+    /// initialization of capacity elements and use of this method.
+    ///
+    /// `set_len()` can be useful for situations in which the vector
     /// is serving as a buffer for other code, particularly over FFI:
     ///
     /// ```no_run
@@ -1884,6 +1887,8 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// Normally, here, one would use [`clear`] instead to correctly drop
     /// the contents and thus not leak memory.
+    ///
+    /// [`spare_capacity_mut()`]: Vec::spare_capacity_mut
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn set_len(&mut self, new_len: usize) {
@@ -1953,11 +1958,11 @@ impl<T, A: Allocator> Vec<T, A> {
     /// # Examples
     ///
     /// ```
-    /// let mut vec = vec![1, 2, 3];
-    /// vec.insert(1, 4);
-    /// assert_eq!(vec, [1, 4, 2, 3]);
-    /// vec.insert(4, 5);
-    /// assert_eq!(vec, [1, 4, 2, 3, 5]);
+    /// let mut vec = vec!['a', 'b', 'c'];
+    /// vec.insert(1, 'd');
+    /// assert_eq!(vec, ['a', 'd', 'b', 'c']);
+    /// vec.insert(4, 'e');
+    /// assert_eq!(vec, ['a', 'd', 'b', 'c', 'e']);
     /// ```
     ///
     /// # Time complexity
@@ -2024,9 +2029,9 @@ impl<T, A: Allocator> Vec<T, A> {
     /// # Examples
     ///
     /// ```
-    /// let mut v = vec![1, 2, 3];
-    /// assert_eq!(v.remove(1), 2);
-    /// assert_eq!(v, [1, 3]);
+    /// let mut v = vec!['a', 'b', 'c'];
+    /// assert_eq!(v.remove(1), 'b');
+    /// assert_eq!(v, ['a', 'c']);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[track_caller]
@@ -2675,7 +2680,14 @@ impl<T, A: Allocator> Vec<T, A> {
     #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
     #[rustc_confusables("length", "size")]
     pub const fn len(&self) -> usize {
-        self.len
+        let len = self.len;
+
+        // SAFETY: The maximum capacity of `Vec<T>` is `isize::MAX` bytes, so the maximum value can
+        // be returned is `usize::checked_div(mem::size_of::<T>()).unwrap_or(usize::MAX)`, which
+        // matches the definition of `T::MAX_SLICE_LEN`.
+        unsafe { intrinsics::assume(len <= T::MAX_SLICE_LEN) };
+
+        len
     }
 
     /// Returns `true` if the vector contains no elements.
@@ -2715,10 +2727,10 @@ impl<T, A: Allocator> Vec<T, A> {
     /// # Examples
     ///
     /// ```
-    /// let mut vec = vec![1, 2, 3];
+    /// let mut vec = vec!['a', 'b', 'c'];
     /// let vec2 = vec.split_off(1);
-    /// assert_eq!(vec, [1]);
-    /// assert_eq!(vec2, [2, 3]);
+    /// assert_eq!(vec, ['a']);
+    /// assert_eq!(vec2, ['b', 'c']);
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[inline]
@@ -2982,9 +2994,9 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
     /// vec.resize(3, "world");
     /// assert_eq!(vec, ["hello", "world", "world"]);
     ///
-    /// let mut vec = vec![1, 2, 3, 4];
-    /// vec.resize(2, 0);
-    /// assert_eq!(vec, [1, 2]);
+    /// let mut vec = vec!['a', 'b', 'c', 'd'];
+    /// vec.resize(2, '_');
+    /// assert_eq!(vec, ['a', 'b']);
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "vec_resize", since = "1.5.0")]
@@ -3615,12 +3627,15 @@ impl<T, A: Allocator> Vec<T, A> {
         Splice { drain: self.drain(range), replace_with: replace_with.into_iter() }
     }
 
-    /// Creates an iterator which uses a closure to determine if an element should be removed.
+    /// Creates an iterator which uses a closure to determine if element in the range should be removed.
     ///
     /// If the closure returns true, then the element is removed and yielded.
     /// If the closure returns false, the element will remain in the vector and will not be yielded
     /// by the iterator.
     ///
+    /// Only elements that fall in the provided range are considered for extraction, but any elements
+    /// after the range will still have to be moved if any element has been extracted.
+    ///
     /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
     /// or the iteration short-circuits, then the remaining elements will be retained.
     /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
@@ -3630,10 +3645,12 @@ impl<T, A: Allocator> Vec<T, A> {
     /// Using this method is equivalent to the following code:
     ///
     /// ```
+    /// # use std::cmp::min;
     /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
     /// # let mut vec = vec![1, 2, 3, 4, 5, 6];
-    /// let mut i = 0;
-    /// while i < vec.len() {
+    /// # let range = 1..4;
+    /// let mut i = range.start;
+    /// while i < min(vec.len(), range.end) {
     ///     if some_predicate(&mut vec[i]) {
     ///         let val = vec.remove(i);
     ///         // your code here
@@ -3648,8 +3665,12 @@ impl<T, A: Allocator> Vec<T, A> {
     /// But `extract_if` is easier to use. `extract_if` is also more efficient,
     /// because it can backshift the elements of the array in bulk.
     ///
-    /// Note that `extract_if` also lets you mutate every element in the filter closure,
-    /// regardless of whether you choose to keep or remove it.
+    /// Note that `extract_if` also lets you mutate the elements passed to the filter closure,
+    /// regardless of whether you choose to keep or remove them.
+    ///
+    /// # Panics
+    ///
+    /// If `range` is out of bounds.
     ///
     /// # Examples
     ///
@@ -3659,25 +3680,29 @@ impl<T, A: Allocator> Vec<T, A> {
     /// #![feature(extract_if)]
     /// let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
     ///
-    /// let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
+    /// let evens = numbers.extract_if(.., |x| *x % 2 == 0).collect::<Vec<_>>();
     /// let odds = numbers;
     ///
     /// assert_eq!(evens, vec![2, 4, 6, 8, 14]);
     /// assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
     /// ```
+    ///
+    /// Using the range argument to only process a part of the vector:
+    ///
+    /// ```
+    /// #![feature(extract_if)]
+    /// let mut items = vec![0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2];
+    /// let ones = items.extract_if(7.., |x| *x == 1).collect::<Vec<_>>();
+    /// assert_eq!(items, vec![0, 0, 0, 0, 0, 0, 0, 2, 2, 2]);
+    /// assert_eq!(ones.len(), 3);
+    /// ```
     #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")]
-    pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>
+    pub fn extract_if<F, R>(&mut self, range: R, filter: F) -> ExtractIf<'_, T, F, A>
     where
         F: FnMut(&mut T) -> bool,
+        R: RangeBounds<usize>,
     {
-        let old_len = self.len();
-
-        // Guard against us getting leaked (leak amplification)
-        unsafe {
-            self.set_len(0);
-        }
-
-        ExtractIf { vec: self, idx: 0, del: 0, old_len, pred: filter }
+        ExtractIf::new(self, filter, range)
     }
 }