about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorphosphorus <steepout@qq.com>2019-08-19 00:34:02 -0500
committerGitHub <noreply@github.com>2019-08-19 00:34:02 -0500
commit92f08b78a12ff119af853cb2bf58468208ea6a90 (patch)
treeb4636f43c056de11dd69130ce47039343a9f52c5 /src/liballoc
parent963184bbb670c1ffa97fc28a98cd5e8473118859 (diff)
parenta807902dd6b4222179776c3f3c33da8dafdd4da1 (diff)
downloadrust-92f08b78a12ff119af853cb2bf58468208ea6a90.tar.gz
rust-92f08b78a12ff119af853cb2bf58468208ea6a90.zip
Merge pull request #1 from rust-lang/master
Pull from newest repo
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/Cargo.toml4
-rw-r--r--src/liballoc/alloc.rs56
-rw-r--r--src/liballoc/alloc/tests.rs30
-rw-r--r--src/liballoc/benches/slice.rs8
-rw-r--r--src/liballoc/borrow.rs12
-rw-r--r--src/liballoc/boxed.rs357
-rw-r--r--src/liballoc/collections/binary_heap.rs60
-rw-r--r--src/liballoc/collections/btree/map.rs38
-rw-r--r--src/liballoc/collections/btree/node.rs8
-rw-r--r--src/liballoc/collections/btree/set.rs8
-rw-r--r--src/liballoc/collections/linked_list.rs293
-rw-r--r--src/liballoc/collections/linked_list/tests.rs264
-rw-r--r--src/liballoc/collections/mod.rs31
-rw-r--r--src/liballoc/collections/vec_deque.rs616
-rw-r--r--src/liballoc/collections/vec_deque/tests.rs379
-rw-r--r--src/liballoc/lib.rs49
-rw-r--r--src/liballoc/macros.rs4
-rw-r--r--src/liballoc/prelude/v1.rs1
-rw-r--r--src/liballoc/raw_vec.rs233
-rw-r--r--src/liballoc/raw_vec/tests.rs73
-rw-r--r--src/liballoc/rc.rs1129
-rw-r--r--src/liballoc/rc/tests.rs439
-rw-r--r--src/liballoc/slice.rs206
-rw-r--r--src/liballoc/str.rs38
-rw-r--r--src/liballoc/string.rs19
-rw-r--r--src/liballoc/sync.rs1091
-rw-r--r--src/liballoc/sync/tests.rs492
-rw-r--r--src/liballoc/tests.rs (renamed from src/liballoc/boxed_test.rs)13
-rw-r--r--src/liballoc/tests/arc.rs121
-rw-r--r--src/liballoc/tests/btree/map.rs3
-rw-r--r--src/liballoc/tests/btree/set.rs32
-rw-r--r--src/liballoc/tests/heap.rs32
-rw-r--r--src/liballoc/tests/lib.rs5
-rw-r--r--src/liballoc/tests/linked_list.rs2
-rw-r--r--src/liballoc/tests/rc.rs117
-rw-r--r--src/liballoc/tests/str.rs20
-rw-r--r--src/liballoc/tests/string.rs14
-rw-r--r--src/liballoc/tests/vec.rs152
-rw-r--r--src/liballoc/tests/vec_deque.rs15
-rw-r--r--src/liballoc/vec.rs285
40 files changed, 4310 insertions, 2439 deletions
diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml
index bcb27bb5161..d1119f7b7c0 100644
--- a/src/liballoc/Cargo.toml
+++ b/src/liballoc/Cargo.toml
@@ -15,8 +15,8 @@ core = { path = "../libcore" }
 compiler_builtins = { version = "0.1.10", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
-rand = "0.6"
-rand_xorshift = "0.1"
+rand = "0.7"
+rand_xorshift = "0.2"
 
 [[test]]
 name = "collectionstests"
diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs
index ddc6481eec7..dc7fd1adc29 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -10,12 +10,15 @@ use core::usize;
 #[doc(inline)]
 pub use core::alloc::*;
 
+#[cfg(test)]
+mod tests;
+
 extern "Rust" {
     // These are the magic symbols to call the global allocator.  rustc generates
     // them from the `#[global_allocator]` attribute if there is one, or uses the
     // default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`)
     // otherwise.
-    #[allocator]
+    #[rustc_allocator]
     #[rustc_allocator_nounwind]
     fn __rust_alloc(size: usize, align: usize) -> *mut u8;
     #[rustc_allocator_nounwind]
@@ -37,6 +40,8 @@ extern "Rust" {
 ///
 /// Note: while this type is unstable, the functionality it provides can be
 /// accessed through the [free functions in `alloc`](index.html#functions).
+///
+/// [`Alloc`]: trait.Alloc.html
 #[unstable(feature = "allocator_api", issue = "32838")]
 #[derive(Copy, Clone, Default, Debug)]
 pub struct Global;
@@ -54,6 +59,10 @@ pub struct Global;
 ///
 /// See [`GlobalAlloc::alloc`].
 ///
+/// [`Global`]: struct.Global.html
+/// [`Alloc`]: trait.Alloc.html
+/// [`GlobalAlloc::alloc`]: trait.GlobalAlloc.html#tymethod.alloc
+///
 /// # Examples
 ///
 /// ```
@@ -87,6 +96,10 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 {
 /// # Safety
 ///
 /// See [`GlobalAlloc::dealloc`].
+///
+/// [`Global`]: struct.Global.html
+/// [`Alloc`]: trait.Alloc.html
+/// [`GlobalAlloc::dealloc`]: trait.GlobalAlloc.html#tymethod.dealloc
 #[stable(feature = "global_alloc", since = "1.28.0")]
 #[inline]
 pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
@@ -105,6 +118,10 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
 /// # Safety
 ///
 /// See [`GlobalAlloc::realloc`].
+///
+/// [`Global`]: struct.Global.html
+/// [`Alloc`]: trait.Alloc.html
+/// [`GlobalAlloc::realloc`]: trait.GlobalAlloc.html#method.realloc
 #[stable(feature = "global_alloc", since = "1.28.0")]
 #[inline]
 pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
@@ -124,6 +141,10 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8
 ///
 /// See [`GlobalAlloc::alloc_zeroed`].
 ///
+/// [`Global`]: struct.Global.html
+/// [`Alloc`]: trait.Alloc.html
+/// [`GlobalAlloc::alloc_zeroed`]: trait.GlobalAlloc.html#method.alloc_zeroed
+///
 /// # Examples
 ///
 /// ```
@@ -226,36 +247,3 @@ pub fn handle_alloc_error(layout: Layout) -> ! {
     }
     unsafe { oom_impl(layout) }
 }
-
-#[cfg(test)]
-mod tests {
-    extern crate test;
-    use test::Bencher;
-    use crate::boxed::Box;
-    use crate::alloc::{Global, Alloc, Layout, handle_alloc_error};
-
-    #[test]
-    fn allocate_zeroed() {
-        unsafe {
-            let layout = Layout::from_size_align(1024, 1).unwrap();
-            let ptr = Global.alloc_zeroed(layout.clone())
-                .unwrap_or_else(|_| handle_alloc_error(layout));
-
-            let mut i = ptr.cast::<u8>().as_ptr();
-            let end = i.add(layout.size());
-            while i < end {
-                assert_eq!(*i, 0);
-                i = i.offset(1);
-            }
-            Global.dealloc(ptr, layout);
-        }
-    }
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn alloc_owned_small(b: &mut Bencher) {
-        b.iter(|| {
-            let _: Box<_> = box 10;
-        })
-    }
-}
diff --git a/src/liballoc/alloc/tests.rs b/src/liballoc/alloc/tests.rs
new file mode 100644
index 00000000000..c69f4e49ee1
--- /dev/null
+++ b/src/liballoc/alloc/tests.rs
@@ -0,0 +1,30 @@
+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.alloc_zeroed(layout.clone())
+            .unwrap_or_else(|_| handle_alloc_error(layout));
+
+        let mut i = ptr.cast::<u8>().as_ptr();
+        let end = i.add(layout.size());
+        while i < end {
+            assert_eq!(*i, 0);
+            i = i.offset(1);
+        }
+        Global.dealloc(ptr, layout);
+    }
+}
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn alloc_owned_small(b: &mut Bencher) {
+    b.iter(|| {
+        let _: Box<_> = box 10;
+    })
+}
diff --git a/src/liballoc/benches/slice.rs b/src/liballoc/benches/slice.rs
index f17fb8212ce..ef91d801dc7 100644
--- a/src/liballoc/benches/slice.rs
+++ b/src/liballoc/benches/slice.rs
@@ -186,12 +186,12 @@ const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
 
 fn gen_random(len: usize) -> Vec<u64> {
     let mut rng = XorShiftRng::from_seed(SEED);
-    rng.sample_iter(&Standard).take(len).collect()
+    (&mut rng).sample_iter(&Standard).take(len).collect()
 }
 
 fn gen_random_bytes(len: usize) -> Vec<u8> {
     let mut rng = XorShiftRng::from_seed(SEED);
-    rng.sample_iter(&Standard).take(len).collect()
+    (&mut rng).sample_iter(&Standard).take(len).collect()
 }
 
 fn gen_mostly_ascending(len: usize) -> Vec<u64> {
@@ -221,14 +221,14 @@ fn gen_strings(len: usize) -> Vec<String> {
     let mut v = vec![];
     for _ in 0..len {
         let n = rng.gen::<usize>() % 20 + 1;
-        v.push(rng.sample_iter(&Alphanumeric).take(n).collect());
+        v.push((&mut rng).sample_iter(&Alphanumeric).take(n).collect());
     }
     v
 }
 
 fn gen_big_random(len: usize) -> Vec<[u64; 16]> {
     let mut rng = XorShiftRng::from_seed(SEED);
-    rng.sample_iter(&Standard).map(|x| [x; 16]).take(len).collect()
+    (&mut rng).sample_iter(&Standard).map(|x| [x; 16]).take(len).collect()
 }
 
 macro_rules! sort {
diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs
index d5e15b3719c..a9c5bce4c25 100644
--- a/src/liballoc/borrow.rs
+++ b/src/liballoc/borrow.rs
@@ -329,8 +329,8 @@ impl<'a, B: ?Sized> PartialOrd for Cow<'a, B>
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B: ?Sized> fmt::Debug for Cow<'_, B>
-    where B: fmt::Debug + ToOwned,
-          <B as ToOwned>::Owned: fmt::Debug
+where
+    B: fmt::Debug + ToOwned<Owned: fmt::Debug>,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
@@ -342,8 +342,8 @@ impl<B: ?Sized> fmt::Debug for Cow<'_, B>
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B: ?Sized> fmt::Display for Cow<'_, B>
-    where B: fmt::Display + ToOwned,
-          <B as ToOwned>::Owned: fmt::Display
+where
+    B: fmt::Display + ToOwned<Owned: fmt::Display>,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
@@ -355,8 +355,8 @@ impl<B: ?Sized> fmt::Display for Cow<'_, B>
 
 #[stable(feature = "default", since = "1.11.0")]
 impl<B: ?Sized> Default for Cow<'_, B>
-    where B: ToOwned,
-          <B as ToOwned>::Owned: Default
+where
+    B: ToOwned<Owned: Default>,
 {
     /// Creates an owned Cow<'a, B> with the default value for the contained owned value.
     fn default() -> Self {
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 207359ed696..c61e3183409 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -1,19 +1,9 @@
 //! A pointer type for heap allocation.
 //!
-//! `Box<T>`, casually referred to as a 'box', provides the simplest form of
+//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
 //! heap allocation in Rust. Boxes provide ownership for this allocation, and
 //! drop their contents when they go out of scope.
 //!
-//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
-//! its allocation. It is valid to convert both ways between a [`Box`] and a
-//! raw pointer allocated with the [`Global`] allocator, given that the
-//! [`Layout`] used with the allocator is correct for the type. More precisely,
-//! a `value: *mut T` that has been allocated with the [`Global`] allocator
-//! with `Layout::for_value(&*value)` may be converted into a box using
-//! `Box::<T>::from_raw(value)`. Conversely, the memory backing a `value: *mut
-//! T` obtained from `Box::<T>::into_raw` may be deallocated using the
-//! [`Global`] allocator with `Layout::for_value(&*value)`.
-//!
 //! # Examples
 //!
 //! Move a value from the stack to the heap by creating a [`Box`]:
@@ -58,20 +48,38 @@
 //!
 //! It wouldn't work. This is because the size of a `List` depends on how many
 //! elements are in the list, and so we don't know how much memory to allocate
-//! for a `Cons`. By introducing a `Box`, which has a defined size, we know how
+//! for a `Cons`. By introducing a [`Box<T>`], which has a defined size, we know how
 //! big `Cons` needs to be.
 //!
+//! # Memory layout
+//!
+//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
+//! its allocation. It is valid to convert both ways between a [`Box`] and a
+//! raw pointer allocated with the [`Global`] allocator, given that the
+//! [`Layout`] used with the allocator is correct for the type. More precisely,
+//! a `value: *mut T` that has been allocated with the [`Global`] allocator
+//! with `Layout::for_value(&*value)` may be converted into a box using
+//! [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut
+//! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the
+//! [`Global`] allocator with [`Layout::for_value(&*value)`].
+//!
+//!
 //! [dereferencing]: ../../std/ops/trait.Deref.html
 //! [`Box`]: struct.Box.html
+//! [`Box<T>`]: struct.Box.html
+//! [`Box::<T>::from_raw(value)`]: struct.Box.html#method.from_raw
+//! [`Box::<T>::into_raw`]: struct.Box.html#method.into_raw
 //! [`Global`]: ../alloc/struct.Global.html
 //! [`Layout`]: ../alloc/struct.Layout.html
+//! [`Layout::for_value(&*value)`]: ../alloc/struct.Layout.html#method.for_value
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use core::any::Any;
+use core::array::LengthAtMost32;
 use core::borrow;
 use core::cmp::Ordering;
-use core::convert::From;
+use core::convert::{From, TryFrom};
 use core::fmt;
 use core::future::Future;
 use core::hash::{Hash, Hasher};
@@ -83,8 +91,10 @@ use core::ops::{
     CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState
 };
 use core::ptr::{self, NonNull, Unique};
+use core::slice;
 use core::task::{Context, Poll};
 
+use crate::alloc::{self, Global, Alloc};
 use crate::vec::Vec;
 use crate::raw_vec::RawVec;
 use crate::str::from_boxed_utf8_unchecked;
@@ -113,6 +123,34 @@ impl<T> Box<T> {
         box x
     }
 
+    /// Constructs a new box with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// let mut five = Box::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     five.as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
+        let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
+        let ptr = unsafe {
+            Global.alloc(layout)
+                .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
+        };
+        Box(ptr.cast().into())
+    }
+
     /// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
     /// `x` will be pinned in memory and unable to be moved.
     #[stable(feature = "pin", since = "1.33.0")]
@@ -122,29 +160,148 @@ impl<T> Box<T> {
     }
 }
 
+impl<T> Box<[T]> {
+    /// Constructs a new boxed slice with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// let mut values = Box::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     values[0].as_mut_ptr().write(1);
+    ///     values[1].as_mut_ptr().write(2);
+    ///     values[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
+        let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
+        let ptr = unsafe { alloc::alloc(layout) };
+        let unique = Unique::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout));
+        let slice = unsafe { slice::from_raw_parts_mut(unique.cast().as_ptr(), len) };
+        Box(Unique::from(slice))
+    }
+}
+
+impl<T> Box<mem::MaybeUninit<T>> {
+    /// Converts to `Box<T>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// let mut five = Box::<u32>::new_uninit();
+    ///
+    /// let five: Box<u32> = unsafe {
+    ///     // Deferred initialization:
+    ///     five.as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Box<T> {
+        Box(Box::into_unique(self).cast())
+    }
+}
+
+impl<T> Box<[mem::MaybeUninit<T>]> {
+    /// Converts to `Box<[T]>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the values
+    /// really are in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// let mut values = Box::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     values[0].as_mut_ptr().write(1);
+    ///     values[1].as_mut_ptr().write(2);
+    ///     values[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Box<[T]> {
+        Box(Unique::new_unchecked(Box::into_raw(self) as _))
+    }
+}
+
 impl<T: ?Sized> Box<T> {
     /// Constructs a box from a raw pointer.
     ///
     /// After calling this function, the raw pointer is owned by the
     /// resulting `Box`. Specifically, the `Box` destructor will call
-    /// the destructor of `T` and free the allocated memory. Since the
-    /// way `Box` allocates and releases memory is unspecified, the
-    /// only valid pointer to pass to this function is the one taken
-    /// from another `Box` via the [`Box::into_raw`] function.
+    /// the destructor of `T` and free the allocated memory. For this
+    /// to be safe, the memory must have been allocated in accordance
+    /// with the [memory layout] used by `Box` .
+    ///
+    /// # Safety
     ///
     /// This function is unsafe because improper use may lead to
     /// memory problems. For example, a double-free may occur if the
     /// function is called twice on the same raw pointer.
     ///
-    /// [`Box::into_raw`]: struct.Box.html#method.into_raw
-    ///
     /// # Examples
-    ///
+    /// Recreate a `Box` which was previously converted to a raw pointer
+    /// using [`Box::into_raw`]:
     /// ```
     /// let x = Box::new(5);
     /// let ptr = Box::into_raw(x);
     /// let x = unsafe { Box::from_raw(ptr) };
     /// ```
+    /// Manually create a `Box` from scratch by using the global allocator:
+    /// ```
+    /// use std::alloc::{alloc, Layout};
+    ///
+    /// unsafe {
+    ///     let ptr = alloc(Layout::new::<i32>()) as *mut i32;
+    ///     *ptr = 5;
+    ///     let x = Box::from_raw(ptr);
+    /// }
+    /// ```
+    ///
+    /// [memory layout]: index.html#memory-layout
+    /// [`Layout`]: ../alloc/struct.Layout.html
+    /// [`Box::into_raw`]: struct.Box.html#method.into_raw
     #[stable(feature = "box_raw", since = "1.4.0")]
     #[inline]
     pub unsafe fn from_raw(raw: *mut T) -> Self {
@@ -157,22 +314,40 @@ impl<T: ?Sized> Box<T> {
     ///
     /// After calling this function, the caller is responsible for the
     /// memory previously managed by the `Box`. In particular, the
-    /// caller should properly destroy `T` and release the memory. The
-    /// proper way to do so is to convert the raw pointer back into a
-    /// `Box` with the [`Box::from_raw`] function.
+    /// caller should properly destroy `T` and release the memory, taking
+    /// into account the [memory layout] used by `Box`. The easiest way to
+    /// do this is to convert the raw pointer back into a `Box` with the
+    /// [`Box::from_raw`] function, allowing the `Box` destructor to perform
+    /// the cleanup.
     ///
     /// Note: this is an associated function, which means that you have
     /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This
     /// is so that there is no conflict with a method on the inner type.
     ///
-    /// [`Box::from_raw`]: struct.Box.html#method.from_raw
-    ///
     /// # Examples
-    ///
+    /// Converting the raw pointer back into a `Box` with [`Box::from_raw`]
+    /// for automatic cleanup:
     /// ```
-    /// let x = Box::new(5);
+    /// let x = Box::new(String::from("Hello"));
     /// let ptr = Box::into_raw(x);
+    /// let x = unsafe { Box::from_raw(ptr) };
     /// ```
+    /// Manual cleanup by explicitly running the destructor and deallocating
+    /// the memory:
+    /// ```
+    /// use std::alloc::{dealloc, Layout};
+    /// use std::ptr;
+    ///
+    /// let x = Box::new(String::from("Hello"));
+    /// let p = Box::into_raw(x);
+    /// unsafe {
+    ///     ptr::drop_in_place(p);
+    ///     dealloc(p as *mut u8, Layout::new::<String>());
+    /// }
+    /// ```
+    ///
+    /// [memory layout]: index.html#memory-layout
+    /// [`Box::from_raw`]: struct.Box.html#method.from_raw
     #[stable(feature = "box_raw", since = "1.4.0")]
     #[inline]
     pub fn into_raw(b: Box<T>) -> *mut T {
@@ -184,7 +359,7 @@ impl<T: ?Sized> Box<T> {
     /// After calling this function, the caller is responsible for the
     /// memory previously managed by the `Box`. In particular, the
     /// caller should properly destroy `T` and release the memory. The
-    /// proper way to do so is to convert the `NonNull<T>` pointer
+    /// easiest way to do so is to convert the `NonNull<T>` pointer
     /// into a raw pointer and back into a `Box` with the [`Box::from_raw`]
     /// function.
     ///
@@ -203,6 +378,10 @@ impl<T: ?Sized> Box<T> {
     /// fn main() {
     ///     let x = Box::new(5);
     ///     let ptr = Box::into_raw_non_null(x);
+    ///
+    ///     // Clean up the memory by converting the NonNull pointer back
+    ///     // into a Box and letting the Box be dropped.
+    ///     let x = unsafe { Box::from_raw(ptr.as_ptr()) };
     /// }
     /// ```
     #[unstable(feature = "box_into_raw_non_null", issue = "47336")]
@@ -214,15 +393,16 @@ impl<T: ?Sized> Box<T> {
     #[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")]
     #[inline]
     #[doc(hidden)]
-    pub fn into_unique(mut b: Box<T>) -> Unique<T> {
+    pub fn into_unique(b: Box<T>) -> Unique<T> {
+        let mut unique = b.0;
+        mem::forget(b);
         // Box is kind-of a library type, but recognized as a "unique pointer" by
         // Stacked Borrows.  This function here corresponds to "reborrowing to
         // a raw pointer", but there is no actual reborrow here -- so
         // without some care, the pointer we are returning here still carries
-        // the `Uniq` tag.  We round-trip through a mutable reference to avoid that.
-        let unique = unsafe { b.0.as_mut() as *mut T };
-        mem::forget(b);
-        unsafe { Unique::new_unchecked(unique) }
+        // the tag of `b`, with `Unique` permission.
+        // We round-trip through a mutable reference to avoid that.
+        unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) }
     }
 
     /// Consumes and leaks the `Box`, returning a mutable reference,
@@ -280,7 +460,7 @@ impl<T: ?Sized> Box<T> {
     /// This conversion does not allocate on the heap and happens in place.
     ///
     /// This is also available via [`From`].
-    #[unstable(feature = "box_into_pin", issue = "0")]
+    #[unstable(feature = "box_into_pin", issue = "62370")]
     pub fn into_pin(boxed: Box<T>) -> Pin<Box<T>> {
         // It's not possible to move or replace the insides of a `Pin<Box<T>>`
         // when `T: !Unpin`,  so it's safe to pin it directly without any
@@ -327,12 +507,19 @@ impl<T: Clone> Clone for Box<T> {
     /// ```
     /// let x = Box::new(5);
     /// let y = x.clone();
+    ///
+    /// // The value is the same
+    /// assert_eq!(x, y);
+    ///
+    /// // But they are unique objects
+    /// assert_ne!(&*x as *const i32, &*y as *const i32);
     /// ```
     #[rustfmt::skip]
     #[inline]
     fn clone(&self) -> Box<T> {
         box { (**self).clone() }
     }
+
     /// Copies `source`'s contents into `self` without creating a new allocation.
     ///
     /// # Examples
@@ -340,10 +527,15 @@ impl<T: Clone> Clone for Box<T> {
     /// ```
     /// let x = Box::new(5);
     /// let mut y = Box::new(10);
+    /// let yp: *const i32 = &*y;
     ///
     /// y.clone_from(&x);
     ///
-    /// assert_eq!(*y, 5);
+    /// // The value is the same
+    /// assert_eq!(x, y);
+    ///
+    /// // And no allocation occurred
+    /// assert_eq!(yp, &*y);
     /// ```
     #[inline]
     fn clone_from(&mut self, source: &Box<T>) {
@@ -355,11 +547,10 @@ impl<T: Clone> Clone for Box<T> {
 #[stable(feature = "box_slice_clone", since = "1.3.0")]
 impl Clone for Box<str> {
     fn clone(&self) -> Self {
-        let len = self.len();
-        let buf = RawVec::with_capacity(len);
+        // this makes a copy of the data
+        let buf: Box<[u8]> = self.as_bytes().into();
         unsafe {
-            ptr::copy_nonoverlapping(self.as_ptr(), buf.ptr(), len);
-            from_boxed_utf8_unchecked(buf.into_box())
+            from_boxed_utf8_unchecked(buf)
         }
     }
 }
@@ -506,9 +697,12 @@ impl<T: Copy> From<&[T]> for Box<[T]> {
     /// println!("{:?}", boxed_slice);
     /// ```
     fn from(slice: &[T]) -> Box<[T]> {
-        let mut boxed = unsafe { RawVec::with_capacity(slice.len()).into_box() };
-        boxed.copy_from_slice(slice);
-        boxed
+        let len = slice.len();
+        let buf = RawVec::with_capacity(len);
+        unsafe {
+            ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len);
+            buf.into_box()
+        }
     }
 }
 
@@ -554,6 +748,22 @@ impl From<Box<str>> for Box<[u8]> {
     }
 }
 
+#[unstable(feature = "boxed_slice_try_from", issue = "0")]
+impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]>
+where
+    [T; N]: LengthAtMost32,
+{
+    type Error = Box<[T]>;
+
+    fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
+        if boxed_slice.len() == N {
+            Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [T; N]) })
+        } else {
+            Err(boxed_slice)
+        }
+    }
+}
+
 impl Box<dyn Any> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -674,6 +884,14 @@ impl<I: Iterator + ?Sized> Iterator for Box<I> {
         (**self).nth(n)
     }
 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator + Sized> Iterator for Box<I> {
+    fn last(self) -> Option<I::Item> where I: Sized {
+        (*self).last()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
     fn next_back(&mut self) -> Option<I::Item> {
@@ -719,61 +937,6 @@ impl<A, F: Fn<A> + ?Sized> Fn<A> for Box<F> {
     }
 }
 
-/// `FnBox` is a version of the `FnOnce` intended for use with boxed
-/// closure objects. The idea is that where one would normally store a
-/// `Box<dyn FnOnce()>` in a data structure, you should use
-/// `Box<dyn FnBox()>`. The two traits behave essentially the same, except
-/// that a `FnBox` closure can only be called if it is boxed. (Note
-/// that `FnBox` may be deprecated in the future if `Box<dyn FnOnce()>`
-/// closures become directly usable.)
-///
-/// # Examples
-///
-/// Here is a snippet of code which creates a hashmap full of boxed
-/// once closures and then removes them one by one, calling each
-/// closure as it is removed. Note that the type of the closures
-/// stored in the map is `Box<dyn FnBox() -> i32>` and not `Box<dyn FnOnce()
-/// -> i32>`.
-///
-/// ```
-/// #![feature(fnbox)]
-///
-/// use std::boxed::FnBox;
-/// use std::collections::HashMap;
-///
-/// fn make_map() -> HashMap<i32, Box<dyn FnBox() -> i32>> {
-///     let mut map: HashMap<i32, Box<dyn FnBox() -> i32>> = HashMap::new();
-///     map.insert(1, Box::new(|| 22));
-///     map.insert(2, Box::new(|| 44));
-///     map
-/// }
-///
-/// fn main() {
-///     let mut map = make_map();
-///     for i in &[1, 2] {
-///         let f = map.remove(&i).unwrap();
-///         assert_eq!(f(), i * 22);
-///     }
-/// }
-/// ```
-#[rustc_paren_sugar]
-#[unstable(feature = "fnbox",
-           reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
-pub trait FnBox<A>: FnOnce<A> {
-    /// Performs the call operation.
-    fn call_box(self: Box<Self>, args: A) -> Self::Output;
-}
-
-#[unstable(feature = "fnbox",
-           reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
-impl<A, F> FnBox<A> for F
-    where F: FnOnce<A>
-{
-    fn call_box(self: Box<F>, args: A) -> F::Output {
-        self.call_once(args)
-    }
-}
-
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
 
diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs
index 39fcfaa7893..3d04f30e7bd 100644
--- a/src/liballoc/collections/binary_heap.rs
+++ b/src/liballoc/collections/binary_heap.rs
@@ -231,6 +231,20 @@ use super::SpecExtend;
 /// assert_eq!(heap.pop(), Some(Reverse(5)));
 /// assert_eq!(heap.pop(), None);
 /// ```
+///
+/// # Time complexity
+///
+/// | [push] | [pop]    | [peek]/[peek\_mut] |
+/// |--------|----------|--------------------|
+/// | O(1)~  | O(log n) | O(1)               |
+///
+/// The value for `push` is an expected cost; the method documentation gives a
+/// more detailed analysis.
+///
+/// [push]: #method.push
+/// [pop]: #method.pop
+/// [peek]: #method.peek
+/// [peek\_mut]: #method.peek_mut
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BinaryHeap<T> {
     data: Vec<T>,
@@ -384,6 +398,10 @@ impl<T: Ord> BinaryHeap<T> {
     /// }
     /// assert_eq!(heap.peek(), Some(&2));
     /// ```
+    ///
+    /// # Time complexity
+    ///
+    /// Cost is O(1) in the worst case.
     #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
     pub fn peek_mut(&mut self) -> Option<PeekMut<'_, T>> {
         if self.is_empty() {
@@ -411,6 +429,11 @@ impl<T: Ord> BinaryHeap<T> {
     /// assert_eq!(heap.pop(), Some(1));
     /// assert_eq!(heap.pop(), None);
     /// ```
+    ///
+    /// # Time complexity
+    ///
+    /// The worst case cost of `pop` on a heap containing *n* elements is O(log
+    /// n).
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn pop(&mut self) -> Option<T> {
         self.data.pop().map(|mut item| {
@@ -438,6 +461,22 @@ impl<T: Ord> BinaryHeap<T> {
     /// assert_eq!(heap.len(), 3);
     /// assert_eq!(heap.peek(), Some(&5));
     /// ```
+    ///
+    /// # Time complexity
+    ///
+    /// The expected cost of `push`, averaged over every possible ordering of
+    /// the elements being pushed, and over a sufficiently large number of
+    /// pushes, is O(1). This is the most meaningful cost metric when pushing
+    /// elements that are *not* already in any sorted pattern.
+    ///
+    /// The time complexity degrades if elements are pushed in predominantly
+    /// ascending order. In the worst case, elements are pushed in ascending
+    /// sorted order and the amortized cost per push is O(log n) against a heap
+    /// containing *n* elements.
+    ///
+    /// The worst case cost of a *single* call to `push` is O(n). The worst case
+    /// occurs when capacity is exhausted and needs a resize. The resize cost
+    /// has been amortized in the previous figures.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn push(&mut self, item: T) {
         let old_len = self.len();
@@ -650,6 +689,10 @@ impl<T> BinaryHeap<T> {
     /// assert_eq!(heap.peek(), Some(&5));
     ///
     /// ```
+    ///
+    /// # Time complexity
+    ///
+    /// Cost is O(1) in the worst case.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn peek(&self) -> Option<&T> {
         self.data.get(0)
@@ -994,8 +1037,8 @@ impl<'a, T> Iterator for Iter<'a, T> {
     }
 
     #[inline]
-    fn last(mut self) -> Option<&'a T> {
-        self.next_back()
+    fn last(self) -> Option<&'a T> {
+        self.iter.last()
     }
 }
 
@@ -1052,11 +1095,6 @@ impl<T> Iterator for IntoIter<T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
-
-    #[inline]
-    fn last(mut self) -> Option<T> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1103,11 +1141,6 @@ impl<T> Iterator for Drain<'_, T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
-
-    #[inline]
-    fn last(mut self) -> Option<T> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
@@ -1130,6 +1163,9 @@ impl<T> FusedIterator for Drain<'_, T> {}
 
 #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
 impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
+    /// Converts a `Vec<T>` into a `BinaryHeap<T>`.
+    ///
+    /// This conversion happens in-place, and has `O(n)` time complexity.
     fn from(vec: Vec<T>) -> BinaryHeap<T> {
         let mut heap = BinaryHeap { data: vec };
         heap.rebuild();
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index 414abb00ef1..1683b810556 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -75,10 +75,10 @@ use Entry::*;
 ///
 /// // look up the values associated with some keys.
 /// let to_find = ["Up!", "Office Space"];
-/// for book in &to_find {
-///     match movie_reviews.get(book) {
-///        Some(review) => println!("{}: {}", book, review),
-///        None => println!("{} is unreviewed.", book)
+/// for movie in &to_find {
+///     match movie_reviews.get(movie) {
+///        Some(review) => println!("{}: {}", movie, review),
+///        None => println!("{} is unreviewed.", movie)
 ///     }
 /// }
 ///
@@ -200,7 +200,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
             }
         }
 
-        if self.len() == 0 {
+        if self.is_empty() {
             // Ideally we'd call `BTreeMap::new` here, but that has the `K:
             // Ord` constraint, which this method lacks.
             BTreeMap {
@@ -759,19 +759,19 @@ impl<K: Ord, V> BTreeMap<K, V> {
     #[stable(feature = "btree_append", since = "1.11.0")]
     pub fn append(&mut self, other: &mut Self) {
         // Do we have to append anything at all?
-        if other.len() == 0 {
+        if other.is_empty() {
             return;
         }
 
         // We can just swap `self` and `other` if `self` is empty.
-        if self.len() == 0 {
+        if self.is_empty() {
             mem::swap(self, other);
             return;
         }
 
         // First, we merge `self` and `other` into a sorted sequence in linear time.
-        let self_iter = mem::replace(self, BTreeMap::new()).into_iter();
-        let other_iter = mem::replace(other, BTreeMap::new()).into_iter();
+        let self_iter = mem::take(self).into_iter();
+        let other_iter = mem::take(other).into_iter();
         let iter = MergeIter {
             left: self_iter.peekable(),
             right: other_iter.peekable(),
@@ -1194,7 +1194,6 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> {
         (self.length, Some(self.length))
     }
 
-    #[inline]
     fn last(mut self) -> Option<(&'a K, &'a V)> {
         self.next_back()
     }
@@ -1259,7 +1258,6 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> {
         (self.length, Some(self.length))
     }
 
-    #[inline]
     fn last(mut self) -> Option<(&'a K, &'a mut V)> {
         self.next_back()
     }
@@ -1369,11 +1367,6 @@ impl<K, V> Iterator for IntoIter<K, V> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.length, Some(self.length))
     }
-
-    #[inline]
-    fn last(mut self) -> Option<(K, V)> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1437,7 +1430,6 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> {
         self.inner.size_hint()
     }
 
-    #[inline]
     fn last(mut self) -> Option<&'a K> {
         self.next_back()
     }
@@ -1479,7 +1471,6 @@ impl<'a, K, V> Iterator for Values<'a, K, V> {
         self.inner.size_hint()
     }
 
-    #[inline]
     fn last(mut self) -> Option<&'a V> {
         self.next_back()
     }
@@ -1521,7 +1512,6 @@ impl<'a, K, V> Iterator for Range<'a, K, V> {
         }
     }
 
-    #[inline]
     fn last(mut self) -> Option<(&'a K, &'a V)> {
         self.next_back()
     }
@@ -1539,7 +1529,6 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
         self.inner.size_hint()
     }
 
-    #[inline]
     fn last(mut self) -> Option<&'a mut V> {
         self.next_back()
     }
@@ -1662,7 +1651,6 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> {
         }
     }
 
-    #[inline]
     fn last(mut self) -> Option<(&'a K, &'a mut V)> {
         self.next_back()
     }
@@ -2044,7 +2032,7 @@ impl<K, V> BTreeMap<K, V> {
     /// assert_eq!(keys, [1, 2]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
+    pub fn keys(&self) -> Keys<'_, K, V> {
         Keys { inner: self.iter() }
     }
 
@@ -2065,7 +2053,7 @@ impl<K, V> BTreeMap<K, V> {
     /// assert_eq!(values, ["hello", "goodbye"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn values<'a>(&'a self) -> Values<'a, K, V> {
+    pub fn values(&self) -> Values<'_, K, V> {
         Values { inner: self.iter() }
     }
 
@@ -2569,8 +2557,8 @@ enum UnderflowResult<'a, K, V> {
     Stole(NodeRef<marker::Mut<'a>, K, V, marker::Internal>),
 }
 
-fn handle_underfull_node<'a, K, V>(node: NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>)
-                                   -> UnderflowResult<'a, K, V> {
+fn handle_underfull_node<K, V>(node: NodeRef<marker::Mut<'_>, K, V, marker::LeafOrInternal>)
+                               -> UnderflowResult<'_, K, V> {
     let parent = if let Ok(parent) = node.ascend() {
         parent
     } else {
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs
index 581c66c7086..0b5a271dbea 100644
--- a/src/liballoc/collections/btree/node.rs
+++ b/src/liballoc/collections/btree/node.rs
@@ -106,8 +106,8 @@ impl<K, V> LeafNode<K, V> {
         LeafNode {
             // As a general policy, we leave fields uninitialized if they can be, as this should
             // be both slightly faster and easier to track in Valgrind.
-            keys: uninitialized_array![_; CAPACITY],
-            vals: uninitialized_array![_; CAPACITY],
+            keys: [MaybeUninit::UNINIT; CAPACITY],
+            vals: [MaybeUninit::UNINIT; CAPACITY],
             parent: ptr::null(),
             parent_idx: MaybeUninit::uninit(),
             len: 0
@@ -159,7 +159,7 @@ impl<K, V> InternalNode<K, V> {
     unsafe fn new() -> Self {
         InternalNode {
             data: LeafNode::new(),
-            edges: uninitialized_array![_; 2*B],
+            edges: [MaybeUninit::UNINIT; 2*B]
         }
     }
 }
@@ -394,7 +394,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
     }
 
     /// Temporarily takes out another, immutable reference to the same node.
-    fn reborrow<'a>(&'a self) -> NodeRef<marker::Immut<'a>, K, V, Type> {
+    fn reborrow(&self) -> NodeRef<marker::Immut<'_>, K, V, Type> {
         NodeRef {
             height: self.height,
             node: self.node,
diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs
index 6f2467dfd6b..d3af910a82c 100644
--- a/src/liballoc/collections/btree/set.rs
+++ b/src/liballoc/collections/btree/set.rs
@@ -1019,8 +1019,6 @@ impl<'a, T> Iterator for Iter<'a, T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
-
-    #[inline]
     fn last(mut self) -> Option<&'a T> {
         self.next_back()
     }
@@ -1049,11 +1047,6 @@ impl<T> Iterator for IntoIter<T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
-
-    #[inline]
-    fn last(mut self) -> Option<T> {
-        self.next_back()
-    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> DoubleEndedIterator for IntoIter<T> {
@@ -1084,7 +1077,6 @@ impl<'a, T> Iterator for Range<'a, T> {
         self.iter.next().map(|(k, _)| k)
     }
 
-    #[inline]
     fn last(mut self) -> Option<&'a T> {
         self.next_back()
     }
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index 40a82d6feaa..a14a3fe9994 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -23,6 +23,9 @@ use core::ptr::NonNull;
 use crate::boxed::Box;
 use super::SpecExtend;
 
+#[cfg(test)]
+mod tests;
+
 /// A doubly-linked list with owned nodes.
 ///
 /// The `LinkedList` allows pushing and popping elements at either end
@@ -237,15 +240,15 @@ impl<T> LinkedList<T> {
 
         // Not creating new mutable (unique!) references overlapping `element`.
         match node.prev {
-            Some(prev) => (*prev.as_ptr()).next = node.next.clone(),
+            Some(prev) => (*prev.as_ptr()).next = node.next,
             // this node is the head node
-            None => self.head = node.next.clone(),
+            None => self.head = node.next,
         };
 
         match node.next {
-            Some(next) => (*next.as_ptr()).prev = node.prev.clone(),
+            Some(next) => (*next.as_ptr()).prev = node.prev,
             // this node is the tail node
-            None => self.tail = node.prev.clone(),
+            None => self.tail = node.prev,
         };
 
         self.len -= 1;
@@ -708,7 +711,7 @@ impl<T> LinkedList<T> {
         let len = self.len();
         assert!(at <= len, "Cannot split off at a nonexistent index");
         if at == 0 {
-            return mem::replace(self, Self::new());
+            return mem::take(self);
         } else if at == len {
             return Self::new();
         }
@@ -832,6 +835,11 @@ impl<'a, T> Iterator for Iter<'a, T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.len, Some(self.len))
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -881,6 +889,11 @@ impl<'a, T> Iterator for IterMut<'a, T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         (self.len, Some(self.len))
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a mut T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1234,273 +1247,3 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
-
-#[cfg(test)]
-mod tests {
-    use std::thread;
-    use std::vec::Vec;
-
-    use rand::{thread_rng, RngCore};
-
-    use super::{LinkedList, Node};
-
-    #[cfg(test)]
-    fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
-        v.iter().cloned().collect()
-    }
-
-    pub fn check_links<T>(list: &LinkedList<T>) {
-        unsafe {
-            let mut len = 0;
-            let mut last_ptr: Option<&Node<T>> = None;
-            let mut node_ptr: &Node<T>;
-            match list.head {
-                None => {
-                    // tail node should also be None.
-                    assert!(list.tail.is_none());
-                    assert_eq!(0, list.len);
-                    return;
-                }
-                Some(node) => node_ptr = &*node.as_ptr(),
-            }
-            loop {
-                match (last_ptr, node_ptr.prev) {
-                    (None, None) => {}
-                    (None, _) => panic!("prev link for head"),
-                    (Some(p), Some(pptr)) => {
-                        assert_eq!(p as *const Node<T>, pptr.as_ptr() as *const Node<T>);
-                    }
-                    _ => panic!("prev link is none, not good"),
-                }
-                match node_ptr.next {
-                    Some(next) => {
-                        last_ptr = Some(node_ptr);
-                        node_ptr = &*next.as_ptr();
-                        len += 1;
-                    }
-                    None => {
-                        len += 1;
-                        break;
-                    }
-                }
-            }
-
-            // verify that the tail node points to the last node.
-            let tail = list.tail.as_ref().expect("some tail node").as_ref();
-            assert_eq!(tail as *const Node<T>, node_ptr as *const Node<T>);
-            // check that len matches interior links.
-            assert_eq!(len, list.len);
-        }
-    }
-
-    #[test]
-    fn test_append() {
-        // Empty to empty
-        {
-            let mut m = LinkedList::<i32>::new();
-            let mut n = LinkedList::new();
-            m.append(&mut n);
-            check_links(&m);
-            assert_eq!(m.len(), 0);
-            assert_eq!(n.len(), 0);
-        }
-        // Non-empty to empty
-        {
-            let mut m = LinkedList::new();
-            let mut n = LinkedList::new();
-            n.push_back(2);
-            m.append(&mut n);
-            check_links(&m);
-            assert_eq!(m.len(), 1);
-            assert_eq!(m.pop_back(), Some(2));
-            assert_eq!(n.len(), 0);
-            check_links(&m);
-        }
-        // Empty to non-empty
-        {
-            let mut m = LinkedList::new();
-            let mut n = LinkedList::new();
-            m.push_back(2);
-            m.append(&mut n);
-            check_links(&m);
-            assert_eq!(m.len(), 1);
-            assert_eq!(m.pop_back(), Some(2));
-            check_links(&m);
-        }
-
-        // Non-empty to non-empty
-        let v = vec![1, 2, 3, 4, 5];
-        let u = vec![9, 8, 1, 2, 3, 4, 5];
-        let mut m = list_from(&v);
-        let mut n = list_from(&u);
-        m.append(&mut n);
-        check_links(&m);
-        let mut sum = v;
-        sum.extend_from_slice(&u);
-        assert_eq!(sum.len(), m.len());
-        for elt in sum {
-            assert_eq!(m.pop_front(), Some(elt))
-        }
-        assert_eq!(n.len(), 0);
-        // let's make sure it's working properly, since we
-        // did some direct changes to private members
-        n.push_back(3);
-        assert_eq!(n.len(), 1);
-        assert_eq!(n.pop_front(), Some(3));
-        check_links(&n);
-    }
-
-    #[test]
-    fn test_insert_prev() {
-        let mut m = list_from(&[0, 2, 4, 6, 8]);
-        let len = m.len();
-        {
-            let mut it = m.iter_mut();
-            it.insert_next(-2);
-            loop {
-                match it.next() {
-                    None => break,
-                    Some(elt) => {
-                        it.insert_next(*elt + 1);
-                        match it.peek_next() {
-                            Some(x) => assert_eq!(*x, *elt + 2),
-                            None => assert_eq!(8, *elt),
-                        }
-                    }
-                }
-            }
-            it.insert_next(0);
-            it.insert_next(1);
-        }
-        check_links(&m);
-        assert_eq!(m.len(), 3 + len * 2);
-        assert_eq!(m.into_iter().collect::<Vec<_>>(),
-                   [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]);
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    #[cfg(not(miri))] // Miri does not support threads
-    fn test_send() {
-        let n = list_from(&[1, 2, 3]);
-        thread::spawn(move || {
-                check_links(&n);
-                let a: &[_] = &[&1, &2, &3];
-                assert_eq!(a, &*n.iter().collect::<Vec<_>>());
-            })
-            .join()
-            .ok()
-            .unwrap();
-    }
-
-    #[test]
-    fn test_fuzz() {
-        for _ in 0..25 {
-            fuzz_test(3);
-            fuzz_test(16);
-            #[cfg(not(miri))] // Miri is too slow
-            fuzz_test(189);
-        }
-    }
-
-    #[test]
-    fn test_26021() {
-        // There was a bug in split_off that failed to null out the RHS's head's prev ptr.
-        // This caused the RHS's dtor to walk up into the LHS at drop and delete all of
-        // its nodes.
-        //
-        // https://github.com/rust-lang/rust/issues/26021
-        let mut v1 = LinkedList::new();
-        v1.push_front(1);
-        v1.push_front(1);
-        v1.push_front(1);
-        v1.push_front(1);
-        let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption
-        assert_eq!(v1.len(), 3);
-
-        assert_eq!(v1.iter().len(), 3);
-        assert_eq!(v1.iter().collect::<Vec<_>>().len(), 3);
-    }
-
-    #[test]
-    fn test_split_off() {
-        let mut v1 = LinkedList::new();
-        v1.push_front(1);
-        v1.push_front(1);
-        v1.push_front(1);
-        v1.push_front(1);
-
-        // test all splits
-        for ix in 0..1 + v1.len() {
-            let mut a = v1.clone();
-            let b = a.split_off(ix);
-            check_links(&a);
-            check_links(&b);
-            a.extend(b);
-            assert_eq!(v1, a);
-        }
-    }
-
-    #[cfg(test)]
-    fn fuzz_test(sz: i32) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        let mut v = vec![];
-        for i in 0..sz {
-            check_links(&m);
-            let r: u8 = thread_rng().next_u32() as u8;
-            match r % 6 {
-                0 => {
-                    m.pop_back();
-                    v.pop();
-                }
-                1 => {
-                    if !v.is_empty() {
-                        m.pop_front();
-                        v.remove(0);
-                    }
-                }
-                2 | 4 => {
-                    m.push_front(-i);
-                    v.insert(0, -i);
-                }
-                3 | 5 | _ => {
-                    m.push_back(i);
-                    v.push(i);
-                }
-            }
-        }
-
-        check_links(&m);
-
-        let mut i = 0;
-        for (a, &b) in m.into_iter().zip(&v) {
-            i += 1;
-            assert_eq!(a, b);
-        }
-        assert_eq!(i, v.len());
-    }
-
-    #[test]
-    fn drain_filter_test() {
-        let mut m: LinkedList<u32> = LinkedList::new();
-        m.extend(&[1, 2, 3, 4, 5, 6]);
-        let deleted = m.drain_filter(|v| *v < 4).collect::<Vec<_>>();
-
-        check_links(&m);
-
-        assert_eq!(deleted, &[1, 2, 3]);
-        assert_eq!(m.into_iter().collect::<Vec<_>>(), &[4, 5, 6]);
-    }
-
-    #[test]
-    fn drain_to_empty_test() {
-        let mut m: LinkedList<u32> = LinkedList::new();
-        m.extend(&[1, 2, 3, 4, 5, 6]);
-        let deleted = m.drain_filter(|_| true).collect::<Vec<_>>();
-
-        check_links(&m);
-
-        assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]);
-        assert_eq!(m.into_iter().collect::<Vec<_>>(), &[]);
-    }
-}
diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs
new file mode 100644
index 00000000000..9a6c57d2869
--- /dev/null
+++ b/src/liballoc/collections/linked_list/tests.rs
@@ -0,0 +1,264 @@
+use super::*;
+
+use std::thread;
+use std::vec::Vec;
+
+use rand::{thread_rng, RngCore};
+
+fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
+    v.iter().cloned().collect()
+}
+
+pub fn check_links<T>(list: &LinkedList<T>) {
+    unsafe {
+        let mut len = 0;
+        let mut last_ptr: Option<&Node<T>> = None;
+        let mut node_ptr: &Node<T>;
+        match list.head {
+            None => {
+                // tail node should also be None.
+                assert!(list.tail.is_none());
+                assert_eq!(0, list.len);
+                return;
+            }
+            Some(node) => node_ptr = &*node.as_ptr(),
+        }
+        loop {
+            match (last_ptr, node_ptr.prev) {
+                (None, None) => {}
+                (None, _) => panic!("prev link for head"),
+                (Some(p), Some(pptr)) => {
+                    assert_eq!(p as *const Node<T>, pptr.as_ptr() as *const Node<T>);
+                }
+                _ => panic!("prev link is none, not good"),
+            }
+            match node_ptr.next {
+                Some(next) => {
+                    last_ptr = Some(node_ptr);
+                    node_ptr = &*next.as_ptr();
+                    len += 1;
+                }
+                None => {
+                    len += 1;
+                    break;
+                }
+            }
+        }
+
+        // verify that the tail node points to the last node.
+        let tail = list.tail.as_ref().expect("some tail node").as_ref();
+        assert_eq!(tail as *const Node<T>, node_ptr as *const Node<T>);
+        // check that len matches interior links.
+        assert_eq!(len, list.len);
+    }
+}
+
+#[test]
+fn test_append() {
+    // Empty to empty
+    {
+        let mut m = LinkedList::<i32>::new();
+        let mut n = LinkedList::new();
+        m.append(&mut n);
+        check_links(&m);
+        assert_eq!(m.len(), 0);
+        assert_eq!(n.len(), 0);
+    }
+    // Non-empty to empty
+    {
+        let mut m = LinkedList::new();
+        let mut n = LinkedList::new();
+        n.push_back(2);
+        m.append(&mut n);
+        check_links(&m);
+        assert_eq!(m.len(), 1);
+        assert_eq!(m.pop_back(), Some(2));
+        assert_eq!(n.len(), 0);
+        check_links(&m);
+    }
+    // Empty to non-empty
+    {
+        let mut m = LinkedList::new();
+        let mut n = LinkedList::new();
+        m.push_back(2);
+        m.append(&mut n);
+        check_links(&m);
+        assert_eq!(m.len(), 1);
+        assert_eq!(m.pop_back(), Some(2));
+        check_links(&m);
+    }
+
+    // Non-empty to non-empty
+    let v = vec![1, 2, 3, 4, 5];
+    let u = vec![9, 8, 1, 2, 3, 4, 5];
+    let mut m = list_from(&v);
+    let mut n = list_from(&u);
+    m.append(&mut n);
+    check_links(&m);
+    let mut sum = v;
+    sum.extend_from_slice(&u);
+    assert_eq!(sum.len(), m.len());
+    for elt in sum {
+        assert_eq!(m.pop_front(), Some(elt))
+    }
+    assert_eq!(n.len(), 0);
+    // let's make sure it's working properly, since we
+    // did some direct changes to private members
+    n.push_back(3);
+    assert_eq!(n.len(), 1);
+    assert_eq!(n.pop_front(), Some(3));
+    check_links(&n);
+}
+
+#[test]
+fn test_insert_prev() {
+    let mut m = list_from(&[0, 2, 4, 6, 8]);
+    let len = m.len();
+    {
+        let mut it = m.iter_mut();
+        it.insert_next(-2);
+        loop {
+            match it.next() {
+                None => break,
+                Some(elt) => {
+                    it.insert_next(*elt + 1);
+                    match it.peek_next() {
+                        Some(x) => assert_eq!(*x, *elt + 2),
+                        None => assert_eq!(8, *elt),
+                    }
+                }
+            }
+        }
+        it.insert_next(0);
+        it.insert_next(1);
+    }
+    check_links(&m);
+    assert_eq!(m.len(), 3 + len * 2);
+    assert_eq!(m.into_iter().collect::<Vec<_>>(),
+                [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]);
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+#[cfg(not(miri))] // Miri does not support threads
+fn test_send() {
+    let n = list_from(&[1, 2, 3]);
+    thread::spawn(move || {
+            check_links(&n);
+            let a: &[_] = &[&1, &2, &3];
+            assert_eq!(a, &*n.iter().collect::<Vec<_>>());
+        })
+        .join()
+        .ok()
+        .unwrap();
+}
+
+#[test]
+fn test_fuzz() {
+    for _ in 0..25 {
+        fuzz_test(3);
+        fuzz_test(16);
+        #[cfg(not(miri))] // Miri is too slow
+        fuzz_test(189);
+    }
+}
+
+#[test]
+fn test_26021() {
+    // There was a bug in split_off that failed to null out the RHS's head's prev ptr.
+    // This caused the RHS's dtor to walk up into the LHS at drop and delete all of
+    // its nodes.
+    //
+    // https://github.com/rust-lang/rust/issues/26021
+    let mut v1 = LinkedList::new();
+    v1.push_front(1);
+    v1.push_front(1);
+    v1.push_front(1);
+    v1.push_front(1);
+    let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption
+    assert_eq!(v1.len(), 3);
+
+    assert_eq!(v1.iter().len(), 3);
+    assert_eq!(v1.iter().collect::<Vec<_>>().len(), 3);
+}
+
+#[test]
+fn test_split_off() {
+    let mut v1 = LinkedList::new();
+    v1.push_front(1);
+    v1.push_front(1);
+    v1.push_front(1);
+    v1.push_front(1);
+
+    // test all splits
+    for ix in 0..1 + v1.len() {
+        let mut a = v1.clone();
+        let b = a.split_off(ix);
+        check_links(&a);
+        check_links(&b);
+        a.extend(b);
+        assert_eq!(v1, a);
+    }
+}
+
+fn fuzz_test(sz: i32) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    let mut v = vec![];
+    for i in 0..sz {
+        check_links(&m);
+        let r: u8 = thread_rng().next_u32() as u8;
+        match r % 6 {
+            0 => {
+                m.pop_back();
+                v.pop();
+            }
+            1 => {
+                if !v.is_empty() {
+                    m.pop_front();
+                    v.remove(0);
+                }
+            }
+            2 | 4 => {
+                m.push_front(-i);
+                v.insert(0, -i);
+            }
+            3 | 5 | _ => {
+                m.push_back(i);
+                v.push(i);
+            }
+        }
+    }
+
+    check_links(&m);
+
+    let mut i = 0;
+    for (a, &b) in m.into_iter().zip(&v) {
+        i += 1;
+        assert_eq!(a, b);
+    }
+    assert_eq!(i, v.len());
+}
+
+#[test]
+fn drain_filter_test() {
+    let mut m: LinkedList<u32> = LinkedList::new();
+    m.extend(&[1, 2, 3, 4, 5, 6]);
+    let deleted = m.drain_filter(|v| *v < 4).collect::<Vec<_>>();
+
+    check_links(&m);
+
+    assert_eq!(deleted, &[1, 2, 3]);
+    assert_eq!(m.into_iter().collect::<Vec<_>>(), &[4, 5, 6]);
+}
+
+#[test]
+fn drain_to_empty_test() {
+    let mut m: LinkedList<u32> = LinkedList::new();
+    m.extend(&[1, 2, 3, 4, 5, 6]);
+    let deleted = m.drain_filter(|_| true).collect::<Vec<_>>();
+
+    check_links(&m);
+
+    assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]);
+    assert_eq!(m.into_iter().collect::<Vec<_>>(), &[]);
+}
diff --git a/src/liballoc/collections/mod.rs b/src/liballoc/collections/mod.rs
index 5a33ddc14f0..f1f22fe48c5 100644
--- a/src/liballoc/collections/mod.rs
+++ b/src/liballoc/collections/mod.rs
@@ -41,32 +41,35 @@ pub use linked_list::LinkedList;
 #[doc(no_inline)]
 pub use vec_deque::VecDeque;
 
-use crate::alloc::{AllocErr, LayoutErr};
+use crate::alloc::{Layout, LayoutErr};
 
-/// Augments `AllocErr` with a CapacityOverflow variant.
+/// The error type for `try_reserve` methods.
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-pub enum CollectionAllocErr {
+pub enum TryReserveError {
     /// Error due to the computed capacity exceeding the collection's maximum
     /// (usually `isize::MAX` bytes).
     CapacityOverflow,
-    /// Error due to the allocator (see the `AllocErr` type's docs).
-    AllocErr,
-}
 
-#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-impl From<AllocErr> for CollectionAllocErr {
-    #[inline]
-    fn from(AllocErr: AllocErr) -> Self {
-        CollectionAllocErr::AllocErr
-    }
+    /// The memory allocator returned an error
+    AllocError {
+        /// The layout of allocation request that failed
+        layout: Layout,
+
+        #[doc(hidden)]
+        #[unstable(feature = "container_error_extra", issue = "0", reason = "\
+            Enable exposing the allocator’s custom error value \
+            if an associated type is added in the future: \
+            https://github.com/rust-lang/wg-allocators/issues/23")]
+        non_exhaustive: (),
+    },
 }
 
 #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-impl From<LayoutErr> for CollectionAllocErr {
+impl From<LayoutErr> for TryReserveError {
     #[inline]
     fn from(_: LayoutErr) -> Self {
-        CollectionAllocErr::CapacityOverflow
+        TryReserveError::CapacityOverflow
     }
 }
 
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 9a8d48083e6..7315963cc8b 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 //! A double-ended queue implemented with a growable ring buffer.
 //!
 //! This queue has `O(1)` amortized inserts and removals from both ends of the
@@ -9,6 +7,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use core::array::LengthAtMost32;
 use core::cmp::{self, Ordering};
 use core::fmt;
 use core::iter::{repeat_with, FromIterator, FusedIterator};
@@ -19,10 +18,13 @@ use core::ptr::{self, NonNull};
 use core::slice;
 use core::hash::{Hash, Hasher};
 
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::raw_vec::RawVec;
 use crate::vec::Vec;
 
+#[cfg(test)]
+mod tests;
+
 const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
 const MINIMUM_CAPACITY: usize = 1; // 2 - 1
 #[cfg(target_pointer_width = "16")]
@@ -98,7 +100,7 @@ impl<T> VecDeque<T> {
             // For zero sized types, we are always at maximum capacity
             MAXIMUM_ZST_CAPACITY
         } else {
-            self.buf.cap()
+            self.buf.capacity()
         }
     }
 
@@ -314,10 +316,10 @@ impl<T> VecDeque<T> {
     }
 
     /// Frobs the head and tail sections around to handle the fact that we
-    /// just reallocated. Unsafe because it trusts old_cap.
+    /// just reallocated. Unsafe because it trusts old_capacity.
     #[inline]
-    unsafe fn handle_cap_increase(&mut self, old_cap: usize) {
-        let new_cap = self.cap();
+    unsafe fn handle_capacity_increase(&mut self, old_capacity: usize) {
+        let new_capacity = self.cap();
 
         // Move the shortest contiguous section of the ring buffer
         //    T             H
@@ -336,15 +338,15 @@ impl<T> VecDeque<T> {
         if self.tail <= self.head {
             // A
             // Nop
-        } else if self.head < old_cap - self.tail {
+        } else if self.head < old_capacity - self.tail {
             // B
-            self.copy_nonoverlapping(old_cap, 0, self.head);
-            self.head += old_cap;
+            self.copy_nonoverlapping(old_capacity, 0, self.head);
+            self.head += old_capacity;
             debug_assert!(self.head > self.tail);
         } else {
             // C
-            let new_tail = new_cap - (old_cap - self.tail);
-            self.copy_nonoverlapping(new_tail, self.tail, old_cap - self.tail);
+            let new_tail = new_capacity - (old_capacity - self.tail);
+            self.copy_nonoverlapping(new_tail, self.tail, old_capacity - self.tail);
             self.tail = new_tail;
             debug_assert!(self.head < self.tail);
         }
@@ -551,7 +553,7 @@ impl<T> VecDeque<T> {
         if new_cap > old_cap {
             self.buf.reserve_exact(used_cap, new_cap - used_cap);
             unsafe {
-                self.handle_cap_increase(old_cap);
+                self.handle_capacity_increase(old_cap);
             }
         }
     }
@@ -574,10 +576,10 @@ impl<T> VecDeque<T> {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     /// use std::collections::VecDeque;
     ///
-    /// fn process_data(data: &[u32]) -> Result<VecDeque<u32>, CollectionAllocErr> {
+    /// fn process_data(data: &[u32]) -> Result<VecDeque<u32>, TryReserveError> {
     ///     let mut output = VecDeque::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -593,7 +595,7 @@ impl<T> VecDeque<T> {
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr>  {
+    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError>  {
         self.try_reserve(additional)
     }
 
@@ -612,10 +614,10 @@ impl<T> VecDeque<T> {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     /// use std::collections::VecDeque;
     ///
-    /// fn process_data(data: &[u32]) -> Result<VecDeque<u32>, CollectionAllocErr> {
+    /// fn process_data(data: &[u32]) -> Result<VecDeque<u32>, TryReserveError> {
     ///     let mut output = VecDeque::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -631,17 +633,17 @@ impl<T> VecDeque<T> {
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         let old_cap = self.cap();
         let used_cap = self.len() + 1;
         let new_cap = used_cap.checked_add(additional)
             .and_then(|needed_cap| needed_cap.checked_next_power_of_two())
-            .ok_or(CollectionAllocErr::CapacityOverflow)?;
+            .ok_or(TryReserveError::CapacityOverflow)?;
 
         if new_cap > old_cap {
             self.buf.try_reserve_exact(used_cap, new_cap - used_cap)?;
             unsafe {
-                self.handle_cap_increase(old_cap);
+                self.handle_capacity_increase(old_cap);
             }
         }
         Ok(())
@@ -1197,6 +1199,31 @@ impl<T> VecDeque<T> {
         }
     }
 
+    /// Removes the last element from the `VecDeque` and returns it, or `None` if
+    /// it is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// assert_eq!(buf.pop_back(), None);
+    /// buf.push_back(1);
+    /// buf.push_back(3);
+    /// assert_eq!(buf.pop_back(), Some(3));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn pop_back(&mut self) -> Option<T> {
+        if self.is_empty() {
+            None
+        } else {
+            self.head = self.wrap_sub(self.head, 1);
+            let head = self.head;
+            unsafe { Some(self.buffer_read(head)) }
+        }
+    }
+
     /// Prepends an element to the `VecDeque`.
     ///
     /// # Examples
@@ -1241,38 +1268,13 @@ impl<T> VecDeque<T> {
         unsafe { self.buffer_write(head, value) }
     }
 
-    /// Removes the last element from the `VecDeque` and returns it, or `None` if
-    /// it is empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::VecDeque;
-    ///
-    /// let mut buf = VecDeque::new();
-    /// assert_eq!(buf.pop_back(), None);
-    /// buf.push_back(1);
-    /// buf.push_back(3);
-    /// assert_eq!(buf.pop_back(), Some(3));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn pop_back(&mut self) -> Option<T> {
-        if self.is_empty() {
-            None
-        } else {
-            self.head = self.wrap_sub(self.head, 1);
-            let head = self.head;
-            unsafe { Some(self.buffer_read(head)) }
-        }
-    }
-
     #[inline]
     fn is_contiguous(&self) -> bool {
         self.tail <= self.head
     }
 
-    /// Removes an element from anywhere in the `VecDeque` and returns it, replacing it with the
-    /// last element.
+    /// Removes an element from anywhere in the `VecDeque` and returns it,
+    /// replacing it with the first element.
     ///
     /// This does not preserve ordering, but is O(1).
     ///
@@ -1286,28 +1288,28 @@ impl<T> VecDeque<T> {
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
-    /// assert_eq!(buf.swap_remove_back(0), None);
+    /// assert_eq!(buf.swap_remove_front(0), None);
     /// buf.push_back(1);
     /// buf.push_back(2);
     /// buf.push_back(3);
     /// assert_eq!(buf, [1, 2, 3]);
     ///
-    /// assert_eq!(buf.swap_remove_back(0), Some(1));
-    /// assert_eq!(buf, [3, 2]);
+    /// assert_eq!(buf.swap_remove_front(2), Some(3));
+    /// assert_eq!(buf, [2, 1]);
     /// ```
     #[stable(feature = "deque_extras_15", since = "1.5.0")]
-    pub fn swap_remove_back(&mut self, index: usize) -> Option<T> {
+    pub fn swap_remove_front(&mut self, index: usize) -> Option<T> {
         let length = self.len();
-        if length > 0 && index < length - 1 {
-            self.swap(index, length - 1);
+        if length > 0 && index < length && index != 0 {
+            self.swap(index, 0);
         } else if index >= length {
             return None;
         }
-        self.pop_back()
+        self.pop_front()
     }
 
-    /// Removes an element from anywhere in the `VecDeque` and returns it,
-    /// replacing it with the first element.
+    /// Removes an element from anywhere in the `VecDeque` and returns it, replacing it with the
+    /// last element.
     ///
     /// This does not preserve ordering, but is O(1).
     ///
@@ -1321,24 +1323,24 @@ impl<T> VecDeque<T> {
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
-    /// assert_eq!(buf.swap_remove_front(0), None);
+    /// assert_eq!(buf.swap_remove_back(0), None);
     /// buf.push_back(1);
     /// buf.push_back(2);
     /// buf.push_back(3);
     /// assert_eq!(buf, [1, 2, 3]);
     ///
-    /// assert_eq!(buf.swap_remove_front(2), Some(3));
-    /// assert_eq!(buf, [2, 1]);
+    /// assert_eq!(buf.swap_remove_back(0), Some(1));
+    /// assert_eq!(buf, [3, 2]);
     /// ```
     #[stable(feature = "deque_extras_15", since = "1.5.0")]
-    pub fn swap_remove_front(&mut self, index: usize) -> Option<T> {
+    pub fn swap_remove_back(&mut self, index: usize) -> Option<T> {
         let length = self.len();
-        if length > 0 && index < length && index != 0 {
-            self.swap(index, 0);
+        if length > 0 && index < length - 1 {
+            self.swap(index, length - 1);
         } else if index >= length {
             return None;
         }
-        self.pop_front()
+        self.pop_back()
     }
 
     /// Inserts an element at `index` within the `VecDeque`, shifting all elements with indices
@@ -1887,7 +1889,7 @@ impl<T> VecDeque<T> {
             let old_cap = self.cap();
             self.buf.double();
             unsafe {
-                self.handle_cap_increase(old_cap);
+                self.handle_capacity_increase(old_cap);
             }
             debug_assert!(!self.is_full());
         }
@@ -1948,8 +1950,6 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(vecdeque_rotate)]
-    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<_> = (0..10).collect();
@@ -1963,7 +1963,7 @@ impl<T> VecDeque<T> {
     /// }
     /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
     /// ```
-    #[unstable(feature = "vecdeque_rotate", issue = "56686")]
+    #[stable(feature = "vecdeque_rotate", since = "1.36.0")]
     pub fn rotate_left(&mut self, mid: usize) {
         assert!(mid <= self.len());
         let k = self.len() - mid;
@@ -1993,8 +1993,6 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(vecdeque_rotate)]
-    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<_> = (0..10).collect();
@@ -2008,7 +2006,7 @@ impl<T> VecDeque<T> {
     /// }
     /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
     /// ```
-    #[unstable(feature = "vecdeque_rotate", issue = "56686")]
+    #[stable(feature = "vecdeque_rotate", since = "1.36.0")]
     pub fn rotate_right(&mut self, k: usize) {
         assert!(k <= self.len());
         let mid = self.len() - k;
@@ -2210,6 +2208,11 @@ impl<'a, T> Iterator for Iter<'a, T> {
         self.tail = self.head - iter.len();
         final_res
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2323,6 +2326,11 @@ impl<'a, T> Iterator for IterMut<'a, T> {
         accum = front.iter_mut().fold(accum, &mut f);
         back.iter_mut().fold(accum, &mut f)
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a mut T> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2565,13 +2573,14 @@ impl<A: PartialEq> PartialEq for VecDeque<A> {
 impl<A: Eq> Eq for VecDeque<A> {}
 
 macro_rules! __impl_slice_eq1 {
-    ($Lhs: ty, $Rhs: ty) => {
-        __impl_slice_eq1! { $Lhs, $Rhs, Sized }
-    };
-    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
+    ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => {
         #[stable(feature = "vec_deque_partial_eq_slice", since = "1.17.0")]
-        impl<A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
-            fn eq(&self, other: &$Rhs) -> bool {
+        impl<A, B, $($vars)*> PartialEq<$rhs> for $lhs
+        where
+            A: PartialEq<B>,
+            $($constraints)*
+        {
+            fn eq(&self, other: &$rhs) -> bool {
                 if self.len() != other.len() {
                     return false;
                 }
@@ -2583,26 +2592,12 @@ macro_rules! __impl_slice_eq1 {
     }
 }
 
-__impl_slice_eq1! { VecDeque<A>, Vec<B> }
-__impl_slice_eq1! { VecDeque<A>, &[B] }
-__impl_slice_eq1! { VecDeque<A>, &mut [B] }
-
-macro_rules! array_impls {
-    ($($N: expr)+) => {
-        $(
-            __impl_slice_eq1! { VecDeque<A>, [B; $N] }
-            __impl_slice_eq1! { VecDeque<A>, &[B; $N] }
-            __impl_slice_eq1! { VecDeque<A>, &mut [B; $N] }
-        )+
-    }
-}
-
-array_impls! {
-     0  1  2  3  4  5  6  7  8  9
-    10 11 12 13 14 15 16 17 18 19
-    20 21 22 23 24 25 26 27 28 29
-    30 31 32
-}
+__impl_slice_eq1! { [] VecDeque<A>, Vec<B>, }
+__impl_slice_eq1! { [] VecDeque<A>, &[B], }
+__impl_slice_eq1! { [] VecDeque<A>, &mut [B], }
+__impl_slice_eq1! { [const N: usize] VecDeque<A>, [B; N], [B; N]: LengthAtMost32 }
+__impl_slice_eq1! { [const N: usize] VecDeque<A>, &[B; N], [B; N]: LengthAtMost32 }
+__impl_slice_eq1! { [const N: usize] VecDeque<A>, &mut [B; N], [B; N]: LengthAtMost32 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A: PartialOrd> PartialOrd for VecDeque<A> {
@@ -2713,6 +2708,14 @@ impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
 
 #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")]
 impl<T> From<Vec<T>> for VecDeque<T> {
+    /// Turn a [`Vec<T>`] into a [`VecDeque<T>`].
+    ///
+    /// [`Vec<T>`]: crate::vec::Vec
+    /// [`VecDeque<T>`]: crate::collections::VecDeque
+    ///
+    /// This avoids reallocating where possible, but the conditions for that are
+    /// strict, and subject to change, and so shouldn't be relied upon unless the
+    /// `Vec<T>` came from `From<VecDeque<T>>` and hasn't been reallocated.
     fn from(mut other: Vec<T>) -> Self {
         unsafe {
             let other_buf = other.as_mut_ptr();
@@ -2722,9 +2725,9 @@ impl<T> From<Vec<T>> for VecDeque<T> {
 
             // We need to extend the buf if it's not a power of two, too small
             // or doesn't have at least one free space
-            if !buf.cap().is_power_of_two() || (buf.cap() < (MINIMUM_CAPACITY + 1)) ||
-               (buf.cap() == len) {
-                let cap = cmp::max(buf.cap() + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
+            if !buf.capacity().is_power_of_two() || (buf.capacity() < (MINIMUM_CAPACITY + 1)) ||
+               (buf.capacity() == len) {
+                let cap = cmp::max(buf.capacity() + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
                 buf.reserve_exact(len, cap - len);
             }
 
@@ -2739,6 +2742,35 @@ impl<T> From<Vec<T>> for VecDeque<T> {
 
 #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")]
 impl<T> From<VecDeque<T>> for Vec<T> {
+    /// Turn a [`VecDeque<T>`] into a [`Vec<T>`].
+    ///
+    /// [`Vec<T>`]: crate::vec::Vec
+    /// [`VecDeque<T>`]: crate::collections::VecDeque
+    ///
+    /// This never needs to re-allocate, but does need to do O(n) data movement if
+    /// the circular buffer doesn't happen to be at the beginning of the allocation.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// // This one is O(1).
+    /// let deque: VecDeque<_> = (1..5).collect();
+    /// let ptr = deque.as_slices().0.as_ptr();
+    /// let vec = Vec::from(deque);
+    /// assert_eq!(vec, [1, 2, 3, 4]);
+    /// assert_eq!(vec.as_ptr(), ptr);
+    ///
+    /// // This one needs data rearranging.
+    /// let mut deque: VecDeque<_> = (1..5).collect();
+    /// deque.push_front(9);
+    /// deque.push_front(8);
+    /// let ptr = deque.as_slices().1.as_ptr();
+    /// let vec = Vec::from(deque);
+    /// assert_eq!(vec, [8, 9, 1, 2, 3, 4]);
+    /// assert_eq!(vec.as_ptr(), ptr);
+    /// ```
     fn from(other: VecDeque<T>) -> Self {
         unsafe {
             let buf = other.buf.ptr();
@@ -2807,387 +2839,3 @@ impl<T> From<VecDeque<T>> for Vec<T> {
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use ::test;
-
-    use super::VecDeque;
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn bench_push_back_100(b: &mut test::Bencher) {
-        let mut deq = VecDeque::with_capacity(101);
-        b.iter(|| {
-            for i in 0..100 {
-                deq.push_back(i);
-            }
-            deq.head = 0;
-            deq.tail = 0;
-        })
-    }
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn bench_push_front_100(b: &mut test::Bencher) {
-        let mut deq = VecDeque::with_capacity(101);
-        b.iter(|| {
-            for i in 0..100 {
-                deq.push_front(i);
-            }
-            deq.head = 0;
-            deq.tail = 0;
-        })
-    }
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn bench_pop_back_100(b: &mut test::Bencher) {
-        let mut deq = VecDeque::<i32>::with_capacity(101);
-
-        b.iter(|| {
-            deq.head = 100;
-            deq.tail = 0;
-            while !deq.is_empty() {
-                test::black_box(deq.pop_back());
-            }
-        })
-    }
-
-    #[bench]
-    #[cfg(not(miri))] // Miri does not support benchmarks
-    fn bench_pop_front_100(b: &mut test::Bencher) {
-        let mut deq = VecDeque::<i32>::with_capacity(101);
-
-        b.iter(|| {
-            deq.head = 100;
-            deq.tail = 0;
-            while !deq.is_empty() {
-                test::black_box(deq.pop_front());
-            }
-        })
-    }
-
-    #[test]
-    fn test_swap_front_back_remove() {
-        fn test(back: bool) {
-            // This test checks that every single combination of tail position and length is tested.
-            // Capacity 15 should be large enough to cover every case.
-            let mut tester = VecDeque::with_capacity(15);
-            let usable_cap = tester.capacity();
-            let final_len = usable_cap / 2;
-
-            for len in 0..final_len {
-                let expected: VecDeque<_> = if back {
-                    (0..len).collect()
-                } else {
-                    (0..len).rev().collect()
-                };
-                for tail_pos in 0..usable_cap {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    if back {
-                        for i in 0..len * 2 {
-                            tester.push_front(i);
-                        }
-                        for i in 0..len {
-                            assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i));
-                        }
-                    } else {
-                        for i in 0..len * 2 {
-                            tester.push_back(i);
-                        }
-                        for i in 0..len {
-                            let idx = tester.len() - 1 - i;
-                            assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i));
-                        }
-                    }
-                    assert!(tester.tail < tester.cap());
-                    assert!(tester.head < tester.cap());
-                    assert_eq!(tester, expected);
-                }
-            }
-        }
-        test(true);
-        test(false);
-    }
-
-    #[test]
-    fn test_insert() {
-        // This test checks that every single combination of tail position, length, and
-        // insertion position is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = VecDeque::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-
-
-        // len is the length *after* insertion
-        for len in 1..cap {
-            // 0, 1, 2, .., len - 1
-            let expected = (0..).take(len).collect::<VecDeque<_>>();
-            for tail_pos in 0..cap {
-                for to_insert in 0..len {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    for i in 0..len {
-                        if i != to_insert {
-                            tester.push_back(i);
-                        }
-                    }
-                    tester.insert(to_insert, to_insert);
-                    assert!(tester.tail < tester.cap());
-                    assert!(tester.head < tester.cap());
-                    assert_eq!(tester, expected);
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_remove() {
-        // This test checks that every single combination of tail position, length, and
-        // removal position is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = VecDeque::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-
-        // len is the length *after* removal
-        for len in 0..cap - 1 {
-            // 0, 1, 2, .., len - 1
-            let expected = (0..).take(len).collect::<VecDeque<_>>();
-            for tail_pos in 0..cap {
-                for to_remove in 0..=len {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    for i in 0..len {
-                        if i == to_remove {
-                            tester.push_back(1234);
-                        }
-                        tester.push_back(i);
-                    }
-                    if to_remove == len {
-                        tester.push_back(1234);
-                    }
-                    tester.remove(to_remove);
-                    assert!(tester.tail < tester.cap());
-                    assert!(tester.head < tester.cap());
-                    assert_eq!(tester, expected);
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_drain() {
-        let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
-
-        let cap = tester.capacity();
-        for len in 0..=cap {
-            for tail in 0..=cap {
-                for drain_start in 0..=len {
-                    for drain_end in drain_start..=len {
-                        tester.tail = tail;
-                        tester.head = tail;
-                        for i in 0..len {
-                            tester.push_back(i);
-                        }
-
-                        // Check that we drain the correct values
-                        let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect();
-                        let drained_expected: VecDeque<_> = (drain_start..drain_end).collect();
-                        assert_eq!(drained, drained_expected);
-
-                        // We shouldn't have changed the capacity or made the
-                        // head or tail out of bounds
-                        assert_eq!(tester.capacity(), cap);
-                        assert!(tester.tail < tester.cap());
-                        assert!(tester.head < tester.cap());
-
-                        // We should see the correct values in the VecDeque
-                        let expected: VecDeque<_> = (0..drain_start)
-                            .chain(drain_end..len)
-                            .collect();
-                        assert_eq!(expected, tester);
-                    }
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_shrink_to_fit() {
-        // This test checks that every single combination of head and tail position,
-        // is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = VecDeque::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-        tester.reserve(63);
-        let max_cap = tester.capacity();
-
-        for len in 0..=cap {
-            // 0, 1, 2, .., len - 1
-            let expected = (0..).take(len).collect::<VecDeque<_>>();
-            for tail_pos in 0..=max_cap {
-                tester.tail = tail_pos;
-                tester.head = tail_pos;
-                tester.reserve(63);
-                for i in 0..len {
-                    tester.push_back(i);
-                }
-                tester.shrink_to_fit();
-                assert!(tester.capacity() <= cap);
-                assert!(tester.tail < tester.cap());
-                assert!(tester.head < tester.cap());
-                assert_eq!(tester, expected);
-            }
-        }
-    }
-
-    #[test]
-    fn test_split_off() {
-        // This test checks that every single combination of tail position, length, and
-        // split position is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = VecDeque::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-
-        // len is the length *before* splitting
-        for len in 0..cap {
-            // index to split at
-            for at in 0..=len {
-                // 0, 1, 2, .., at - 1 (may be empty)
-                let expected_self = (0..).take(at).collect::<VecDeque<_>>();
-                // at, at + 1, .., len - 1 (may be empty)
-                let expected_other = (at..).take(len - at).collect::<VecDeque<_>>();
-
-                for tail_pos in 0..cap {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    for i in 0..len {
-                        tester.push_back(i);
-                    }
-                    let result = tester.split_off(at);
-                    assert!(tester.tail < tester.cap());
-                    assert!(tester.head < tester.cap());
-                    assert!(result.tail < result.cap());
-                    assert!(result.head < result.cap());
-                    assert_eq!(tester, expected_self);
-                    assert_eq!(result, expected_other);
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_from_vec() {
-        use crate::vec::Vec;
-        for cap in 0..35 {
-            for len in 0..=cap {
-                let mut vec = Vec::with_capacity(cap);
-                vec.extend(0..len);
-
-                let vd = VecDeque::from(vec.clone());
-                assert!(vd.cap().is_power_of_two());
-                assert_eq!(vd.len(), vec.len());
-                assert!(vd.into_iter().eq(vec));
-            }
-        }
-    }
-
-    #[test]
-    fn test_vec_from_vecdeque() {
-        use crate::vec::Vec;
-
-        fn create_vec_and_test_convert(cap: usize, offset: usize, len: usize) {
-            let mut vd = VecDeque::with_capacity(cap);
-            for _ in 0..offset {
-                vd.push_back(0);
-                vd.pop_front();
-            }
-            vd.extend(0..len);
-
-            let vec: Vec<_> = Vec::from(vd.clone());
-            assert_eq!(vec.len(), vd.len());
-            assert!(vec.into_iter().eq(vd));
-        }
-
-        #[cfg(not(miri))] // Miri is too slow
-        let max_pwr = 7;
-        #[cfg(miri)]
-        let max_pwr = 5;
-
-        for cap_pwr in 0..max_pwr {
-            // Make capacity as a (2^x)-1, so that the ring size is 2^x
-            let cap = (2i32.pow(cap_pwr) - 1) as usize;
-
-            // In these cases there is enough free space to solve it with copies
-            for len in 0..((cap + 1) / 2) {
-                // Test contiguous cases
-                for offset in 0..(cap - len) {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-
-                // Test cases where block at end of buffer is bigger than block at start
-                for offset in (cap - len)..(cap - (len / 2)) {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-
-                // Test cases where block at start of buffer is bigger than block at end
-                for offset in (cap - (len / 2))..cap {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-            }
-
-            // Now there's not (necessarily) space to straighten the ring with simple copies,
-            // the ring will use swapping when:
-            // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len))
-            //  right block size  >   free space    &&      left block size       >    free space
-            for len in ((cap + 1) / 2)..cap {
-                // Test contiguous cases
-                for offset in 0..(cap - len) {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-
-                // Test cases where block at end of buffer is bigger than block at start
-                for offset in (cap - len)..(cap - (len / 2)) {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-
-                // Test cases where block at start of buffer is bigger than block at end
-                for offset in (cap - (len / 2))..cap {
-                    create_vec_and_test_convert(cap, offset, len)
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn issue_53529() {
-        use crate::boxed::Box;
-
-        let mut dst = VecDeque::new();
-        dst.push_front(Box::new(1));
-        dst.push_front(Box::new(2));
-        assert_eq!(*dst.pop_back().unwrap(), 1);
-
-        let mut src = VecDeque::new();
-        src.push_front(Box::new(2));
-        dst.append(&mut src);
-        for a in dst {
-            assert_eq!(*a, 2);
-        }
-    }
-
-}
diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs
new file mode 100644
index 00000000000..d2535239979
--- /dev/null
+++ b/src/liballoc/collections/vec_deque/tests.rs
@@ -0,0 +1,379 @@
+use super::*;
+
+use ::test;
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn bench_push_back_100(b: &mut test::Bencher) {
+    let mut deq = VecDeque::with_capacity(101);
+    b.iter(|| {
+        for i in 0..100 {
+            deq.push_back(i);
+        }
+        deq.head = 0;
+        deq.tail = 0;
+    })
+}
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn bench_push_front_100(b: &mut test::Bencher) {
+    let mut deq = VecDeque::with_capacity(101);
+    b.iter(|| {
+        for i in 0..100 {
+            deq.push_front(i);
+        }
+        deq.head = 0;
+        deq.tail = 0;
+    })
+}
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn bench_pop_back_100(b: &mut test::Bencher) {
+    let mut deq = VecDeque::<i32>::with_capacity(101);
+
+    b.iter(|| {
+        deq.head = 100;
+        deq.tail = 0;
+        while !deq.is_empty() {
+            test::black_box(deq.pop_back());
+        }
+    })
+}
+
+#[bench]
+#[cfg(not(miri))] // Miri does not support benchmarks
+fn bench_pop_front_100(b: &mut test::Bencher) {
+    let mut deq = VecDeque::<i32>::with_capacity(101);
+
+    b.iter(|| {
+        deq.head = 100;
+        deq.tail = 0;
+        while !deq.is_empty() {
+            test::black_box(deq.pop_front());
+        }
+    })
+}
+
+#[test]
+fn test_swap_front_back_remove() {
+    fn test(back: bool) {
+        // This test checks that every single combination of tail position and length is tested.
+        // Capacity 15 should be large enough to cover every case.
+        let mut tester = VecDeque::with_capacity(15);
+        let usable_cap = tester.capacity();
+        let final_len = usable_cap / 2;
+
+        for len in 0..final_len {
+            let expected: VecDeque<_> = if back {
+                (0..len).collect()
+            } else {
+                (0..len).rev().collect()
+            };
+            for tail_pos in 0..usable_cap {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                if back {
+                    for i in 0..len * 2 {
+                        tester.push_front(i);
+                    }
+                    for i in 0..len {
+                        assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i));
+                    }
+                } else {
+                    for i in 0..len * 2 {
+                        tester.push_back(i);
+                    }
+                    for i in 0..len {
+                        let idx = tester.len() - 1 - i;
+                        assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i));
+                    }
+                }
+                assert!(tester.tail < tester.cap());
+                assert!(tester.head < tester.cap());
+                assert_eq!(tester, expected);
+            }
+        }
+    }
+    test(true);
+    test(false);
+}
+
+#[test]
+fn test_insert() {
+    // This test checks that every single combination of tail position, length, and
+    // insertion position is tested. Capacity 15 should be large enough to cover every case.
+
+    let mut tester = VecDeque::with_capacity(15);
+    // can't guarantee we got 15, so have to get what we got.
+    // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+    // this test isn't covering what it wants to
+    let cap = tester.capacity();
+
+
+    // len is the length *after* insertion
+    for len in 1..cap {
+        // 0, 1, 2, .., len - 1
+        let expected = (0..).take(len).collect::<VecDeque<_>>();
+        for tail_pos in 0..cap {
+            for to_insert in 0..len {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                for i in 0..len {
+                    if i != to_insert {
+                        tester.push_back(i);
+                    }
+                }
+                tester.insert(to_insert, to_insert);
+                assert!(tester.tail < tester.cap());
+                assert!(tester.head < tester.cap());
+                assert_eq!(tester, expected);
+            }
+        }
+    }
+}
+
+#[test]
+fn test_remove() {
+    // This test checks that every single combination of tail position, length, and
+    // removal position is tested. Capacity 15 should be large enough to cover every case.
+
+    let mut tester = VecDeque::with_capacity(15);
+    // can't guarantee we got 15, so have to get what we got.
+    // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+    // this test isn't covering what it wants to
+    let cap = tester.capacity();
+
+    // len is the length *after* removal
+    for len in 0..cap - 1 {
+        // 0, 1, 2, .., len - 1
+        let expected = (0..).take(len).collect::<VecDeque<_>>();
+        for tail_pos in 0..cap {
+            for to_remove in 0..=len {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                for i in 0..len {
+                    if i == to_remove {
+                        tester.push_back(1234);
+                    }
+                    tester.push_back(i);
+                }
+                if to_remove == len {
+                    tester.push_back(1234);
+                }
+                tester.remove(to_remove);
+                assert!(tester.tail < tester.cap());
+                assert!(tester.head < tester.cap());
+                assert_eq!(tester, expected);
+            }
+        }
+    }
+}
+
+#[test]
+fn test_drain() {
+    let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
+
+    let cap = tester.capacity();
+    for len in 0..=cap {
+        for tail in 0..=cap {
+            for drain_start in 0..=len {
+                for drain_end in drain_start..=len {
+                    tester.tail = tail;
+                    tester.head = tail;
+                    for i in 0..len {
+                        tester.push_back(i);
+                    }
+
+                    // Check that we drain the correct values
+                    let drained: VecDeque<_> = tester.drain(drain_start..drain_end).collect();
+                    let drained_expected: VecDeque<_> = (drain_start..drain_end).collect();
+                    assert_eq!(drained, drained_expected);
+
+                    // We shouldn't have changed the capacity or made the
+                    // head or tail out of bounds
+                    assert_eq!(tester.capacity(), cap);
+                    assert!(tester.tail < tester.cap());
+                    assert!(tester.head < tester.cap());
+
+                    // We should see the correct values in the VecDeque
+                    let expected: VecDeque<_> = (0..drain_start)
+                        .chain(drain_end..len)
+                        .collect();
+                    assert_eq!(expected, tester);
+                }
+            }
+        }
+    }
+}
+
+#[test]
+fn test_shrink_to_fit() {
+    // This test checks that every single combination of head and tail position,
+    // is tested. Capacity 15 should be large enough to cover every case.
+
+    let mut tester = VecDeque::with_capacity(15);
+    // can't guarantee we got 15, so have to get what we got.
+    // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+    // this test isn't covering what it wants to
+    let cap = tester.capacity();
+    tester.reserve(63);
+    let max_cap = tester.capacity();
+
+    for len in 0..=cap {
+        // 0, 1, 2, .., len - 1
+        let expected = (0..).take(len).collect::<VecDeque<_>>();
+        for tail_pos in 0..=max_cap {
+            tester.tail = tail_pos;
+            tester.head = tail_pos;
+            tester.reserve(63);
+            for i in 0..len {
+                tester.push_back(i);
+            }
+            tester.shrink_to_fit();
+            assert!(tester.capacity() <= cap);
+            assert!(tester.tail < tester.cap());
+            assert!(tester.head < tester.cap());
+            assert_eq!(tester, expected);
+        }
+    }
+}
+
+#[test]
+fn test_split_off() {
+    // This test checks that every single combination of tail position, length, and
+    // split position is tested. Capacity 15 should be large enough to cover every case.
+
+    let mut tester = VecDeque::with_capacity(15);
+    // can't guarantee we got 15, so have to get what we got.
+    // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+    // this test isn't covering what it wants to
+    let cap = tester.capacity();
+
+    // len is the length *before* splitting
+    for len in 0..cap {
+        // index to split at
+        for at in 0..=len {
+            // 0, 1, 2, .., at - 1 (may be empty)
+            let expected_self = (0..).take(at).collect::<VecDeque<_>>();
+            // at, at + 1, .., len - 1 (may be empty)
+            let expected_other = (at..).take(len - at).collect::<VecDeque<_>>();
+
+            for tail_pos in 0..cap {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                for i in 0..len {
+                    tester.push_back(i);
+                }
+                let result = tester.split_off(at);
+                assert!(tester.tail < tester.cap());
+                assert!(tester.head < tester.cap());
+                assert!(result.tail < result.cap());
+                assert!(result.head < result.cap());
+                assert_eq!(tester, expected_self);
+                assert_eq!(result, expected_other);
+            }
+        }
+    }
+}
+
+#[test]
+fn test_from_vec() {
+    use crate::vec::Vec;
+    for cap in 0..35 {
+        for len in 0..=cap {
+            let mut vec = Vec::with_capacity(cap);
+            vec.extend(0..len);
+
+            let vd = VecDeque::from(vec.clone());
+            assert!(vd.cap().is_power_of_two());
+            assert_eq!(vd.len(), vec.len());
+            assert!(vd.into_iter().eq(vec));
+        }
+    }
+}
+
+#[test]
+fn test_vec_from_vecdeque() {
+    use crate::vec::Vec;
+
+    fn create_vec_and_test_convert(capacity: usize, offset: usize, len: usize) {
+        let mut vd = VecDeque::with_capacity(capacity);
+        for _ in 0..offset {
+            vd.push_back(0);
+            vd.pop_front();
+        }
+        vd.extend(0..len);
+
+        let vec: Vec<_> = Vec::from(vd.clone());
+        assert_eq!(vec.len(), vd.len());
+        assert!(vec.into_iter().eq(vd));
+    }
+
+    #[cfg(not(miri))] // Miri is too slow
+    let max_pwr = 7;
+    #[cfg(miri)]
+    let max_pwr = 5;
+
+    for cap_pwr in 0..max_pwr {
+        // Make capacity as a (2^x)-1, so that the ring size is 2^x
+        let cap = (2i32.pow(cap_pwr) - 1) as usize;
+
+        // In these cases there is enough free space to solve it with copies
+        for len in 0..((cap + 1) / 2) {
+            // Test contiguous cases
+            for offset in 0..(cap - len) {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+
+            // Test cases where block at end of buffer is bigger than block at start
+            for offset in (cap - len)..(cap - (len / 2)) {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+
+            // Test cases where block at start of buffer is bigger than block at end
+            for offset in (cap - (len / 2))..cap {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+        }
+
+        // Now there's not (necessarily) space to straighten the ring with simple copies,
+        // the ring will use swapping when:
+        // (cap + 1 - offset) > (cap + 1 - len) && (len - (cap + 1 - offset)) > (cap + 1 - len))
+        //  right block size  >   free space    &&      left block size       >    free space
+        for len in ((cap + 1) / 2)..cap {
+            // Test contiguous cases
+            for offset in 0..(cap - len) {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+
+            // Test cases where block at end of buffer is bigger than block at start
+            for offset in (cap - len)..(cap - (len / 2)) {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+
+            // Test cases where block at start of buffer is bigger than block at end
+            for offset in (cap - (len / 2))..cap {
+                create_vec_and_test_convert(cap, offset, len)
+            }
+        }
+    }
+}
+
+#[test]
+fn issue_53529() {
+    use crate::boxed::Box;
+
+    let mut dst = VecDeque::new();
+    dst.push_front(Box::new(1));
+    dst.push_front(Box::new(2));
+    assert_eq!(*dst.pop_back().unwrap(), 1);
+
+    let mut src = VecDeque::new();
+    src.push_front(Box::new(2));
+    dst.append(&mut src);
+    for a in dst {
+        assert_eq!(*a, 2);
+    }
+}
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 2edd946ff11..4a48945adc3 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -10,9 +10,9 @@
 //!
 //! ## Boxed values
 //!
-//! The [`Box`](boxed/index.html) type is a smart pointer type. There can
-//! only be one owner of a `Box`, and the owner can decide to mutate the
-//! contents, which live on the heap.
+//! The [`Box`] type is a smart pointer type. There can only be one owner of a
+//! [`Box`], and the owner can decide to mutate the contents, which live on the
+//! heap.
 //!
 //! This type can be sent among threads efficiently as the size of a `Box` value
 //! is the same as that of a pointer. Tree-like data structures are often built
@@ -20,20 +20,20 @@
 //!
 //! ## Reference counted pointers
 //!
-//! The [`Rc`](rc/index.html) type is a non-threadsafe reference-counted pointer
-//! type intended for sharing memory within a thread. An `Rc` pointer wraps a
-//! type, `T`, and only allows access to `&T`, a shared reference.
+//! The [`Rc`] type is a non-threadsafe reference-counted pointer type intended
+//! for sharing memory within a thread. An [`Rc`] pointer wraps a type, `T`, and
+//! only allows access to `&T`, a shared reference.
 //!
-//! This type is useful when inherited mutability (such as using `Box`) is too
-//! constraining for an application, and is often paired with the `Cell` or
-//! `RefCell` types in order to allow mutation.
+//! This type is useful when inherited mutability (such as using [`Box`]) is too
+//! constraining for an application, and is often paired with the [`Cell`] or
+//! [`RefCell`] types in order to allow mutation.
 //!
 //! ## Atomically reference counted pointers
 //!
-//! The [`Arc`](sync/index.html) type is the threadsafe equivalent of the `Rc`
-//! type. It provides all the same functionality of `Rc`, except it requires
-//! that the contained type `T` is shareable. Additionally, `Arc<T>` is itself
-//! sendable while `Rc<T>` is not.
+//! The [`Arc`] type is the threadsafe equivalent of the [`Rc`] type. It
+//! provides all the same functionality of [`Rc`], except it requires that the
+//! contained type `T` is shareable. Additionally, [`Arc<T>`][`Arc`] is itself
+//! sendable while [`Rc<T>`][`Rc`] is not.
 //!
 //! This type allows for shared access to the contained data, and is often
 //! paired with synchronization primitives such as mutexes to allow mutation of
@@ -49,6 +49,12 @@
 //!
 //! The [`alloc`](alloc/index.html) module defines the low-level interface to the
 //! default global allocator. It is not compatible with the libc allocator API.
+//!
+//! [`Arc`]: sync/index.html
+//! [`Box`]: boxed/index.html
+//! [`Cell`]: ../core/cell/index.html
+//! [`Rc`]: rc/index.html
+//! [`RefCell`]: ../core/cell/index.html
 
 #![allow(unused_attributes)]
 #![stable(feature = "alloc", since = "1.36.0")]
@@ -62,9 +68,8 @@
 #![warn(missing_docs)]
 #![warn(missing_debug_implementations)]
 #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings
-
-#![deny(rust_2018_idioms)]
 #![allow(explicit_outlives_requirements)]
+#![allow(incomplete_features)]
 
 #![cfg_attr(not(test), feature(generator_trait))]
 #![cfg_attr(test, feature(test))]
@@ -77,14 +82,18 @@
 #![feature(box_syntax)]
 #![feature(cfg_target_has_atomic)]
 #![feature(coerce_unsized)]
+#![feature(const_generic_impls_guard)]
+#![feature(const_generics)]
+#![feature(const_in_array_repeat_expressions)]
 #![feature(dispatch_from_dyn)]
 #![feature(core_intrinsics)]
-#![feature(custom_attribute)]
+#![feature(container_error_extra)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
 #![feature(fmt_internals)]
 #![feature(fn_traits)]
 #![feature(fundamental)]
+#![feature(internal_uninit_const)]
 #![feature(lang_items)]
 #![feature(libc)]
 #![feature(nll)]
@@ -94,6 +103,7 @@
 #![feature(ptr_offset_from)]
 #![feature(rustc_attrs)]
 #![feature(receiver_trait)]
+#![feature(slice_from_raw_parts)]
 #![feature(specialization)]
 #![feature(staged_api)]
 #![feature(std_internals)]
@@ -109,10 +119,11 @@
 #![feature(rustc_const_unstable)]
 #![feature(const_vec_new)]
 #![feature(slice_partition_dedup)]
-#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)]
+#![feature(maybe_uninit_extra, maybe_uninit_slice)]
 #![feature(alloc_layout_extra)]
 #![feature(try_trait)]
-#![feature(iter_nth_back)]
+#![feature(mem_take)]
+#![feature(associated_type_bounds)]
 
 // Allow testing this library
 
@@ -142,7 +153,7 @@ mod boxed {
     pub use std::boxed::Box;
 }
 #[cfg(test)]
-mod boxed_test;
+mod tests;
 pub mod collections;
 #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
 pub mod sync;
diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs
index dd128e096f9..0b5e186d4c7 100644
--- a/src/liballoc/macros.rs
+++ b/src/liballoc/macros.rs
@@ -42,7 +42,7 @@ macro_rules! vec {
     ($($x:expr),*) => (
         <[_]>::into_vec(box [$($x),*])
     );
-    ($($x:expr,)*) => (vec![$($x),*])
+    ($($x:expr,)*) => ($crate::vec![$($x),*])
 }
 
 // HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
@@ -98,5 +98,5 @@ macro_rules! vec {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! format {
-    ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
+    ($($arg:tt)*) => ($crate::fmt::format(::core::format_args!($($arg)*)))
 }
diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs
index b6b01395ad6..3cb285bf049 100644
--- a/src/liballoc/prelude/v1.rs
+++ b/src/liballoc/prelude/v1.rs
@@ -6,6 +6,5 @@
 
 #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned;
 #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box;
-#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt;
 #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString};
 #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec;
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index d1fc5ac3b30..bc8a38f6b3a 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -7,10 +7,13 @@ use core::ops::Drop;
 use core::ptr::{self, NonNull, Unique};
 use core::slice;
 
-use crate::alloc::{Alloc, Layout, Global, handle_alloc_error};
-use crate::collections::CollectionAllocErr::{self, *};
+use crate::alloc::{Alloc, Layout, Global, AllocErr, handle_alloc_error};
+use crate::collections::TryReserveError::{self, *};
 use crate::boxed::Box;
 
+#[cfg(test)]
+mod tests;
+
 /// A low-level utility for more ergonomically allocating, reallocating, and deallocating
 /// a buffer of memory on the heap without having to worry about all the corner cases
 /// involved. This type is excellent for building your own data structures like Vec and VecDeque.
@@ -34,7 +37,7 @@ use crate::boxed::Box;
 /// that might occur with zero-sized types.
 ///
 /// However this means that you need to be careful when round-tripping this type
-/// with a `Box<[T]>`: `cap()` won't yield the len. However `with_capacity`,
+/// with a `Box<[T]>`: `capacity()` won't yield the len. However `with_capacity`,
 /// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity
 /// field. This allows zero-sized types to not be special-cased by consumers of
 /// this type.
@@ -65,25 +68,25 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// Like `with_capacity` but parameterized over the choice of
     /// allocator for the returned RawVec.
     #[inline]
-    pub fn with_capacity_in(cap: usize, a: A) -> Self {
-        RawVec::allocate_in(cap, false, a)
+    pub fn with_capacity_in(capacity: usize, a: A) -> Self {
+        RawVec::allocate_in(capacity, false, a)
     }
 
     /// Like `with_capacity_zeroed` but parameterized over the choice
     /// of allocator for the returned RawVec.
     #[inline]
-    pub fn with_capacity_zeroed_in(cap: usize, a: A) -> Self {
-        RawVec::allocate_in(cap, true, a)
+    pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self {
+        RawVec::allocate_in(capacity, true, a)
     }
 
-    fn allocate_in(cap: usize, zeroed: bool, mut a: A) -> Self {
+    fn allocate_in(capacity: usize, zeroed: bool, mut a: A) -> Self {
         unsafe {
             let elem_size = mem::size_of::<T>();
 
-            let alloc_size = cap.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow());
+            let alloc_size = capacity.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow());
             alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow());
 
-            // handles ZSTs and `cap = 0` alike
+            // handles ZSTs and `capacity = 0` alike
             let ptr = if alloc_size == 0 {
                 NonNull::<T>::dangling()
             } else {
@@ -102,7 +105,7 @@ impl<T, A: Alloc> RawVec<T, A> {
 
             RawVec {
                 ptr: ptr.into(),
-                cap,
+                cap: capacity,
                 a,
             }
         }
@@ -120,8 +123,8 @@ impl<T> RawVec<T, Global> {
     }
 
     /// Creates a RawVec (on the system heap) with exactly the
-    /// capacity and alignment requirements for a `[T; cap]`. This is
-    /// equivalent to calling RawVec::new when `cap` is 0 or T is
+    /// capacity and alignment requirements for a `[T; capacity]`. This is
+    /// equivalent to calling RawVec::new when `capacity` is 0 or T is
     /// zero-sized. Note that if `T` is zero-sized this means you will
     /// *not* get a RawVec with the requested capacity!
     ///
@@ -135,14 +138,14 @@ impl<T> RawVec<T, Global> {
     ///
     /// Aborts on OOM
     #[inline]
-    pub fn with_capacity(cap: usize) -> Self {
-        RawVec::allocate_in(cap, false, Global)
+    pub fn with_capacity(capacity: usize) -> Self {
+        RawVec::allocate_in(capacity, false, Global)
     }
 
     /// Like `with_capacity` but guarantees the buffer is zeroed.
     #[inline]
-    pub fn with_capacity_zeroed(cap: usize) -> Self {
-        RawVec::allocate_in(cap, true, Global)
+    pub fn with_capacity_zeroed(capacity: usize) -> Self {
+        RawVec::allocate_in(capacity, true, Global)
     }
 }
 
@@ -154,10 +157,10 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// The ptr must be allocated (via the given allocator `a`), and with the given capacity. The
     /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
     /// If the ptr and capacity come from a RawVec created via `a`, then this is guaranteed.
-    pub unsafe fn from_raw_parts_in(ptr: *mut T, cap: usize, a: A) -> Self {
+    pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self {
         RawVec {
             ptr: Unique::new_unchecked(ptr),
-            cap,
+            cap: capacity,
             a,
         }
     }
@@ -171,10 +174,10 @@ impl<T> RawVec<T, Global> {
     /// The ptr must be allocated (on the system heap), and with the given capacity. The
     /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
     /// If the ptr and capacity come from a RawVec, then this is guaranteed.
-    pub unsafe fn from_raw_parts(ptr: *mut T, cap: usize) -> Self {
+    pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self {
         RawVec {
             ptr: Unique::new_unchecked(ptr),
-            cap,
+            cap: capacity,
             a: Global,
         }
     }
@@ -191,7 +194,7 @@ impl<T> RawVec<T, Global> {
 
 impl<T, A: Alloc> RawVec<T, A> {
     /// Gets a raw pointer to the start of the allocation. Note that this is
-    /// Unique::empty() if `cap = 0` or T is zero-sized. In the former case, you must
+    /// Unique::empty() if `capacity = 0` or T is zero-sized. In the former case, you must
     /// be careful.
     pub fn ptr(&self) -> *mut T {
         self.ptr.as_ptr()
@@ -201,7 +204,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     ///
     /// This will always be `usize::MAX` if `T` is zero-sized.
     #[inline(always)]
-    pub fn cap(&self) -> usize {
+    pub fn capacity(&self) -> usize {
         if mem::size_of::<T>() == 0 {
             !0
         } else {
@@ -240,7 +243,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// This function is ideal for when pushing elements one-at-a-time because
     /// you don't need to incur the costs of the more general computations
     /// reserve needs to do to guard against overflow. You do however need to
-    /// manually check if your `len == cap`.
+    /// manually check if your `len == capacity`.
     ///
     /// # Panics
     ///
@@ -267,7 +270,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     ///
     /// impl<T> MyVec<T> {
     ///     pub fn push(&mut self, elem: T) {
-    ///         if self.len == self.buf.cap() { self.buf.double(); }
+    ///         if self.len == self.buf.capacity() { self.buf.double(); }
     ///         // double would have aborted or panicked if the len exceeded
     ///         // `isize::MAX` so this is safe to do unchecked now.
     ///         unsafe {
@@ -381,20 +384,20 @@ impl<T, A: Alloc> RawVec<T, A> {
     }
 
     /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting.
-    pub fn try_reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize)
-           -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize)
+           -> Result<(), TryReserveError> {
 
-        self.reserve_internal(used_cap, needed_extra_cap, Fallible, Exact)
+        self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Exact)
     }
 
     /// Ensures that the buffer contains at least enough space to hold
-    /// `used_cap + needed_extra_cap` elements. If it doesn't already,
+    /// `used_capacity + needed_extra_capacity` elements. If it doesn't already,
     /// will reallocate the minimum possible amount of memory necessary.
     /// Generally this will be exactly the amount of memory necessary,
     /// but in principle the allocator is free to give back more than
     /// we asked for.
     ///
-    /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate
+    /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate
     /// the requested space. This is not really unsafe, but the unsafe
     /// code *you* write that relies on the behavior of this function may break.
     ///
@@ -407,22 +410,23 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// # Aborts
     ///
     /// Aborts on OOM
-    pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) {
-        match self.reserve_internal(used_cap, needed_extra_cap, Infallible, Exact) {
+    pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
+        match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Exact) {
             Err(CapacityOverflow) => capacity_overflow(),
-            Err(AllocErr) => unreachable!(),
+            Err(AllocError { .. }) => unreachable!(),
             Ok(()) => { /* yay */ }
          }
      }
 
-    /// Calculates the buffer's new size given that it'll hold `used_cap +
-    /// needed_extra_cap` elements. This logic is used in amortized reserve methods.
+    /// Calculates the buffer's new size given that it'll hold `used_capacity +
+    /// needed_extra_capacity` elements. This logic is used in amortized reserve methods.
     /// Returns `(new_capacity, new_alloc_size)`.
-    fn amortized_new_size(&self, used_cap: usize, needed_extra_cap: usize)
-        -> Result<usize, CollectionAllocErr> {
+    fn amortized_new_size(&self, used_capacity: usize, needed_extra_capacity: usize)
+        -> Result<usize, TryReserveError> {
 
         // Nothing we can really do about these checks :(
-        let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?;
+        let required_cap = used_capacity.checked_add(needed_extra_capacity)
+            .ok_or(CapacityOverflow)?;
         // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
         let double_cap = self.cap * 2;
         // `double_cap` guarantees exponential growth.
@@ -430,18 +434,18 @@ impl<T, A: Alloc> RawVec<T, A> {
     }
 
     /// The same as `reserve`, but returns on errors instead of panicking or aborting.
-    pub fn try_reserve(&mut self, used_cap: usize, needed_extra_cap: usize)
-        -> Result<(), CollectionAllocErr> {
-        self.reserve_internal(used_cap, needed_extra_cap, Fallible, Amortized)
+    pub fn try_reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize)
+        -> Result<(), TryReserveError> {
+        self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Amortized)
     }
 
     /// Ensures that the buffer contains at least enough space to hold
-    /// `used_cap + needed_extra_cap` elements. If it doesn't already have
+    /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have
     /// enough capacity, will reallocate enough space plus comfortable slack
     /// space to get amortized `O(1)` behavior. Will limit this behavior
     /// if it would needlessly cause itself to panic.
     ///
-    /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate
+    /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate
     /// the requested space. This is not really unsafe, but the unsafe
     /// code *you* write that relies on the behavior of this function may break.
     ///
@@ -487,20 +491,20 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// #   vector.push_all(&[1, 3, 5, 7, 9]);
     /// # }
     /// ```
-    pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
-        match self.reserve_internal(used_cap, needed_extra_cap, Infallible, Amortized) {
+    pub fn reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
+        match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Amortized) {
             Err(CapacityOverflow) => capacity_overflow(),
-            Err(AllocErr) => unreachable!(),
+            Err(AllocError { .. }) => unreachable!(),
             Ok(()) => { /* yay */ }
         }
     }
     /// Attempts to ensure that the buffer contains at least enough space to hold
-    /// `used_cap + needed_extra_cap` elements. If it doesn't already have
+    /// `used_capacity + needed_extra_capacity` elements. If it doesn't already have
     /// enough capacity, will reallocate in place enough space plus comfortable slack
     /// space to get amortized `O(1)` behavior. Will limit this behaviour
     /// if it would needlessly cause itself to panic.
     ///
-    /// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate
+    /// If `used_capacity` exceeds `self.capacity()`, this may fail to actually allocate
     /// the requested space. This is not really unsafe, but the unsafe
     /// code *you* write that relies on the behavior of this function may break.
     ///
@@ -511,7 +515,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// * Panics if the requested capacity exceeds `usize::MAX` bytes.
     /// * Panics on 32-bit platforms if the requested capacity exceeds
     ///   `isize::MAX` bytes.
-    pub fn reserve_in_place(&mut self, used_cap: usize, needed_extra_cap: usize) -> bool {
+    pub fn reserve_in_place(&mut self, used_capacity: usize, needed_extra_capacity: usize) -> bool {
         unsafe {
             // NOTE: we don't early branch on ZSTs here because we want this
             // to actually catch "asking for more than usize::MAX" in that case.
@@ -520,20 +524,20 @@ impl<T, A: Alloc> RawVec<T, A> {
 
             // Don't actually need any more capacity. If the current `cap` is 0, we can't
             // reallocate in place.
-            // Wrapping in case they give a bad `used_cap`
+            // Wrapping in case they give a bad `used_capacity`
             let old_layout = match self.current_layout() {
                 Some(layout) => layout,
                 None => return false,
             };
-            if self.cap().wrapping_sub(used_cap) >= needed_extra_cap {
+            if self.capacity().wrapping_sub(used_capacity) >= needed_extra_capacity {
                 return false;
             }
 
-            let new_cap = self.amortized_new_size(used_cap, needed_extra_cap)
+            let new_cap = self.amortized_new_size(used_capacity, needed_extra_capacity)
                 .unwrap_or_else(|_| capacity_overflow());
 
-            // Here, `cap < used_cap + needed_extra_cap <= new_cap`
-            // (regardless of whether `self.cap - used_cap` wrapped).
+            // Here, `cap < used_capacity + needed_extra_capacity <= new_cap`
+            // (regardless of whether `self.cap - used_capacity` wrapped).
             // Therefore we can safely call grow_in_place.
 
             let new_layout = Layout::new::<T>().repeat(new_cap).unwrap().0;
@@ -632,29 +636,27 @@ use ReserveStrategy::*;
 impl<T, A: Alloc> RawVec<T, A> {
     fn reserve_internal(
         &mut self,
-        used_cap: usize,
-        needed_extra_cap: usize,
+        used_capacity: usize,
+        needed_extra_capacity: usize,
         fallibility: Fallibility,
         strategy: ReserveStrategy,
-    ) -> Result<(), CollectionAllocErr> {
+    ) -> Result<(), TryReserveError> {
         unsafe {
-            use crate::alloc::AllocErr;
-
             // NOTE: we don't early branch on ZSTs here because we want this
             // to actually catch "asking for more than usize::MAX" in that case.
             // If we make it past the first branch then we are guaranteed to
             // panic.
 
             // Don't actually need any more capacity.
-            // Wrapping in case they gave a bad `used_cap`.
-            if self.cap().wrapping_sub(used_cap) >= needed_extra_cap {
+            // Wrapping in case they gave a bad `used_capacity`.
+            if self.capacity().wrapping_sub(used_capacity) >= needed_extra_capacity {
                 return Ok(());
             }
 
             // Nothing we can really do about these checks :(
             let new_cap = match strategy {
-                Exact => used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?,
-                Amortized => self.amortized_new_size(used_cap, needed_extra_cap)?,
+                Exact => used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?,
+                Amortized => self.amortized_new_size(used_capacity, needed_extra_capacity)?,
             };
             let new_layout = Layout::array::<T>(new_cap).map_err(|_| CapacityOverflow)?;
 
@@ -668,12 +670,16 @@ impl<T, A: Alloc> RawVec<T, A> {
                 None => self.a.alloc(new_layout),
             };
 
-            match (&res, fallibility) {
+            let ptr = match (res, fallibility) {
                 (Err(AllocErr), Infallible) => handle_alloc_error(new_layout),
-                _ => {}
-            }
+                (Err(AllocErr), Fallible) => return Err(TryReserveError::AllocError {
+                    layout: new_layout,
+                    non_exhaustive: (),
+                }),
+                (Ok(ptr), _) => ptr,
+            };
 
-            self.ptr = res?.cast().into();
+            self.ptr = ptr.cast().into();
             self.cap = new_cap;
 
             Ok(())
@@ -685,14 +691,16 @@ impl<T, A: Alloc> RawVec<T, A> {
 impl<T> RawVec<T, Global> {
     /// Converts the entire buffer into `Box<[T]>`.
     ///
-    /// While it is not *strictly* Undefined Behavior to call
-    /// this procedure while some of the RawVec is uninitialized,
-    /// it certainly makes it trivial to trigger it.
-    ///
     /// Note that this will correctly reconstitute any `cap` changes
     /// that may have been performed. (see description of type for details)
+    ///
+    /// # Undefined Behavior
+    ///
+    /// All elements of `RawVec<T, Global>` must be initialized. Notice that
+    /// the rules around uninitialized boxed values are not finalized yet,
+    /// but until they are, it is advisable to avoid them.
     pub unsafe fn into_box(self) -> Box<[T]> {
-        // NOTE: not calling `cap()` here, actually using the real `cap` field!
+        // NOTE: not calling `capacity()` here, actually using the real `cap` field!
         let slice = slice::from_raw_parts_mut(self.ptr(), self.cap);
         let output: Box<[T]> = Box::from_raw(slice);
         mem::forget(self);
@@ -731,7 +739,7 @@ unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec<T, A> {
 // all 4GB in user-space. e.g., PAE or x32
 
 #[inline]
-fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> {
+fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
     if mem::size_of::<usize>() < 8 && alloc_size > core::isize::MAX as usize {
         Err(CapacityOverflow)
     } else {
@@ -745,82 +753,3 @@ fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> {
 fn capacity_overflow() -> ! {
     panic!("capacity overflow")
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn allocator_param() {
-        use crate::alloc::AllocErr;
-
-        // Writing a test of integration between third-party
-        // allocators and RawVec is a little tricky because the RawVec
-        // API does not expose fallible allocation methods, so we
-        // cannot check what happens when allocator is exhausted
-        // (beyond detecting a panic).
-        //
-        // Instead, this just checks that the RawVec methods do at
-        // least go through the Allocator API when it reserves
-        // storage.
-
-        // A dumb allocator that consumes a fixed amount of fuel
-        // before allocation attempts start failing.
-        struct BoundedAlloc { fuel: usize }
-        unsafe impl Alloc for BoundedAlloc {
-            unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
-                let size = layout.size();
-                if size > self.fuel {
-                    return Err(AllocErr);
-                }
-                match Global.alloc(layout) {
-                    ok @ Ok(_) => { self.fuel -= size; ok }
-                    err @ Err(_) => err,
-                }
-            }
-            unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
-                Global.dealloc(ptr, layout)
-            }
-        }
-
-        let a = BoundedAlloc { fuel: 500 };
-        let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
-        assert_eq!(v.a.fuel, 450);
-        v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
-        assert_eq!(v.a.fuel, 250);
-    }
-
-    #[test]
-    fn reserve_does_not_overallocate() {
-        {
-            let mut v: RawVec<u32> = RawVec::new();
-            // First `reserve` allocates like `reserve_exact`
-            v.reserve(0, 9);
-            assert_eq!(9, v.cap());
-        }
-
-        {
-            let mut v: RawVec<u32> = RawVec::new();
-            v.reserve(0, 7);
-            assert_eq!(7, v.cap());
-            // 97 if more than double of 7, so `reserve` should work
-            // like `reserve_exact`.
-            v.reserve(7, 90);
-            assert_eq!(97, v.cap());
-        }
-
-        {
-            let mut v: RawVec<u32> = RawVec::new();
-            v.reserve(0, 12);
-            assert_eq!(12, v.cap());
-            v.reserve(12, 3);
-            // 3 is less than half of 12, so `reserve` must grow
-            // exponentially. At the time of writing this test grow
-            // factor is 2, so new capacity is 24, however, grow factor
-            // of 1.5 is OK too. Hence `>= 18` in assert.
-            assert!(v.cap() >= 12 + 12 / 2);
-        }
-    }
-
-
-}
diff --git a/src/liballoc/raw_vec/tests.rs b/src/liballoc/raw_vec/tests.rs
new file mode 100644
index 00000000000..c389898d1ef
--- /dev/null
+++ b/src/liballoc/raw_vec/tests.rs
@@ -0,0 +1,73 @@
+use super::*;
+
+#[test]
+fn allocator_param() {
+    use crate::alloc::AllocErr;
+
+    // Writing a test of integration between third-party
+    // allocators and RawVec is a little tricky because the RawVec
+    // API does not expose fallible allocation methods, so we
+    // cannot check what happens when allocator is exhausted
+    // (beyond detecting a panic).
+    //
+    // Instead, this just checks that the RawVec methods do at
+    // least go through the Allocator API when it reserves
+    // storage.
+
+    // A dumb allocator that consumes a fixed amount of fuel
+    // before allocation attempts start failing.
+    struct BoundedAlloc { fuel: usize }
+    unsafe impl Alloc for BoundedAlloc {
+        unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
+            let size = layout.size();
+            if size > self.fuel {
+                return Err(AllocErr);
+            }
+            match Global.alloc(layout) {
+                ok @ Ok(_) => { self.fuel -= size; ok }
+                err @ Err(_) => err,
+            }
+        }
+        unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
+            Global.dealloc(ptr, layout)
+        }
+    }
+
+    let a = BoundedAlloc { fuel: 500 };
+    let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
+    assert_eq!(v.a.fuel, 450);
+    v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
+    assert_eq!(v.a.fuel, 250);
+}
+
+#[test]
+fn reserve_does_not_overallocate() {
+    {
+        let mut v: RawVec<u32> = RawVec::new();
+        // First `reserve` allocates like `reserve_exact`
+        v.reserve(0, 9);
+        assert_eq!(9, v.capacity());
+    }
+
+    {
+        let mut v: RawVec<u32> = RawVec::new();
+        v.reserve(0, 7);
+        assert_eq!(7, v.capacity());
+        // 97 if more than double of 7, so `reserve` should work
+        // like `reserve_exact`.
+        v.reserve(7, 90);
+        assert_eq!(97, v.capacity());
+    }
+
+    {
+        let mut v: RawVec<u32> = RawVec::new();
+        v.reserve(0, 12);
+        assert_eq!(12, v.capacity());
+        v.reserve(12, 3);
+        // 3 is less than half of 12, so `reserve` must grow
+        // exponentially. At the time of writing this test grow
+        // factor is 2, so new capacity is 24, however, grow factor
+        // of 1.5 is OK too. Hence `>= 18` in assert.
+        assert!(v.capacity() >= 12 + 12 / 2);
+    }
+}
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 0dffb19476f..2b222caf13f 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -232,25 +232,30 @@ use crate::boxed::Box;
 use std::boxed::Box;
 
 use core::any::Any;
+use core::array::LengthAtMost32;
 use core::borrow;
 use core::cell::Cell;
 use core::cmp::Ordering;
 use core::fmt;
 use core::hash::{Hash, Hasher};
 use core::intrinsics::abort;
+use core::iter;
 use core::marker::{self, Unpin, Unsize, PhantomData};
-use core::mem::{self, align_of_val, forget, size_of_val};
+use core::mem::{self, align_of, align_of_val, forget, size_of_val};
 use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn};
 use core::pin::Pin;
 use core::ptr::{self, NonNull};
-use core::slice::from_raw_parts_mut;
-use core::convert::From;
+use core::slice::{self, from_raw_parts_mut};
+use core::convert::{From, TryFrom};
 use core::usize;
 
 use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
 use crate::string::String;
 use crate::vec::Vec;
 
+#[cfg(test)]
+mod tests;
+
 struct RcBox<T: ?Sized> {
     strong: Cell<usize>,
     weak: Cell<usize>,
@@ -286,6 +291,19 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T> {}
 
+impl<T: ?Sized> Rc<T> {
+    fn from_inner(ptr: NonNull<RcBox<T>>) -> Self {
+        Self {
+            ptr,
+            phantom: PhantomData,
+        }
+    }
+
+    unsafe fn from_ptr(ptr: *mut RcBox<T>) -> Self {
+        Self::from_inner(NonNull::new_unchecked(ptr))
+    }
+}
+
 impl<T> Rc<T> {
     /// Constructs a new `Rc<T>`.
     ///
@@ -298,17 +316,45 @@ impl<T> Rc<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(value: T) -> Rc<T> {
-        Rc {
-            // there is an implicit weak pointer owned by all the strong
-            // pointers, which ensures that the weak destructor never frees
-            // the allocation while the strong destructor is running, even
-            // if the weak pointer is stored inside the strong one.
-            ptr: Box::into_raw_non_null(box RcBox {
-                strong: Cell::new(1),
-                weak: Cell::new(1),
-                value,
-            }),
-            phantom: PhantomData,
+        // There is an implicit weak pointer owned by all the strong
+        // pointers, which ensures that the weak destructor never frees
+        // the allocation while the strong destructor is running, even
+        // if the weak pointer is stored inside the strong one.
+        Self::from_inner(Box::into_raw_non_null(box RcBox {
+            strong: Cell::new(1),
+            weak: Cell::new(1),
+            value,
+        }))
+    }
+
+    /// Constructs a new `Rc` with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut five = Rc::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit() -> Rc<mem::MaybeUninit<T>> {
+        unsafe {
+            Rc::from_ptr(Rc::allocate_for_layout(
+                Layout::new::<T>(),
+                |mem| mem as *mut RcBox<mem::MaybeUninit<T>>,
+            ))
         }
     }
 
@@ -362,6 +408,118 @@ impl<T> Rc<T> {
     }
 }
 
+impl<T> Rc<[T]> {
+    /// Constructs a new reference-counted slice with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+    ///     Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+    ///     Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> {
+        unsafe {
+            Rc::from_ptr(Rc::allocate_for_slice(len))
+        }
+    }
+}
+
+impl<T> Rc<mem::MaybeUninit<T>> {
+    /// Converts to `Rc<T>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut five = Rc::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Rc<T> {
+        Rc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
+    }
+}
+
+impl<T> Rc<[mem::MaybeUninit<T>]> {
+    /// Converts to `Rc<[T]>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+    ///     Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+    ///     Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Rc<[T]> {
+        Rc::from_ptr(mem::ManuallyDrop::new(self).ptr.as_ptr() as _)
+    }
+}
+
 impl<T: ?Sized> Rc<T> {
     /// Consumes the `Rc`, returning the wrapped pointer.
     ///
@@ -375,9 +533,9 @@ impl<T: ?Sized> Rc<T> {
     /// ```
     /// use std::rc::Rc;
     ///
-    /// let x = Rc::new(10);
+    /// let x = Rc::new("hello".to_owned());
     /// let x_ptr = Rc::into_raw(x);
-    /// assert_eq!(unsafe { *x_ptr }, 10);
+    /// assert_eq!(unsafe { &*x_ptr }, "hello");
     /// ```
     #[stable(feature = "rc_raw", since = "1.17.0")]
     pub fn into_raw(this: Self) -> *const T {
@@ -401,13 +559,13 @@ impl<T: ?Sized> Rc<T> {
     /// ```
     /// use std::rc::Rc;
     ///
-    /// let x = Rc::new(10);
+    /// let x = Rc::new("hello".to_owned());
     /// let x_ptr = Rc::into_raw(x);
     ///
     /// unsafe {
     ///     // Convert back to an `Rc` to prevent leak.
     ///     let x = Rc::from_raw(x_ptr);
-    ///     assert_eq!(*x, 10);
+    ///     assert_eq!(&*x, "hello");
     ///
     ///     // Further calls to `Rc::from_raw(x_ptr)` would be memory unsafe.
     /// }
@@ -416,20 +574,13 @@ impl<T: ?Sized> Rc<T> {
     /// ```
     #[stable(feature = "rc_raw", since = "1.17.0")]
     pub unsafe fn from_raw(ptr: *const T) -> Self {
-        // Align the unsized value to the end of the RcBox.
-        // Because it is ?Sized, it will always be the last field in memory.
-        let align = align_of_val(&*ptr);
-        let layout = Layout::new::<RcBox<()>>();
-        let offset = (layout.size() + layout.padding_needed_for(align)) as isize;
+        let offset = data_offset(ptr);
 
         // Reverse the offset to find the original RcBox.
         let fake_ptr = ptr as *mut RcBox<T>;
         let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
 
-        Rc {
-            ptr: NonNull::new_unchecked(rc_ptr),
-            phantom: PhantomData,
-        }
+        Self::from_ptr(rc_ptr)
     }
 
     /// Consumes the `Rc`, returning the wrapped pointer as `NonNull<T>`.
@@ -441,10 +592,10 @@ impl<T: ?Sized> Rc<T> {
     ///
     /// use std::rc::Rc;
     ///
-    /// let x = Rc::new(10);
+    /// let x = Rc::new("hello".to_owned());
     /// let ptr = Rc::into_raw_non_null(x);
-    /// let deref = unsafe { *ptr.as_ref() };
-    /// assert_eq!(deref, 10);
+    /// let deref = unsafe { ptr.as_ref() };
+    /// assert_eq!(deref, "hello");
     /// ```
     #[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
     #[inline]
@@ -552,13 +703,46 @@ impl<T: ?Sized> Rc<T> {
     pub fn get_mut(this: &mut Self) -> Option<&mut T> {
         if Rc::is_unique(this) {
             unsafe {
-                Some(&mut this.ptr.as_mut().value)
+                Some(Rc::get_mut_unchecked(this))
             }
         } else {
             None
         }
     }
 
+    /// Returns a mutable reference to the inner value,
+    /// without any check.
+    ///
+    /// See also [`get_mut`], which is safe and does appropriate checks.
+    ///
+    /// [`get_mut`]: struct.Rc.html#method.get_mut
+    ///
+    /// # Safety
+    ///
+    /// Any other `Rc` or [`Weak`] pointers to the same value must not be dereferenced
+    /// for the duration of the returned borrow.
+    /// This is trivially the case if no such pointers exist,
+    /// for example immediately after `Rc::new`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut x = Rc::new(String::new());
+    /// unsafe {
+    ///     Rc::get_mut_unchecked(&mut x).push_str("foo")
+    /// }
+    /// assert_eq!(*x, "foo");
+    /// ```
+    #[inline]
+    #[unstable(feature = "get_mut_unchecked", issue = "63292")]
+    pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
+        &mut this.ptr.as_mut().value
+    }
+
     #[inline]
     #[stable(feature = "ptr_eq", since = "1.17.0")]
     /// Returns `true` if the two `Rc`s point to the same value (not
@@ -584,15 +768,18 @@ impl<T: ?Sized> Rc<T> {
 impl<T: Clone> Rc<T> {
     /// Makes a mutable reference into the given `Rc`.
     ///
-    /// If there are other `Rc` or [`Weak`][weak] pointers to the same value,
-    /// then `make_mut` will invoke [`clone`][clone] on the inner value to
-    /// ensure unique ownership. This is also referred to as clone-on-write.
+    /// If there are other `Rc` pointers to the same value, then `make_mut` will
+    /// [`clone`] the inner value to ensure unique ownership.  This is also
+    /// referred to as clone-on-write.
     ///
-    /// See also [`get_mut`][get_mut], which will fail rather than cloning.
+    /// If there are no other `Rc` pointers to this value, then [`Weak`]
+    /// pointers to this value will be dissassociated.
     ///
-    /// [weak]: struct.Weak.html
-    /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone
-    /// [get_mut]: struct.Rc.html#method.get_mut
+    /// See also [`get_mut`], which will fail rather than cloning.
+    ///
+    /// [`Weak`]: struct.Weak.html
+    /// [`clone`]: ../../std/clone/trait.Clone.html#tymethod.clone
+    /// [`get_mut`]: struct.Rc.html#method.get_mut
     ///
     /// # Examples
     ///
@@ -611,6 +798,23 @@ impl<T: Clone> Rc<T> {
     /// assert_eq!(*data, 8);
     /// assert_eq!(*other_data, 12);
     /// ```
+    ///
+    /// [`Weak`] pointers will be dissassociated:
+    ///
+    /// ```
+    /// use std::rc::Rc;
+    ///
+    /// let mut data = Rc::new(75);
+    /// let weak = Rc::downgrade(&data);
+    ///
+    /// assert!(75 == *data);
+    /// assert!(75 == *weak.upgrade().unwrap());
+    ///
+    /// *Rc::make_mut(&mut data) += 1;
+    ///
+    /// assert!(76 == *data);
+    /// assert!(weak.upgrade().is_none());
+    /// ```
     #[inline]
     #[stable(feature = "rc_unique", since = "1.4.0")]
     pub fn make_mut(this: &mut Self) -> &mut T {
@@ -667,7 +871,7 @@ impl Rc<dyn Any> {
         if (*self).is::<T>() {
             let ptr = self.ptr.cast::<RcBox<T>>();
             forget(self);
-            Ok(Rc { ptr, phantom: PhantomData })
+            Ok(Rc::from_inner(ptr))
         } else {
             Err(self)
         }
@@ -675,21 +879,29 @@ impl Rc<dyn Any> {
 }
 
 impl<T: ?Sized> Rc<T> {
-    // Allocates an `RcBox<T>` with sufficient space for an unsized value
-    unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
-        // Calculate layout using the given value.
+    /// Allocates an `RcBox<T>` with sufficient space for
+    /// a possibly-unsized value where the value has the layout provided.
+    ///
+    /// The function `mem_to_rcbox` is called with the data pointer
+    /// and must return back a (potentially fat)-pointer for the `RcBox<T>`.
+    unsafe fn allocate_for_layout(
+        value_layout: Layout,
+        mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox<T>
+    ) -> *mut RcBox<T> {
+        // Calculate layout using the given value layout.
         // Previously, layout was calculated on the expression
         // `&*(ptr as *const RcBox<T>)`, but this created a misaligned
         // reference (see #54908).
         let layout = Layout::new::<RcBox<()>>()
-            .extend(Layout::for_value(&*ptr)).unwrap().0
+            .extend(value_layout).unwrap().0
             .pad_to_align().unwrap();
 
+        // Allocate for the layout.
         let mem = Global.alloc(layout)
             .unwrap_or_else(|_| handle_alloc_error(layout));
 
         // Initialize the RcBox
-        let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut RcBox<T>;
+        let inner = mem_to_rcbox(mem.as_ptr());
         debug_assert_eq!(Layout::for_value(&*inner), layout);
 
         ptr::write(&mut (*inner).strong, Cell::new(1));
@@ -698,6 +910,15 @@ impl<T: ?Sized> Rc<T> {
         inner
     }
 
+    /// Allocates an `RcBox<T>` with sufficient space for an unsized value
+    unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
+        // Allocate for the `RcBox<T>` using the given value.
+        Self::allocate_for_layout(
+            Layout::for_value(&*ptr),
+            |mem| set_data_ptr(ptr as *mut T, mem) as *mut RcBox<T>,
+        )
+    }
+
     fn from_box(v: Box<T>) -> Rc<T> {
         unsafe {
             let box_unique = Box::into_unique(v);
@@ -715,44 +936,49 @@ impl<T: ?Sized> Rc<T> {
             // Free the allocation without dropping its contents
             box_free(box_unique);
 
-            Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
+            Self::from_ptr(ptr)
         }
     }
 }
 
-// Sets the data pointer of a `?Sized` raw pointer.
-//
-// For a slice/trait object, this sets the `data` field and leaves the rest
-// unchanged. For a sized raw pointer, this simply sets the pointer.
+impl<T> Rc<[T]> {
+    /// Allocates an `RcBox<[T]>` with the given length.
+    unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> {
+        Self::allocate_for_layout(
+            Layout::array::<T>(len).unwrap(),
+            |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>,
+        )
+    }
+}
+
+/// Sets the data pointer of a `?Sized` raw pointer.
+///
+/// For a slice/trait object, this sets the `data` field and leaves the rest
+/// unchanged. For a sized raw pointer, this simply sets the pointer.
 unsafe fn set_data_ptr<T: ?Sized, U>(mut ptr: *mut T, data: *mut U) -> *mut T {
     ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8);
     ptr
 }
 
 impl<T> Rc<[T]> {
-    // Copy elements from slice into newly allocated Rc<[T]>
-    //
-    // Unsafe because the caller must either take ownership or bind `T: Copy`
+    /// Copy elements from slice into newly allocated Rc<[T]>
+    ///
+    /// Unsafe because the caller must either take ownership or bind `T: Copy`
     unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> {
-        let v_ptr = v as *const [T];
-        let ptr = Self::allocate_for_ptr(v_ptr);
+        let ptr = Self::allocate_for_slice(v.len());
 
         ptr::copy_nonoverlapping(
             v.as_ptr(),
             &mut (*ptr).value as *mut [T] as *mut T,
             v.len());
 
-        Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
+        Self::from_ptr(ptr)
     }
-}
-
-trait RcFromSlice<T> {
-    fn from_slice(slice: &[T]) -> Self;
-}
 
-impl<T: Clone> RcFromSlice<T> for Rc<[T]> {
-    #[inline]
-    default fn from_slice(v: &[T]) -> Self {
+    /// Constructs an `Rc<[T]>` from an iterator known to be of a certain size.
+    ///
+    /// Behavior is undefined should the size be wrong.
+    unsafe fn from_iter_exact(iter: impl iter::Iterator<Item = T>, len: usize) -> Rc<[T]> {
         // Panic guard while cloning T elements.
         // In the event of a panic, elements that have been written
         // into the new RcBox will be dropped, then the memory freed.
@@ -769,37 +995,48 @@ impl<T: Clone> RcFromSlice<T> for Rc<[T]> {
                     let slice = from_raw_parts_mut(self.elems, self.n_elems);
                     ptr::drop_in_place(slice);
 
-                    Global.dealloc(self.mem, self.layout.clone());
+                    Global.dealloc(self.mem, self.layout);
                 }
             }
         }
 
-        unsafe {
-            let v_ptr = v as *const [T];
-            let ptr = Self::allocate_for_ptr(v_ptr);
+        let ptr = Self::allocate_for_slice(len);
 
-            let mem = ptr as *mut _ as *mut u8;
-            let layout = Layout::for_value(&*ptr);
+        let mem = ptr as *mut _ as *mut u8;
+        let layout = Layout::for_value(&*ptr);
 
-            // Pointer to first element
-            let elems = &mut (*ptr).value as *mut [T] as *mut T;
+        // Pointer to first element
+        let elems = &mut (*ptr).value as *mut [T] as *mut T;
 
-            let mut guard = Guard{
-                mem: NonNull::new_unchecked(mem),
-                elems: elems,
-                layout: layout,
-                n_elems: 0,
-            };
+        let mut guard = Guard {
+            mem: NonNull::new_unchecked(mem),
+            elems,
+            layout,
+            n_elems: 0,
+        };
 
-            for (i, item) in v.iter().enumerate() {
-                ptr::write(elems.add(i), item.clone());
-                guard.n_elems += 1;
-            }
+        for (i, item) in iter.enumerate() {
+            ptr::write(elems.add(i), item);
+            guard.n_elems += 1;
+        }
 
-            // All clear. Forget the guard so it doesn't free the new RcBox.
-            forget(guard);
+        // All clear. Forget the guard so it doesn't free the new RcBox.
+        forget(guard);
+
+        Self::from_ptr(ptr)
+    }
+}
 
-            Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
+/// Specialization trait used for `From<&[T]>`.
+trait RcFromSlice<T> {
+    fn from_slice(slice: &[T]) -> Self;
+}
+
+impl<T: Clone> RcFromSlice<T> for Rc<[T]> {
+    #[inline]
+    default fn from_slice(v: &[T]) -> Self {
+        unsafe {
+            Self::from_iter_exact(v.iter().cloned(), v.len())
         }
     }
 }
@@ -891,7 +1128,7 @@ impl<T: ?Sized> Clone for Rc<T> {
     #[inline]
     fn clone(&self) -> Rc<T> {
         self.inc_strong();
-        Rc { ptr: self.ptr, phantom: PhantomData }
+        Self::from_inner(self.ptr)
     }
 }
 
@@ -1197,6 +1434,114 @@ impl<T> From<Vec<T>> for Rc<[T]> {
     }
 }
 
+#[unstable(feature = "boxed_slice_try_from", issue = "0")]
+impl<T, const N: usize> TryFrom<Rc<[T]>> for Rc<[T; N]>
+where
+    [T; N]: LengthAtMost32,
+{
+    type Error = Rc<[T]>;
+
+    fn try_from(boxed_slice: Rc<[T]>) -> Result<Self, Self::Error> {
+        if boxed_slice.len() == N {
+            Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) })
+        } else {
+            Err(boxed_slice)
+        }
+    }
+}
+
+#[stable(feature = "shared_from_iter", since = "1.37.0")]
+impl<T> iter::FromIterator<T> for Rc<[T]> {
+    /// Takes each element in the `Iterator` and collects it into an `Rc<[T]>`.
+    ///
+    /// # Performance characteristics
+    ///
+    /// ## The general case
+    ///
+    /// In the general case, collecting into `Rc<[T]>` is done by first
+    /// collecting into a `Vec<T>`. That is, when writing the following:
+    ///
+    /// ```rust
+    /// # use std::rc::Rc;
+    /// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();
+    /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
+    /// ```
+    ///
+    /// this behaves as if we wrote:
+    ///
+    /// ```rust
+    /// # use std::rc::Rc;
+    /// let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0)
+    ///     .collect::<Vec<_>>() // The first set of allocations happens here.
+    ///     .into(); // A second allocation for `Rc<[T]>` happens here.
+    /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
+    /// ```
+    ///
+    /// This will allocate as many times as needed for constructing the `Vec<T>`
+    /// and then it will allocate once for turning the `Vec<T>` into the `Rc<[T]>`.
+    ///
+    /// ## Iterators of known length
+    ///
+    /// When your `Iterator` implements `TrustedLen` and is of an exact size,
+    /// a single allocation will be made for the `Rc<[T]>`. For example:
+    ///
+    /// ```rust
+    /// # use std::rc::Rc;
+    /// let evens: Rc<[u8]> = (0..10).collect(); // Just a single allocation happens here.
+    /// # assert_eq!(&*evens, &*(0..10).collect::<Vec<_>>());
+    /// ```
+    fn from_iter<I: iter::IntoIterator<Item = T>>(iter: I) -> Self {
+        RcFromIter::from_iter(iter.into_iter())
+    }
+}
+
+/// Specialization trait used for collecting into `Rc<[T]>`.
+trait RcFromIter<T, I> {
+    fn from_iter(iter: I) -> Self;
+}
+
+impl<T, I: Iterator<Item = T>> RcFromIter<T, I> for Rc<[T]> {
+    default fn from_iter(iter: I) -> Self {
+        iter.collect::<Vec<T>>().into()
+    }
+}
+
+impl<T, I: iter::TrustedLen<Item = T>> RcFromIter<T, I> for Rc<[T]>  {
+    default fn from_iter(iter: I) -> Self {
+        // This is the case for a `TrustedLen` iterator.
+        let (low, high) = iter.size_hint();
+        if let Some(high) = high {
+            debug_assert_eq!(
+                low, high,
+                "TrustedLen iterator's size hint is not exact: {:?}",
+                (low, high)
+            );
+
+            unsafe {
+                // SAFETY: We need to ensure that the iterator has an exact length and we have.
+                Rc::from_iter_exact(iter, low)
+            }
+        } else {
+            // Fall back to normal implementation.
+            iter.collect::<Vec<T>>().into()
+        }
+    }
+}
+
+impl<'a, T: 'a + Clone> RcFromIter<&'a T, slice::Iter<'a, T>> for Rc<[T]> {
+    fn from_iter(iter: slice::Iter<'a, T>) -> Self {
+        // Delegate to `impl<T: Clone> From<&[T]> for Rc<[T]>`.
+        //
+        // In the case that `T: Copy`, we get to use `ptr::copy_nonoverlapping`
+        // which is even more performant.
+        //
+        // In the fall-back case we have `T: Clone`. This is still better
+        // than the `TrustedLen` implementation as slices have a known length
+        // and so we get to avoid calling `size_hint` and avoid the branching.
+        iter.as_slice().into()
+    }
+}
+
 /// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
 /// managed value. The value is accessed by calling [`upgrade`] on the `Weak`
 /// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.
@@ -1262,6 +1607,143 @@ impl<T> Weak<T> {
             ptr: NonNull::new(usize::MAX as *mut RcBox<T>).expect("MAX is not 0"),
         }
     }
+
+    /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
+    ///
+    /// It is up to the caller to ensure that the object is still alive when accessing it through
+    /// the pointer.
+    ///
+    /// The pointer may be [`null`] or be dangling in case the object has already been destroyed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(weak_into_raw)]
+    ///
+    /// use std::rc::Rc;
+    /// use std::ptr;
+    ///
+    /// let strong = Rc::new("hello".to_owned());
+    /// let weak = Rc::downgrade(&strong);
+    /// // Both point to the same object
+    /// assert!(ptr::eq(&*strong, weak.as_raw()));
+    /// // The strong here keeps it alive, so we can still access the object.
+    /// assert_eq!("hello", unsafe { &*weak.as_raw() });
+    ///
+    /// drop(strong);
+    /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to
+    /// // undefined behaviour.
+    /// // assert_eq!("hello", unsafe { &*weak.as_raw() });
+    /// ```
+    ///
+    /// [`null`]: ../../std/ptr/fn.null.html
+    #[unstable(feature = "weak_into_raw", issue = "60728")]
+    pub fn as_raw(&self) -> *const T {
+        match self.inner() {
+            None => ptr::null(),
+            Some(inner) => {
+                let offset = data_offset_sized::<T>();
+                let ptr = inner as *const RcBox<T>;
+                // Note: while the pointer we create may already point to dropped value, the
+                // allocation still lives (it must hold the weak point as long as we are alive).
+                // Therefore, the offset is OK to do, it won't get out of the allocation.
+                let ptr = unsafe { (ptr as *const u8).offset(offset) };
+                ptr as *const T
+            }
+        }
+    }
+
+    /// Consumes the `Weak<T>` and turns it into a raw pointer.
+    ///
+    /// This converts the weak pointer into a raw pointer, preserving the original weak count. It
+    /// can be turned back into the `Weak<T>` with [`from_raw`].
+    ///
+    /// The same restrictions of accessing the target of the pointer as with
+    /// [`as_raw`] apply.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(weak_into_raw)]
+    ///
+    /// use std::rc::{Rc, Weak};
+    ///
+    /// let strong = Rc::new("hello".to_owned());
+    /// let weak = Rc::downgrade(&strong);
+    /// let raw = weak.into_raw();
+    ///
+    /// assert_eq!(1, Rc::weak_count(&strong));
+    /// assert_eq!("hello", unsafe { &*raw });
+    ///
+    /// drop(unsafe { Weak::from_raw(raw) });
+    /// assert_eq!(0, Rc::weak_count(&strong));
+    /// ```
+    ///
+    /// [`from_raw`]: struct.Weak.html#method.from_raw
+    /// [`as_raw`]: struct.Weak.html#method.as_raw
+    #[unstable(feature = "weak_into_raw", issue = "60728")]
+    pub fn into_raw(self) -> *const T {
+        let result = self.as_raw();
+        mem::forget(self);
+        result
+    }
+
+    /// Converts a raw pointer previously created by [`into_raw`] back into `Weak<T>`.
+    ///
+    /// This can be used to safely get a strong reference (by calling [`upgrade`]
+    /// later) or to deallocate the weak count by dropping the `Weak<T>`.
+    ///
+    /// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is
+    /// returned.
+    ///
+    /// # Safety
+    ///
+    /// The pointer must represent one valid weak count. In other words, it must point to `T` which
+    /// is or *was* managed by an [`Rc`] and the weak count of that [`Rc`] must not have reached
+    /// 0. It is allowed for the strong count to be 0.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(weak_into_raw)]
+    ///
+    /// use std::rc::{Rc, Weak};
+    ///
+    /// let strong = Rc::new("hello".to_owned());
+    ///
+    /// let raw_1 = Rc::downgrade(&strong).into_raw();
+    /// let raw_2 = Rc::downgrade(&strong).into_raw();
+    ///
+    /// assert_eq!(2, Rc::weak_count(&strong));
+    ///
+    /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap());
+    /// assert_eq!(1, Rc::weak_count(&strong));
+    ///
+    /// drop(strong);
+    ///
+    /// // Decrement the last weak count.
+    /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
+    /// ```
+    ///
+    /// [`null`]: ../../std/ptr/fn.null.html
+    /// [`into_raw`]: struct.Weak.html#method.into_raw
+    /// [`upgrade`]: struct.Weak.html#method.upgrade
+    /// [`Rc`]: struct.Rc.html
+    /// [`Weak`]: struct.Weak.html
+    #[unstable(feature = "weak_into_raw", issue = "60728")]
+    pub unsafe fn from_raw(ptr: *const T) -> Self {
+        if ptr.is_null() {
+            Self::new()
+        } else {
+            // See Rc::from_raw for details
+            let offset = data_offset(ptr);
+            let fake_ptr = ptr as *mut RcBox<T>;
+            let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
+            Weak {
+                ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw"),
+            }
+        }
+    }
 }
 
 pub(crate) fn is_dangling<T: ?Sized>(ptr: NonNull<T>) -> bool {
@@ -1303,7 +1785,7 @@ impl<T: ?Sized> Weak<T> {
             None
         } else {
             inner.inc_strong();
-            Some(Rc { ptr: self.ptr, phantom: PhantomData })
+            Some(Rc::from_inner(self.ptr))
         }
     }
 
@@ -1362,18 +1844,18 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// ```
     /// #![feature(weak_ptr_eq)]
-    /// use std::rc::{Rc, Weak};
+    /// use std::rc::Rc;
     ///
     /// let first_rc = Rc::new(5);
     /// let first = Rc::downgrade(&first_rc);
     /// let second = Rc::downgrade(&first_rc);
     ///
-    /// assert!(Weak::ptr_eq(&first, &second));
+    /// assert!(first.ptr_eq(&second));
     ///
     /// let third_rc = Rc::new(5);
     /// let third = Rc::downgrade(&third_rc);
     ///
-    /// assert!(!Weak::ptr_eq(&first, &third));
+    /// assert!(!first.ptr_eq(&third));
     /// ```
     ///
     /// Comparing `Weak::new`.
@@ -1384,16 +1866,16 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// let first = Weak::new();
     /// let second = Weak::new();
-    /// assert!(Weak::ptr_eq(&first, &second));
+    /// assert!(first.ptr_eq(&second));
     ///
     /// let third_rc = Rc::new(());
     /// let third = Rc::downgrade(&third_rc);
-    /// assert!(!Weak::ptr_eq(&first, &third));
+    /// assert!(!first.ptr_eq(&third));
     /// ```
     #[inline]
     #[unstable(feature = "weak_ptr_eq", issue = "55981")]
-    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
-        this.ptr.as_ptr() == other.ptr.as_ptr()
+    pub fn ptr_eq(&self, other: &Self) -> bool {
+        self.ptr.as_ptr() == other.ptr.as_ptr()
     }
 }
 
@@ -1507,14 +1989,16 @@ trait RcBoxPtr<T: ?Sized> {
 
     #[inline]
     fn inc_strong(&self) {
+        let strong = self.strong();
+
         // We want to abort on overflow instead of dropping the value.
         // The reference count will never be zero when this is called;
         // nevertheless, we insert an abort here to hint LLVM at
         // an otherwise missed optimization.
-        if self.strong() == 0 || self.strong() == usize::max_value() {
+        if strong == 0 || strong == usize::max_value() {
             unsafe { abort(); }
         }
-        self.inner().strong.set(self.strong() + 1);
+        self.inner().strong.set(strong + 1);
     }
 
     #[inline]
@@ -1529,14 +2013,16 @@ trait RcBoxPtr<T: ?Sized> {
 
     #[inline]
     fn inc_weak(&self) {
+        let weak = self.weak();
+
         // We want to abort on overflow instead of dropping the value.
         // The reference count will never be zero when this is called;
         // nevertheless, we insert an abort here to hint LLVM at
         // an otherwise missed optimization.
-        if self.weak() == 0 || self.weak() == usize::max_value() {
+        if weak == 0 || weak == usize::max_value() {
             unsafe { abort(); }
         }
-        self.inner().weak.set(self.weak() + 1);
+        self.inner().weak.set(weak + 1);
     }
 
     #[inline]
@@ -1561,436 +2047,6 @@ impl<T: ?Sized> RcBoxPtr<T> for RcBox<T> {
     }
 }
 
-#[cfg(test)]
-mod tests {
-    use super::{Rc, Weak};
-    use std::boxed::Box;
-    use std::cell::RefCell;
-    use std::option::Option::{self, None, Some};
-    use std::result::Result::{Err, Ok};
-    use std::mem::drop;
-    use std::clone::Clone;
-    use std::convert::From;
-
-    #[test]
-    fn test_clone() {
-        let x = Rc::new(RefCell::new(5));
-        let y = x.clone();
-        *x.borrow_mut() = 20;
-        assert_eq!(*y.borrow(), 20);
-    }
-
-    #[test]
-    fn test_simple() {
-        let x = Rc::new(5);
-        assert_eq!(*x, 5);
-    }
-
-    #[test]
-    fn test_simple_clone() {
-        let x = Rc::new(5);
-        let y = x.clone();
-        assert_eq!(*x, 5);
-        assert_eq!(*y, 5);
-    }
-
-    #[test]
-    fn test_destructor() {
-        let x: Rc<Box<_>> = Rc::new(box 5);
-        assert_eq!(**x, 5);
-    }
-
-    #[test]
-    fn test_live() {
-        let x = Rc::new(5);
-        let y = Rc::downgrade(&x);
-        assert!(y.upgrade().is_some());
-    }
-
-    #[test]
-    fn test_dead() {
-        let x = Rc::new(5);
-        let y = Rc::downgrade(&x);
-        drop(x);
-        assert!(y.upgrade().is_none());
-    }
-
-    #[test]
-    fn weak_self_cyclic() {
-        struct Cycle {
-            x: RefCell<Option<Weak<Cycle>>>,
-        }
-
-        let a = Rc::new(Cycle { x: RefCell::new(None) });
-        let b = Rc::downgrade(&a.clone());
-        *a.x.borrow_mut() = Some(b);
-
-        // hopefully we don't double-free (or leak)...
-    }
-
-    #[test]
-    fn is_unique() {
-        let x = Rc::new(3);
-        assert!(Rc::is_unique(&x));
-        let y = x.clone();
-        assert!(!Rc::is_unique(&x));
-        drop(y);
-        assert!(Rc::is_unique(&x));
-        let w = Rc::downgrade(&x);
-        assert!(!Rc::is_unique(&x));
-        drop(w);
-        assert!(Rc::is_unique(&x));
-    }
-
-    #[test]
-    fn test_strong_count() {
-        let a = Rc::new(0);
-        assert!(Rc::strong_count(&a) == 1);
-        let w = Rc::downgrade(&a);
-        assert!(Rc::strong_count(&a) == 1);
-        let b = w.upgrade().expect("upgrade of live rc failed");
-        assert!(Rc::strong_count(&b) == 2);
-        assert!(Rc::strong_count(&a) == 2);
-        drop(w);
-        drop(a);
-        assert!(Rc::strong_count(&b) == 1);
-        let c = b.clone();
-        assert!(Rc::strong_count(&b) == 2);
-        assert!(Rc::strong_count(&c) == 2);
-    }
-
-    #[test]
-    fn test_weak_count() {
-        let a = Rc::new(0);
-        assert!(Rc::strong_count(&a) == 1);
-        assert!(Rc::weak_count(&a) == 0);
-        let w = Rc::downgrade(&a);
-        assert!(Rc::strong_count(&a) == 1);
-        assert!(Rc::weak_count(&a) == 1);
-        drop(w);
-        assert!(Rc::strong_count(&a) == 1);
-        assert!(Rc::weak_count(&a) == 0);
-        let c = a.clone();
-        assert!(Rc::strong_count(&a) == 2);
-        assert!(Rc::weak_count(&a) == 0);
-        drop(c);
-    }
-
-    #[test]
-    fn weak_counts() {
-        assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
-        assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
-
-        let a = Rc::new(0);
-        let w = Rc::downgrade(&a);
-        assert_eq!(Weak::strong_count(&w), 1);
-        assert_eq!(Weak::weak_count(&w), Some(1));
-        let w2 = w.clone();
-        assert_eq!(Weak::strong_count(&w), 1);
-        assert_eq!(Weak::weak_count(&w), Some(2));
-        assert_eq!(Weak::strong_count(&w2), 1);
-        assert_eq!(Weak::weak_count(&w2), Some(2));
-        drop(w);
-        assert_eq!(Weak::strong_count(&w2), 1);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        let a2 = a.clone();
-        assert_eq!(Weak::strong_count(&w2), 2);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        drop(a2);
-        drop(a);
-        assert_eq!(Weak::strong_count(&w2), 0);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        drop(w2);
-    }
-
-    #[test]
-    fn try_unwrap() {
-        let x = Rc::new(3);
-        assert_eq!(Rc::try_unwrap(x), Ok(3));
-        let x = Rc::new(4);
-        let _y = x.clone();
-        assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4)));
-        let x = Rc::new(5);
-        let _w = Rc::downgrade(&x);
-        assert_eq!(Rc::try_unwrap(x), Ok(5));
-    }
-
-    #[test]
-    fn into_from_raw() {
-        let x = Rc::new(box "hello");
-        let y = x.clone();
-
-        let x_ptr = Rc::into_raw(x);
-        drop(y);
-        unsafe {
-            assert_eq!(**x_ptr, "hello");
-
-            let x = Rc::from_raw(x_ptr);
-            assert_eq!(**x, "hello");
-
-            assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello"));
-        }
-    }
-
-    #[test]
-    fn test_into_from_raw_unsized() {
-        use std::fmt::Display;
-        use std::string::ToString;
-
-        let rc: Rc<str> = Rc::from("foo");
-
-        let ptr = Rc::into_raw(rc.clone());
-        let rc2 = unsafe { Rc::from_raw(ptr) };
-
-        assert_eq!(unsafe { &*ptr }, "foo");
-        assert_eq!(rc, rc2);
-
-        let rc: Rc<dyn Display> = Rc::new(123);
-
-        let ptr = Rc::into_raw(rc.clone());
-        let rc2 = unsafe { Rc::from_raw(ptr) };
-
-        assert_eq!(unsafe { &*ptr }.to_string(), "123");
-        assert_eq!(rc2.to_string(), "123");
-    }
-
-    #[test]
-    fn get_mut() {
-        let mut x = Rc::new(3);
-        *Rc::get_mut(&mut x).unwrap() = 4;
-        assert_eq!(*x, 4);
-        let y = x.clone();
-        assert!(Rc::get_mut(&mut x).is_none());
-        drop(y);
-        assert!(Rc::get_mut(&mut x).is_some());
-        let _w = Rc::downgrade(&x);
-        assert!(Rc::get_mut(&mut x).is_none());
-    }
-
-    #[test]
-    fn test_cowrc_clone_make_unique() {
-        let mut cow0 = Rc::new(75);
-        let mut cow1 = cow0.clone();
-        let mut cow2 = cow1.clone();
-
-        assert!(75 == *Rc::make_mut(&mut cow0));
-        assert!(75 == *Rc::make_mut(&mut cow1));
-        assert!(75 == *Rc::make_mut(&mut cow2));
-
-        *Rc::make_mut(&mut cow0) += 1;
-        *Rc::make_mut(&mut cow1) += 2;
-        *Rc::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_cowrc_clone_unique2() {
-        let mut cow0 = Rc::new(75);
-        let cow1 = cow0.clone();
-        let cow2 = cow1.clone();
-
-        assert!(75 == *cow0);
-        assert!(75 == *cow1);
-        assert!(75 == *cow2);
-
-        *Rc::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_cowrc_clone_weak() {
-        let mut cow0 = Rc::new(75);
-        let cow1_weak = Rc::downgrade(&cow0);
-
-        assert!(75 == *cow0);
-        assert!(75 == *cow1_weak.upgrade().unwrap());
-
-        *Rc::make_mut(&mut cow0) += 1;
-
-        assert!(76 == *cow0);
-        assert!(cow1_weak.upgrade().is_none());
-    }
-
-    #[test]
-    fn test_show() {
-        let foo = Rc::new(75);
-        assert_eq!(format!("{:?}", foo), "75");
-    }
-
-    #[test]
-    fn test_unsized() {
-        let foo: Rc<[i32]> = Rc::new([1, 2, 3]);
-        assert_eq!(foo, foo.clone());
-    }
-
-    #[test]
-    fn test_from_owned() {
-        let foo = 123;
-        let foo_rc = Rc::from(foo);
-        assert!(123 == *foo_rc);
-    }
-
-    #[test]
-    fn test_new_weak() {
-        let foo: Weak<usize> = Weak::new();
-        assert!(foo.upgrade().is_none());
-    }
-
-    #[test]
-    fn test_ptr_eq() {
-        let five = Rc::new(5);
-        let same_five = five.clone();
-        let other_five = Rc::new(5);
-
-        assert!(Rc::ptr_eq(&five, &same_five));
-        assert!(!Rc::ptr_eq(&five, &other_five));
-    }
-
-    #[test]
-    fn test_from_str() {
-        let r: Rc<str> = Rc::from("foo");
-
-        assert_eq!(&r[..], "foo");
-    }
-
-    #[test]
-    fn test_copy_from_slice() {
-        let s: &[u32] = &[1, 2, 3];
-        let r: Rc<[u32]> = Rc::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: Rc<[X]> = Rc::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: Rc<[Fail]> = Rc::from(s);
-    }
-
-    #[test]
-    fn test_from_box() {
-        let b: Box<u32> = box 123;
-        let r: Rc<u32> = Rc::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: Rc<str> = Rc::from(s);
-
-        assert_eq!(&r[..], "foo");
-    }
-
-    #[test]
-    fn test_from_box_slice() {
-        let s = vec![1, 2, 3].into_boxed_slice();
-        let r: Rc<[u32]> = Rc::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 123;
-        let r: Rc<dyn Display> = Rc::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 ();
-        let r: Rc<dyn Debug> = Rc::from(b);
-
-        assert_eq!(format!("{:?}", r), "()");
-    }
-
-    #[test]
-    fn test_from_vec() {
-        let v = vec![1, 2, 3];
-        let r: Rc<[u32]> = Rc::from(v);
-
-        assert_eq!(&r[..], [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_downcast() {
-        use std::any::Any;
-
-        let r1: Rc<dyn Any> = Rc::new(i32::max_value());
-        let r2: Rc<dyn Any> = Rc::new("abc");
-
-        assert!(r1.clone().downcast::<u32>().is_err());
-
-        let r1i32 = r1.downcast::<i32>();
-        assert!(r1i32.is_ok());
-        assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value()));
-
-        assert!(r2.clone().downcast::<i32>().is_err());
-
-        let r2str = r2.downcast::<&'static str>();
-        assert!(r2str.is_ok());
-        assert_eq!(r2str.unwrap(), Rc::new("abc"));
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> borrow::Borrow<T> for Rc<T> {
     fn borrow(&self) -> &T {
@@ -2007,3 +2063,22 @@ impl<T: ?Sized> AsRef<T> for Rc<T> {
 
 #[stable(feature = "pin", since = "1.33.0")]
 impl<T: ?Sized> Unpin for Rc<T> { }
+
+unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
+    // Align the unsized value to the end of the `RcBox`.
+    // Because it is ?Sized, it will always be the last field in memory.
+    data_offset_align(align_of_val(&*ptr))
+}
+
+/// Computes the offset of the data field within `RcBox`.
+///
+/// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`.
+fn data_offset_sized<T>() -> isize {
+    data_offset_align(align_of::<T>())
+}
+
+#[inline]
+fn data_offset_align(align: usize) -> isize {
+    let layout = Layout::new::<RcBox<()>>();
+    (layout.size() + layout.padding_needed_for(align)) as isize
+}
diff --git a/src/liballoc/rc/tests.rs b/src/liballoc/rc/tests.rs
new file mode 100644
index 00000000000..6fd3f909357
--- /dev/null
+++ b/src/liballoc/rc/tests.rs
@@ -0,0 +1,439 @@
+use super::*;
+
+use std::boxed::Box;
+use std::cell::RefCell;
+use std::option::Option::{self, None, Some};
+use std::result::Result::{Err, Ok};
+use std::mem::drop;
+use std::clone::Clone;
+use std::convert::{From, TryInto};
+
+#[test]
+fn test_clone() {
+    let x = Rc::new(RefCell::new(5));
+    let y = x.clone();
+    *x.borrow_mut() = 20;
+    assert_eq!(*y.borrow(), 20);
+}
+
+#[test]
+fn test_simple() {
+    let x = Rc::new(5);
+    assert_eq!(*x, 5);
+}
+
+#[test]
+fn test_simple_clone() {
+    let x = Rc::new(5);
+    let y = x.clone();
+    assert_eq!(*x, 5);
+    assert_eq!(*y, 5);
+}
+
+#[test]
+fn test_destructor() {
+    let x: Rc<Box<_>> = Rc::new(box 5);
+    assert_eq!(**x, 5);
+}
+
+#[test]
+fn test_live() {
+    let x = Rc::new(5);
+    let y = Rc::downgrade(&x);
+    assert!(y.upgrade().is_some());
+}
+
+#[test]
+fn test_dead() {
+    let x = Rc::new(5);
+    let y = Rc::downgrade(&x);
+    drop(x);
+    assert!(y.upgrade().is_none());
+}
+
+#[test]
+fn weak_self_cyclic() {
+    struct Cycle {
+        x: RefCell<Option<Weak<Cycle>>>,
+    }
+
+    let a = Rc::new(Cycle { x: RefCell::new(None) });
+    let b = Rc::downgrade(&a.clone());
+    *a.x.borrow_mut() = Some(b);
+
+    // hopefully we don't double-free (or leak)...
+}
+
+#[test]
+fn is_unique() {
+    let x = Rc::new(3);
+    assert!(Rc::is_unique(&x));
+    let y = x.clone();
+    assert!(!Rc::is_unique(&x));
+    drop(y);
+    assert!(Rc::is_unique(&x));
+    let w = Rc::downgrade(&x);
+    assert!(!Rc::is_unique(&x));
+    drop(w);
+    assert!(Rc::is_unique(&x));
+}
+
+#[test]
+fn test_strong_count() {
+    let a = Rc::new(0);
+    assert!(Rc::strong_count(&a) == 1);
+    let w = Rc::downgrade(&a);
+    assert!(Rc::strong_count(&a) == 1);
+    let b = w.upgrade().expect("upgrade of live rc failed");
+    assert!(Rc::strong_count(&b) == 2);
+    assert!(Rc::strong_count(&a) == 2);
+    drop(w);
+    drop(a);
+    assert!(Rc::strong_count(&b) == 1);
+    let c = b.clone();
+    assert!(Rc::strong_count(&b) == 2);
+    assert!(Rc::strong_count(&c) == 2);
+}
+
+#[test]
+fn test_weak_count() {
+    let a = Rc::new(0);
+    assert!(Rc::strong_count(&a) == 1);
+    assert!(Rc::weak_count(&a) == 0);
+    let w = Rc::downgrade(&a);
+    assert!(Rc::strong_count(&a) == 1);
+    assert!(Rc::weak_count(&a) == 1);
+    drop(w);
+    assert!(Rc::strong_count(&a) == 1);
+    assert!(Rc::weak_count(&a) == 0);
+    let c = a.clone();
+    assert!(Rc::strong_count(&a) == 2);
+    assert!(Rc::weak_count(&a) == 0);
+    drop(c);
+}
+
+#[test]
+fn weak_counts() {
+    assert_eq!(Weak::weak_count(&Weak::<u64>::new()), None);
+    assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
+
+    let a = Rc::new(0);
+    let w = Rc::downgrade(&a);
+    assert_eq!(Weak::strong_count(&w), 1);
+    assert_eq!(Weak::weak_count(&w), Some(1));
+    let w2 = w.clone();
+    assert_eq!(Weak::strong_count(&w), 1);
+    assert_eq!(Weak::weak_count(&w), Some(2));
+    assert_eq!(Weak::strong_count(&w2), 1);
+    assert_eq!(Weak::weak_count(&w2), Some(2));
+    drop(w);
+    assert_eq!(Weak::strong_count(&w2), 1);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    let a2 = a.clone();
+    assert_eq!(Weak::strong_count(&w2), 2);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    drop(a2);
+    drop(a);
+    assert_eq!(Weak::strong_count(&w2), 0);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    drop(w2);
+}
+
+#[test]
+fn try_unwrap() {
+    let x = Rc::new(3);
+    assert_eq!(Rc::try_unwrap(x), Ok(3));
+    let x = Rc::new(4);
+    let _y = x.clone();
+    assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4)));
+    let x = Rc::new(5);
+    let _w = Rc::downgrade(&x);
+    assert_eq!(Rc::try_unwrap(x), Ok(5));
+}
+
+#[test]
+fn into_from_raw() {
+    let x = Rc::new(box "hello");
+    let y = x.clone();
+
+    let x_ptr = Rc::into_raw(x);
+    drop(y);
+    unsafe {
+        assert_eq!(**x_ptr, "hello");
+
+        let x = Rc::from_raw(x_ptr);
+        assert_eq!(**x, "hello");
+
+        assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello"));
+    }
+}
+
+#[test]
+fn test_into_from_raw_unsized() {
+    use std::fmt::Display;
+    use std::string::ToString;
+
+    let rc: Rc<str> = Rc::from("foo");
+
+    let ptr = Rc::into_raw(rc.clone());
+    let rc2 = unsafe { Rc::from_raw(ptr) };
+
+    assert_eq!(unsafe { &*ptr }, "foo");
+    assert_eq!(rc, rc2);
+
+    let rc: Rc<dyn Display> = Rc::new(123);
+
+    let ptr = Rc::into_raw(rc.clone());
+    let rc2 = unsafe { Rc::from_raw(ptr) };
+
+    assert_eq!(unsafe { &*ptr }.to_string(), "123");
+    assert_eq!(rc2.to_string(), "123");
+}
+
+#[test]
+fn get_mut() {
+    let mut x = Rc::new(3);
+    *Rc::get_mut(&mut x).unwrap() = 4;
+    assert_eq!(*x, 4);
+    let y = x.clone();
+    assert!(Rc::get_mut(&mut x).is_none());
+    drop(y);
+    assert!(Rc::get_mut(&mut x).is_some());
+    let _w = Rc::downgrade(&x);
+    assert!(Rc::get_mut(&mut x).is_none());
+}
+
+#[test]
+fn test_cowrc_clone_make_unique() {
+    let mut cow0 = Rc::new(75);
+    let mut cow1 = cow0.clone();
+    let mut cow2 = cow1.clone();
+
+    assert!(75 == *Rc::make_mut(&mut cow0));
+    assert!(75 == *Rc::make_mut(&mut cow1));
+    assert!(75 == *Rc::make_mut(&mut cow2));
+
+    *Rc::make_mut(&mut cow0) += 1;
+    *Rc::make_mut(&mut cow1) += 2;
+    *Rc::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_cowrc_clone_unique2() {
+    let mut cow0 = Rc::new(75);
+    let cow1 = cow0.clone();
+    let cow2 = cow1.clone();
+
+    assert!(75 == *cow0);
+    assert!(75 == *cow1);
+    assert!(75 == *cow2);
+
+    *Rc::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_cowrc_clone_weak() {
+    let mut cow0 = Rc::new(75);
+    let cow1_weak = Rc::downgrade(&cow0);
+
+    assert!(75 == *cow0);
+    assert!(75 == *cow1_weak.upgrade().unwrap());
+
+    *Rc::make_mut(&mut cow0) += 1;
+
+    assert!(76 == *cow0);
+    assert!(cow1_weak.upgrade().is_none());
+}
+
+#[test]
+fn test_show() {
+    let foo = Rc::new(75);
+    assert_eq!(format!("{:?}", foo), "75");
+}
+
+#[test]
+fn test_unsized() {
+    let foo: Rc<[i32]> = Rc::new([1, 2, 3]);
+    assert_eq!(foo, foo.clone());
+}
+
+#[test]
+fn test_from_owned() {
+    let foo = 123;
+    let foo_rc = Rc::from(foo);
+    assert!(123 == *foo_rc);
+}
+
+#[test]
+fn test_new_weak() {
+    let foo: Weak<usize> = Weak::new();
+    assert!(foo.upgrade().is_none());
+}
+
+#[test]
+fn test_ptr_eq() {
+    let five = Rc::new(5);
+    let same_five = five.clone();
+    let other_five = Rc::new(5);
+
+    assert!(Rc::ptr_eq(&five, &same_five));
+    assert!(!Rc::ptr_eq(&five, &other_five));
+}
+
+#[test]
+fn test_from_str() {
+    let r: Rc<str> = Rc::from("foo");
+
+    assert_eq!(&r[..], "foo");
+}
+
+#[test]
+fn test_copy_from_slice() {
+    let s: &[u32] = &[1, 2, 3];
+    let r: Rc<[u32]> = Rc::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: Rc<[X]> = Rc::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: Rc<[Fail]> = Rc::from(s);
+}
+
+#[test]
+fn test_from_box() {
+    let b: Box<u32> = box 123;
+    let r: Rc<u32> = Rc::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: Rc<str> = Rc::from(s);
+
+    assert_eq!(&r[..], "foo");
+}
+
+#[test]
+fn test_from_box_slice() {
+    let s = vec![1, 2, 3].into_boxed_slice();
+    let r: Rc<[u32]> = Rc::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 123;
+    let r: Rc<dyn Display> = Rc::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 ();
+    let r: Rc<dyn Debug> = Rc::from(b);
+
+    assert_eq!(format!("{:?}", r), "()");
+}
+
+#[test]
+fn test_from_vec() {
+    let v = vec![1, 2, 3];
+    let r: Rc<[u32]> = Rc::from(v);
+
+    assert_eq!(&r[..], [1, 2, 3]);
+}
+
+#[test]
+fn test_downcast() {
+    use std::any::Any;
+
+    let r1: Rc<dyn Any> = Rc::new(i32::max_value());
+    let r2: Rc<dyn Any> = Rc::new("abc");
+
+    assert!(r1.clone().downcast::<u32>().is_err());
+
+    let r1i32 = r1.downcast::<i32>();
+    assert!(r1i32.is_ok());
+    assert_eq!(r1i32.unwrap(), Rc::new(i32::max_value()));
+
+    assert!(r2.clone().downcast::<i32>().is_err());
+
+    let r2str = r2.downcast::<&'static str>();
+    assert!(r2str.is_ok());
+    assert_eq!(r2str.unwrap(), Rc::new("abc"));
+}
+
+#[test]
+fn test_array_from_slice() {
+    let v = vec![1, 2, 3];
+    let r: Rc<[u32]> = Rc::from(v);
+
+    let a: Result<Rc<[u32; 3]>, _> = r.clone().try_into();
+    assert!(a.is_ok());
+
+    let a: Result<Rc<[u32; 2]>, _> = r.clone().try_into();
+    assert!(a.is_err());
+}
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 6eac8487401..881d499c074 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -123,12 +123,12 @@ pub use core::slice::{RChunks, RChunksMut, RChunksExact, RChunksExactMut};
 ////////////////////////////////////////////////////////////////////////////////
 
 // HACK(japaric) needed for the implementation of `vec!` macro during testing
-// NB see the hack module in this file for more details
+// N.B., see the `hack` module in this file for more details.
 #[cfg(test)]
 pub use hack::into_vec;
 
 // HACK(japaric) needed for the implementation of `Vec::clone` during testing
-// NB see the hack module in this file for more details
+// N.B., see the `hack` module in this file for more details.
 #[cfg(test)]
 pub use hack::to_vec;
 
@@ -137,17 +137,16 @@ pub use hack::to_vec;
 // `core::slice::SliceExt` - we need to supply these functions for the
 // `test_permutations` test
 mod hack {
-    use core::mem;
-
     use crate::boxed::Box;
     use crate::vec::Vec;
     #[cfg(test)]
     use crate::string::ToString;
 
-    pub fn into_vec<T>(mut b: Box<[T]>) -> Vec<T> {
+    pub fn into_vec<T>(b: Box<[T]>) -> Vec<T> {
         unsafe {
-            let xs = Vec::from_raw_parts(b.as_mut_ptr(), b.len(), b.len());
-            mem::forget(b);
+            let len = b.len();
+            let b = Box::into_raw(b);
+            let xs = Vec::from_raw_parts(b as *mut T, len, len);
             xs
         }
     }
@@ -376,7 +375,7 @@ impl<T> [T] {
     pub fn to_vec(&self) -> Vec<T>
         where T: Clone
     {
-        // NB see hack module in this file
+        // N.B., see the `hack` module in this file for more details.
         hack::to_vec(self)
     }
 
@@ -397,7 +396,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn into_vec(self: Box<Self>) -> Vec<T> {
-        // NB see hack module in this file
+        // N.B., see the `hack` module in this file for more details.
         hack::into_vec(self)
     }
 
@@ -485,6 +484,57 @@ impl<T> [T] {
         }
         buf
     }
+
+    /// Flattens a slice of `T` into a single value `Self::Output`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!(["hello", "world"].concat(), "helloworld");
+    /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output
+        where Self: Concat<Item>
+    {
+        Concat::concat(self)
+    }
+
+    /// Flattens a slice of `T` into a single value `Self::Output`, placing a
+    /// given separator between each.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!(["hello", "world"].join(" "), "hello world");
+    /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+    /// assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+    /// ```
+    #[stable(feature = "rename_connect_to_join", since = "1.3.0")]
+    pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
+        where Self: Join<Separator>
+    {
+        Join::join(self, sep)
+    }
+
+    /// Flattens a slice of `T` into a single value `Self::Output`, placing a
+    /// given separator between each.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![allow(deprecated)]
+    /// assert_eq!(["hello", "world"].connect(" "), "hello world");
+    /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
+    pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
+        where Self: Join<Separator>
+    {
+        Join::join(self, sep)
+    }
+
 }
 
 #[lang = "slice_u8_alloc"]
@@ -528,85 +578,84 @@ impl [u8] {
 ////////////////////////////////////////////////////////////////////////////////
 // Extension traits for slices over specific kinds of data
 ////////////////////////////////////////////////////////////////////////////////
-#[unstable(feature = "slice_concat_ext",
-           reason = "trait should not have to exist",
-           issue = "27747")]
-/// An extension trait for concatenating slices
+
+/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat).
 ///
-/// While this trait is unstable, the methods are stable. `SliceConcatExt` is
-/// included in the [standard library prelude], so you can use [`join()`] and
-/// [`concat()`] as if they existed on `[T]` itself.
+/// Note: the `Item` type parameter is not used in this trait,
+/// but it allows impls to be more generic.
+/// Without it, we get this error:
 ///
-/// [standard library prelude]: ../../std/prelude/index.html
-/// [`join()`]: #tymethod.join
-/// [`concat()`]: #tymethod.concat
-pub trait SliceConcatExt<T: ?Sized> {
-    #[unstable(feature = "slice_concat_ext",
-               reason = "trait should not have to exist",
-               issue = "27747")]
+/// ```error
+/// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predica
+///    --> src/liballoc/slice.rs:608:6
+///     |
+/// 608 | impl<T: Clone, V: Borrow<[T]>> Concat for [V] {
+///     |      ^ unconstrained type parameter
+/// ```
+///
+/// This is because there could exist `V` types with multiple `Borrow<[_]>` impls,
+/// such that multiple `T` types would apply:
+///
+/// ```
+/// # #[allow(dead_code)]
+/// pub struct Foo(Vec<u32>, Vec<String>);
+///
+/// impl std::borrow::Borrow<[u32]> for Foo {
+///     fn borrow(&self) -> &[u32] { &self.0 }
+/// }
+///
+/// impl std::borrow::Borrow<[String]> for Foo {
+///     fn borrow(&self) -> &[String] { &self.1 }
+/// }
+/// ```
+#[unstable(feature = "slice_concat_trait", issue = "27747")]
+pub trait Concat<Item: ?Sized> {
+    #[unstable(feature = "slice_concat_trait", issue = "27747")]
     /// The resulting type after concatenation
     type Output;
 
-    /// Flattens a slice of `T` into a single value `Self::Output`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// assert_eq!(["hello", "world"].concat(), "helloworld");
-    /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn concat(&self) -> Self::Output;
+    /// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat)
+    #[unstable(feature = "slice_concat_trait", issue = "27747")]
+    fn concat(slice: &Self) -> Self::Output;
+}
 
-    /// Flattens a slice of `T` into a single value `Self::Output`, placing a
-    /// given separator between each.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// assert_eq!(["hello", "world"].join(" "), "hello world");
-    /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
-    /// ```
-    #[stable(feature = "rename_connect_to_join", since = "1.3.0")]
-    fn join(&self, sep: &T) -> Self::Output;
+/// Helper trait for [`[T]::join`](../../std/primitive.slice.html#method.join)
+#[unstable(feature = "slice_concat_trait", issue = "27747")]
+pub trait Join<Separator> {
+    #[unstable(feature = "slice_concat_trait", issue = "27747")]
+    /// The resulting type after concatenation
+    type Output;
 
-    /// Flattens a slice of `T` into a single value `Self::Output`, placing a
-    /// given separator between each.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![allow(deprecated)]
-    /// assert_eq!(["hello", "world"].connect(" "), "hello world");
-    /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
-    fn connect(&self, sep: &T) -> Self::Output;
+    /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join)
+    #[unstable(feature = "slice_concat_trait", issue = "27747")]
+    fn join(slice: &Self, sep: Separator) -> Self::Output;
 }
 
-#[unstable(feature = "slice_concat_ext",
-           reason = "trait should not have to exist",
-           issue = "27747")]
-impl<T: Clone, V: Borrow<[T]>> SliceConcatExt<T> for [V] {
+#[unstable(feature = "slice_concat_ext", issue = "27747")]
+impl<T: Clone, V: Borrow<[T]>> Concat<T> for [V] {
     type Output = Vec<T>;
 
-    fn concat(&self) -> Vec<T> {
-        let size = self.iter().map(|slice| slice.borrow().len()).sum();
+    fn concat(slice: &Self) -> Vec<T> {
+        let size = slice.iter().map(|slice| slice.borrow().len()).sum();
         let mut result = Vec::with_capacity(size);
-        for v in self {
+        for v in slice {
             result.extend_from_slice(v.borrow())
         }
         result
     }
+}
+
+#[unstable(feature = "slice_concat_ext", issue = "27747")]
+impl<T: Clone, V: Borrow<[T]>> Join<&T> for [V] {
+    type Output = Vec<T>;
 
-    fn join(&self, sep: &T) -> Vec<T> {
-        let mut iter = self.iter();
+    fn join(slice: &Self, sep: &T) -> Vec<T> {
+        let mut iter = slice.iter();
         let first = match iter.next() {
             Some(first) => first,
             None => return vec![],
         };
-        let size = self.iter().map(|slice| slice.borrow().len()).sum::<usize>() + self.len() - 1;
+        let size = slice.iter().map(|v| v.borrow().len()).sum::<usize>() + slice.len() - 1;
         let mut result = Vec::with_capacity(size);
         result.extend_from_slice(first.borrow());
 
@@ -616,9 +665,28 @@ impl<T: Clone, V: Borrow<[T]>> SliceConcatExt<T> for [V] {
         }
         result
     }
+}
+
+#[unstable(feature = "slice_concat_ext", issue = "27747")]
+impl<T: Clone, V: Borrow<[T]>> Join<&[T]> for [V] {
+    type Output = Vec<T>;
+
+    fn join(slice: &Self, sep: &[T]) -> Vec<T> {
+        let mut iter = slice.iter();
+        let first = match iter.next() {
+            Some(first) => first,
+            None => return vec![],
+        };
+        let size = slice.iter().map(|v| v.borrow().len()).sum::<usize>() +
+            sep.len() * (slice.len() - 1);
+        let mut result = Vec::with_capacity(size);
+        result.extend_from_slice(first.borrow());
 
-    fn connect(&self, sep: &T) -> Vec<T> {
-        self.join(sep)
+        for v in iter {
+            result.extend_from_slice(sep);
+            result.extend_from_slice(v.borrow())
+        }
+        result
     }
 }
 
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index f66ff894ae8..9a1342c30d5 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -37,7 +37,7 @@ use core::unicode::conversions;
 
 use crate::borrow::ToOwned;
 use crate::boxed::Box;
-use crate::slice::{SliceConcatExt, SliceIndex};
+use crate::slice::{Concat, Join, SliceIndex};
 use crate::string::String;
 use crate::vec::Vec;
 
@@ -71,25 +71,26 @@ pub use core::str::SplitAsciiWhitespace;
 #[stable(feature = "str_escape", since = "1.34.0")]
 pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode};
 
-#[unstable(feature = "slice_concat_ext",
-           reason = "trait should not have to exist",
-           issue = "27747")]
-impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
+/// Note: `str` in `Concat<str>` is not meaningful here.
+/// This type parameter of the trait only exists to enable another impl.
+#[unstable(feature = "slice_concat_ext", issue = "27747")]
+impl<S: Borrow<str>> Concat<str> for [S] {
     type Output = String;
 
-    fn concat(&self) -> String {
-        self.join("")
+    fn concat(slice: &Self) -> String {
+        Join::join(slice, "")
     }
+}
+
+#[unstable(feature = "slice_concat_ext", issue = "27747")]
+impl<S: Borrow<str>> Join<&str> for [S] {
+    type Output = String;
 
-    fn join(&self, sep: &str) -> String {
+    fn join(slice: &Self, sep: &str) -> String {
         unsafe {
-            String::from_utf8_unchecked( join_generic_copy(self, sep.as_bytes()) )
+            String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) )
         }
     }
-
-    fn connect(&self, sep: &str) -> String {
-        self.join(sep)
-    }
 }
 
 macro_rules! spezialize_for_lengths {
@@ -130,7 +131,7 @@ macro_rules! copy_slice_and_advance {
 
 // Optimized join implementation that works for both Vec<T> (T: Copy) and String's inner vec
 // Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262)
-// For this reason SliceConcatExt<T> is not specialized for T: Copy and SliceConcatExt<str> is the
+// For this reason SliceConcat<T> is not specialized for T: Copy and SliceConcat<str> is the
 // only user of this function. It is left in place for the time when that is fixed.
 //
 // the bounds for String-join are S: Borrow<str> and for Vec-join Borrow<[T]>
@@ -207,7 +208,7 @@ impl ToOwned for str {
     }
 
     fn clone_into(&self, target: &mut String) {
-        let mut b = mem::replace(target, String::new()).into_bytes();
+        let mut b = mem::take(target).into_bytes();
         self.as_bytes().clone_into(&mut b);
         *target = unsafe { String::from_utf8_unchecked(b) }
     }
@@ -431,6 +432,13 @@ impl str {
     ///
     /// assert_eq!(new_year, new_year.to_uppercase());
     /// ```
+    ///
+    /// One character can become multiple:
+    /// ```
+    /// let s = "tschüß";
+    ///
+    /// assert_eq!("TSCHÜSS", s.to_uppercase());
+    /// ```
     #[stable(feature = "unicode_case_mapping", since = "1.2.0")]
     pub fn to_uppercase(&self) -> String {
         let mut s = String::with_capacity(self.len());
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index e74d37c1c2b..b65f191836e 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -56,7 +56,7 @@ use core::ptr;
 use core::str::{pattern::Pattern, lossy};
 
 use crate::borrow::{Cow, ToOwned};
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::boxed::Box;
 use crate::str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars};
 use crate::vec::Vec;
@@ -552,7 +552,7 @@ impl String {
     /// assert_eq!("Hello �World", output);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
+    pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> {
         let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks();
 
         let (first_valid, first_broken) = if let Some(chunk) = iter.next() {
@@ -937,9 +937,9 @@ impl String {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     ///
-    /// fn process_data(data: &str) -> Result<String, CollectionAllocErr> {
+    /// fn process_data(data: &str) -> Result<String, TryReserveError> {
     ///     let mut output = String::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -953,7 +953,7 @@ impl String {
     /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.vec.try_reserve(additional)
     }
 
@@ -975,9 +975,9 @@ impl String {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     ///
-    /// fn process_data(data: &str) -> Result<String, CollectionAllocErr> {
+    /// fn process_data(data: &str) -> Result<String, TryReserveError> {
     ///     let mut output = String::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -991,7 +991,7 @@ impl String {
     /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr>  {
+    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError>  {
         self.vec.try_reserve_exact(additional)
     }
 
@@ -1838,6 +1838,7 @@ impl PartialEq for String {
 macro_rules! impl_eq {
     ($lhs:ty, $rhs: ty) => {
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(unused_lifetimes)]
         impl<'a, 'b> PartialEq<$rhs> for $lhs {
             #[inline]
             fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&self[..], &other[..]) }
@@ -1846,6 +1847,7 @@ macro_rules! impl_eq {
         }
 
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(unused_lifetimes)]
         impl<'a, 'b> PartialEq<$lhs> for $rhs {
             #[inline]
             fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&self[..], &other[..]) }
@@ -2385,6 +2387,7 @@ impl Iterator for Drain<'_> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
     #[inline]
     fn last(mut self) -> Option<char> {
         self.next_back()
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 90c7859b3db..341172136e2 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -7,21 +7,23 @@
 //! [arc]: struct.Arc.html
 
 use core::any::Any;
+use core::array::LengthAtMost32;
 use core::sync::atomic;
 use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
 use core::borrow;
 use core::fmt;
 use core::cmp::{self, Ordering};
+use core::iter;
 use core::intrinsics::abort;
-use core::mem::{self, align_of_val, size_of_val};
+use core::mem::{self, align_of, align_of_val, size_of_val};
 use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn};
 use core::pin::Pin;
 use core::ptr::{self, NonNull};
 use core::marker::{Unpin, Unsize, PhantomData};
 use core::hash::{Hash, Hasher};
 use core::{isize, usize};
-use core::convert::From;
-use core::slice::from_raw_parts_mut;
+use core::convert::{From, TryFrom};
+use core::slice::{self, from_raw_parts_mut};
 
 use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
 use crate::boxed::Box;
@@ -29,6 +31,9 @@ use crate::rc::is_dangling;
 use crate::string::String;
 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
@@ -206,6 +211,19 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Arc<U>> for Arc<T> {}
 
+impl<T: ?Sized> Arc<T> {
+    fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
+        Self {
+            ptr,
+            phantom: PhantomData,
+        }
+    }
+
+    unsafe fn from_ptr(ptr: *mut ArcInner<T>) -> Self {
+        Self::from_inner(NonNull::new_unchecked(ptr))
+    }
+}
+
 /// `Weak` is a version of [`Arc`] that holds a non-owning reference to the
 /// managed value. The value is accessed by calling [`upgrade`] on the `Weak`
 /// pointer, which returns an [`Option`]`<`[`Arc`]`<T>>`.
@@ -290,7 +308,38 @@ impl<T> Arc<T> {
             weak: atomic::AtomicUsize::new(1),
             data,
         };
-        Arc { ptr: Box::into_raw_non_null(x), phantom: PhantomData }
+        Self::from_inner(Box::into_raw_non_null(x))
+    }
+
+    /// Constructs a new `Arc` with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut five = Arc::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
+        unsafe {
+            Arc::from_ptr(Arc::allocate_for_layout(
+                Layout::new::<T>(),
+                |mem| mem as *mut ArcInner<mem::MaybeUninit<T>>,
+            ))
+        }
     }
 
     /// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then
@@ -343,6 +392,118 @@ impl<T> Arc<T> {
     }
 }
 
+impl<T> Arc<[T]> {
+    /// Constructs a new reference-counted slice with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+    ///     Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+    ///     Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
+        unsafe {
+            Arc::from_ptr(Arc::allocate_for_slice(len))
+        }
+    }
+}
+
+impl<T> Arc<mem::MaybeUninit<T>> {
+    /// Converts to `Arc<T>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut five = Arc::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Arc<T> {
+        Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
+    }
+}
+
+impl<T> Arc<[mem::MaybeUninit<T>]> {
+    /// Converts to `Arc<[T]>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+    ///     Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+    ///     Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Arc<[T]> {
+        Arc::from_ptr(mem::ManuallyDrop::new(self).ptr.as_ptr() as _)
+    }
+}
+
 impl<T: ?Sized> Arc<T> {
     /// Consumes the `Arc`, returning the wrapped pointer.
     ///
@@ -356,9 +517,9 @@ impl<T: ?Sized> Arc<T> {
     /// ```
     /// use std::sync::Arc;
     ///
-    /// let x = Arc::new(10);
+    /// let x = Arc::new("hello".to_owned());
     /// let x_ptr = Arc::into_raw(x);
-    /// assert_eq!(unsafe { *x_ptr }, 10);
+    /// assert_eq!(unsafe { &*x_ptr }, "hello");
     /// ```
     #[stable(feature = "rc_raw", since = "1.17.0")]
     pub fn into_raw(this: Self) -> *const T {
@@ -382,13 +543,13 @@ impl<T: ?Sized> Arc<T> {
     /// ```
     /// use std::sync::Arc;
     ///
-    /// let x = Arc::new(10);
+    /// let x = Arc::new("hello".to_owned());
     /// let x_ptr = Arc::into_raw(x);
     ///
     /// unsafe {
     ///     // Convert back to an `Arc` to prevent leak.
     ///     let x = Arc::from_raw(x_ptr);
-    ///     assert_eq!(*x, 10);
+    ///     assert_eq!(&*x, "hello");
     ///
     ///     // Further calls to `Arc::from_raw(x_ptr)` would be memory unsafe.
     /// }
@@ -397,20 +558,13 @@ impl<T: ?Sized> Arc<T> {
     /// ```
     #[stable(feature = "rc_raw", since = "1.17.0")]
     pub unsafe fn from_raw(ptr: *const T) -> Self {
-        // Align the unsized value to the end of the ArcInner.
-        // Because it is ?Sized, it will always be the last field in memory.
-        let align = align_of_val(&*ptr);
-        let layout = Layout::new::<ArcInner<()>>();
-        let offset = (layout.size() + layout.padding_needed_for(align)) as isize;
+        let offset = data_offset(ptr);
 
         // Reverse the offset to find the original ArcInner.
         let fake_ptr = ptr as *mut ArcInner<T>;
         let arc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
 
-        Arc {
-            ptr: NonNull::new_unchecked(arc_ptr),
-            phantom: PhantomData,
-        }
+        Self::from_ptr(arc_ptr)
     }
 
     /// Consumes the `Arc`, returning the wrapped pointer as `NonNull<T>`.
@@ -422,10 +576,10 @@ impl<T: ?Sized> Arc<T> {
     ///
     /// use std::sync::Arc;
     ///
-    /// let x = Arc::new(10);
+    /// let x = Arc::new("hello".to_owned());
     /// let ptr = Arc::into_raw_non_null(x);
-    /// let deref = unsafe { *ptr.as_ref() };
-    /// assert_eq!(deref, 10);
+    /// let deref = unsafe { ptr.as_ref() };
+    /// assert_eq!(deref, "hello");
     /// ```
     #[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
     #[inline]
@@ -581,21 +735,28 @@ impl<T: ?Sized> Arc<T> {
 }
 
 impl<T: ?Sized> Arc<T> {
-    // Allocates an `ArcInner<T>` with sufficient space for an unsized value
-    unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner<T> {
-        // Calculate layout using the given value.
+    /// Allocates an `ArcInner<T>` with sufficient space for
+    /// a possibly-unsized value where the value has the layout provided.
+    ///
+    /// The function `mem_to_arcinner` is called with the data pointer
+    /// and must return back a (potentially fat)-pointer for the `ArcInner<T>`.
+    unsafe fn allocate_for_layout(
+        value_layout: Layout,
+        mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>
+    ) -> *mut ArcInner<T> {
+        // Calculate layout using the given value layout.
         // Previously, layout was calculated on the expression
         // `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
         // reference (see #54908).
         let layout = Layout::new::<ArcInner<()>>()
-            .extend(Layout::for_value(&*ptr)).unwrap().0
+            .extend(value_layout).unwrap().0
             .pad_to_align().unwrap();
 
         let mem = Global.alloc(layout)
             .unwrap_or_else(|_| handle_alloc_error(layout));
 
         // Initialize the ArcInner
-        let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut ArcInner<T>;
+        let inner = mem_to_arcinner(mem.as_ptr());
         debug_assert_eq!(Layout::for_value(&*inner), layout);
 
         ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
@@ -604,6 +765,15 @@ impl<T: ?Sized> Arc<T> {
         inner
     }
 
+    /// Allocates an `ArcInner<T>` with sufficient space for an unsized value.
+    unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner<T> {
+        // Allocate for the `ArcInner<T>` using the given value.
+        Self::allocate_for_layout(
+            Layout::for_value(&*ptr),
+            |mem| set_data_ptr(ptr as *mut T, mem) as *mut ArcInner<T>,
+        )
+    }
+
     fn from_box(v: Box<T>) -> Arc<T> {
         unsafe {
             let box_unique = Box::into_unique(v);
@@ -621,45 +791,49 @@ impl<T: ?Sized> Arc<T> {
             // Free the allocation without dropping its contents
             box_free(box_unique);
 
-            Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
+            Self::from_ptr(ptr)
         }
     }
 }
 
-// Sets the data pointer of a `?Sized` raw pointer.
-//
-// For a slice/trait object, this sets the `data` field and leaves the rest
-// unchanged. For a sized raw pointer, this simply sets the pointer.
+impl<T> Arc<[T]> {
+    /// Allocates an `ArcInner<[T]>` with the given length.
+    unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> {
+        Self::allocate_for_layout(
+            Layout::array::<T>(len).unwrap(),
+            |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>,
+        )
+    }
+}
+
+/// Sets the data pointer of a `?Sized` raw pointer.
+///
+/// For a slice/trait object, this sets the `data` field and leaves the rest
+/// unchanged. For a sized raw pointer, this simply sets the pointer.
 unsafe fn set_data_ptr<T: ?Sized, U>(mut ptr: *mut T, data: *mut U) -> *mut T {
     ptr::write(&mut ptr as *mut _ as *mut *mut u8, data as *mut u8);
     ptr
 }
 
 impl<T> Arc<[T]> {
-    // Copy elements from slice into newly allocated Arc<[T]>
-    //
-    // Unsafe because the caller must either take ownership or bind `T: Copy`
+    /// Copy elements from slice into newly allocated Arc<[T]>
+    ///
+    /// Unsafe because the caller must either take ownership or bind `T: Copy`.
     unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> {
-        let v_ptr = v as *const [T];
-        let ptr = Self::allocate_for_ptr(v_ptr);
+        let ptr = Self::allocate_for_slice(v.len());
 
         ptr::copy_nonoverlapping(
             v.as_ptr(),
             &mut (*ptr).data as *mut [T] as *mut T,
             v.len());
 
-        Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
+        Self::from_ptr(ptr)
     }
-}
-
-// Specialization trait used for From<&[T]>
-trait ArcFromSlice<T> {
-    fn from_slice(slice: &[T]) -> Self;
-}
 
-impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
-    #[inline]
-    default fn from_slice(v: &[T]) -> Self {
+    /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size.
+    ///
+    /// Behavior is undefined should the size be wrong.
+    unsafe fn from_iter_exact(iter: impl iter::Iterator<Item = T>, len: usize) -> Arc<[T]> {
         // Panic guard while cloning T elements.
         // In the event of a panic, elements that have been written
         // into the new ArcInner will be dropped, then the memory freed.
@@ -676,37 +850,48 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
                     let slice = from_raw_parts_mut(self.elems, self.n_elems);
                     ptr::drop_in_place(slice);
 
-                    Global.dealloc(self.mem.cast(), self.layout.clone());
+                    Global.dealloc(self.mem.cast(), self.layout);
                 }
             }
         }
 
-        unsafe {
-            let v_ptr = v as *const [T];
-            let ptr = Self::allocate_for_ptr(v_ptr);
+        let ptr = Self::allocate_for_slice(len);
 
-            let mem = ptr as *mut _ as *mut u8;
-            let layout = Layout::for_value(&*ptr);
+        let mem = ptr as *mut _ as *mut u8;
+        let layout = Layout::for_value(&*ptr);
 
-            // Pointer to first element
-            let elems = &mut (*ptr).data as *mut [T] as *mut T;
+        // Pointer to first element
+        let elems = &mut (*ptr).data as *mut [T] as *mut T;
 
-            let mut guard = Guard{
-                mem: NonNull::new_unchecked(mem),
-                elems: elems,
-                layout: layout,
-                n_elems: 0,
-            };
+        let mut guard = Guard {
+            mem: NonNull::new_unchecked(mem),
+            elems,
+            layout,
+            n_elems: 0,
+        };
 
-            for (i, item) in v.iter().enumerate() {
-                ptr::write(elems.add(i), item.clone());
-                guard.n_elems += 1;
-            }
+        for (i, item) in iter.enumerate() {
+            ptr::write(elems.add(i), item);
+            guard.n_elems += 1;
+        }
 
-            // All clear. Forget the guard so it doesn't free the new ArcInner.
-            mem::forget(guard);
+        // All clear. Forget the guard so it doesn't free the new ArcInner.
+        mem::forget(guard);
 
-            Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
+        Self::from_ptr(ptr)
+    }
+}
+
+/// Specialization trait used for `From<&[T]>`.
+trait ArcFromSlice<T> {
+    fn from_slice(slice: &[T]) -> Self;
+}
+
+impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
+    #[inline]
+    default fn from_slice(v: &[T]) -> Self {
+        unsafe {
+            Self::from_iter_exact(v.iter().cloned(), v.len())
         }
     }
 }
@@ -764,7 +949,7 @@ impl<T: ?Sized> Clone for Arc<T> {
             }
         }
 
-        Arc { ptr: self.ptr, phantom: PhantomData }
+        Self::from_inner(self.ptr)
     }
 }
 
@@ -903,13 +1088,46 @@ impl<T: ?Sized> Arc<T> {
             // the Arc itself to be `mut`, so we're returning the only possible
             // reference to the inner data.
             unsafe {
-                Some(&mut this.ptr.as_mut().data)
+                Some(Arc::get_mut_unchecked(this))
             }
         } else {
             None
         }
     }
 
+    /// Returns a mutable reference to the inner value,
+    /// without any check.
+    ///
+    /// See also [`get_mut`], which is safe and does appropriate checks.
+    ///
+    /// [`get_mut`]: struct.Arc.html#method.get_mut
+    ///
+    /// # Safety
+    ///
+    /// Any other `Arc` or [`Weak`] pointers to the same value must not be dereferenced
+    /// for the duration of the returned borrow.
+    /// This is trivially the case if no such pointers exist,
+    /// for example immediately after `Arc::new`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut x = Arc::new(String::new());
+    /// unsafe {
+    ///     Arc::get_mut_unchecked(&mut x).push_str("foo")
+    /// }
+    /// assert_eq!(*x, "foo");
+    /// ```
+    #[inline]
+    #[unstable(feature = "get_mut_unchecked", issue = "63292")]
+    pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
+        &mut this.ptr.as_mut().data
+    }
+
     /// Determine whether this is the unique reference (including weak refs) to
     /// the underlying data.
     ///
@@ -1043,7 +1261,7 @@ impl Arc<dyn Any + Send + Sync> {
         if (*self).is::<T>() {
             let ptr = self.ptr.cast::<ArcInner<T>>();
             mem::forget(self);
-            Ok(Arc { ptr, phantom: PhantomData })
+            Ok(Arc::from_inner(ptr))
         } else {
             Err(self)
         }
@@ -1071,6 +1289,144 @@ impl<T> Weak<T> {
             ptr: NonNull::new(usize::MAX as *mut ArcInner<T>).expect("MAX is not 0"),
         }
     }
+
+    /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
+    ///
+    /// It is up to the caller to ensure that the object is still alive when accessing it through
+    /// the pointer.
+    ///
+    /// The pointer may be [`null`] or be dangling in case the object has already been destroyed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(weak_into_raw)]
+    ///
+    /// use std::sync::Arc;
+    /// use std::ptr;
+    ///
+    /// let strong = Arc::new("hello".to_owned());
+    /// let weak = Arc::downgrade(&strong);
+    /// // Both point to the same object
+    /// assert!(ptr::eq(&*strong, weak.as_raw()));
+    /// // The strong here keeps it alive, so we can still access the object.
+    /// assert_eq!("hello", unsafe { &*weak.as_raw() });
+    ///
+    /// drop(strong);
+    /// // But not any more. We can do weak.as_raw(), but accessing the pointer would lead to
+    /// // undefined behaviour.
+    /// // assert_eq!("hello", unsafe { &*weak.as_raw() });
+    /// ```
+    ///
+    /// [`null`]: ../../std/ptr/fn.null.html
+    #[unstable(feature = "weak_into_raw", issue = "60728")]
+    pub fn as_raw(&self) -> *const T {
+        match self.inner() {
+            None => ptr::null(),
+            Some(inner) => {
+                let offset = data_offset_sized::<T>();
+                let ptr = inner as *const ArcInner<T>;
+                // Note: while the pointer we create may already point to dropped value, the
+                // allocation still lives (it must hold the weak point as long as we are alive).
+                // Therefore, the offset is OK to do, it won't get out of the allocation.
+                let ptr = unsafe { (ptr as *const u8).offset(offset) };
+                ptr as *const T
+            }
+        }
+    }
+
+    /// Consumes the `Weak<T>` and turns it into a raw pointer.
+    ///
+    /// This converts the weak pointer into a raw pointer, preserving the original weak count. It
+    /// can be turned back into the `Weak<T>` with [`from_raw`].
+    ///
+    /// The same restrictions of accessing the target of the pointer as with
+    /// [`as_raw`] apply.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(weak_into_raw)]
+    ///
+    /// use std::sync::{Arc, Weak};
+    ///
+    /// let strong = Arc::new("hello".to_owned());
+    /// let weak = Arc::downgrade(&strong);
+    /// let raw = weak.into_raw();
+    ///
+    /// assert_eq!(1, Arc::weak_count(&strong));
+    /// assert_eq!("hello", unsafe { &*raw });
+    ///
+    /// drop(unsafe { Weak::from_raw(raw) });
+    /// assert_eq!(0, Arc::weak_count(&strong));
+    /// ```
+    ///
+    /// [`from_raw`]: struct.Weak.html#method.from_raw
+    /// [`as_raw`]: struct.Weak.html#method.as_raw
+    #[unstable(feature = "weak_into_raw", issue = "60728")]
+    pub fn into_raw(self) -> *const T {
+        let result = self.as_raw();
+        mem::forget(self);
+        result
+    }
+
+    /// Converts a raw pointer previously created by [`into_raw`] back into
+    /// `Weak<T>`.
+    ///
+    /// This can be used to safely get a strong reference (by calling [`upgrade`]
+    /// later) or to deallocate the weak count by dropping the `Weak<T>`.
+    ///
+    /// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is
+    /// returned.
+    ///
+    /// # Safety
+    ///
+    /// The pointer must represent one valid weak count. In other words, it must point to `T` which
+    /// is or *was* managed by an [`Arc`] and the weak count of that [`Arc`] must not have reached
+    /// 0. It is allowed for the strong count to be 0.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(weak_into_raw)]
+    ///
+    /// use std::sync::{Arc, Weak};
+    ///
+    /// let strong = Arc::new("hello".to_owned());
+    ///
+    /// let raw_1 = Arc::downgrade(&strong).into_raw();
+    /// let raw_2 = Arc::downgrade(&strong).into_raw();
+    ///
+    /// assert_eq!(2, Arc::weak_count(&strong));
+    ///
+    /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap());
+    /// assert_eq!(1, Arc::weak_count(&strong));
+    ///
+    /// drop(strong);
+    ///
+    /// // Decrement the last weak count.
+    /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
+    /// ```
+    ///
+    /// [`null`]: ../../std/ptr/fn.null.html
+    /// [`into_raw`]: struct.Weak.html#method.into_raw
+    /// [`upgrade`]: struct.Weak.html#method.upgrade
+    /// [`Weak`]: struct.Weak.html
+    /// [`Arc`]: struct.Arc.html
+    #[unstable(feature = "weak_into_raw", issue = "60728")]
+    pub unsafe fn from_raw(ptr: *const T) -> Self {
+        if ptr.is_null() {
+            Self::new()
+        } else {
+            // See Arc::from_raw for details
+            let offset = data_offset(ptr);
+            let fake_ptr = ptr as *mut ArcInner<T>;
+            let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
+            Weak {
+                ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw"),
+            }
+        }
+    }
 }
 
 impl<T: ?Sized> Weak<T> {
@@ -1126,11 +1482,7 @@ impl<T: ?Sized> Weak<T> {
 
             // Relaxed is valid for the same reason it is on Arc's Clone impl
             match inner.strong.compare_exchange_weak(n, n + 1, Relaxed, Relaxed) {
-                Ok(_) => return Some(Arc {
-                    // null checked above
-                    ptr: self.ptr,
-                    phantom: PhantomData,
-                }),
+                Ok(_) => return Some(Arc::from_inner(self.ptr)), // null checked above
                 Err(old) => n = old,
             }
         }
@@ -1215,18 +1567,18 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// ```
     /// #![feature(weak_ptr_eq)]
-    /// use std::sync::{Arc, Weak};
+    /// use std::sync::Arc;
     ///
     /// let first_rc = Arc::new(5);
     /// let first = Arc::downgrade(&first_rc);
     /// let second = Arc::downgrade(&first_rc);
     ///
-    /// assert!(Weak::ptr_eq(&first, &second));
+    /// assert!(first.ptr_eq(&second));
     ///
     /// let third_rc = Arc::new(5);
     /// let third = Arc::downgrade(&third_rc);
     ///
-    /// assert!(!Weak::ptr_eq(&first, &third));
+    /// assert!(!first.ptr_eq(&third));
     /// ```
     ///
     /// Comparing `Weak::new`.
@@ -1237,16 +1589,16 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// let first = Weak::new();
     /// let second = Weak::new();
-    /// assert!(Weak::ptr_eq(&first, &second));
+    /// assert!(first.ptr_eq(&second));
     ///
     /// let third_rc = Arc::new(());
     /// let third = Arc::downgrade(&third_rc);
-    /// assert!(!Weak::ptr_eq(&first, &third));
+    /// assert!(!first.ptr_eq(&third));
     /// ```
     #[inline]
     #[unstable(feature = "weak_ptr_eq", issue = "55981")]
-    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
-        this.ptr.as_ptr() == other.ptr.as_ptr()
+    pub fn ptr_eq(&self, other: &Self) -> bool {
+        self.ptr.as_ptr() == other.ptr.as_ptr()
     }
 }
 
@@ -1651,486 +2003,111 @@ impl<T> From<Vec<T>> for Arc<[T]> {
     }
 }
 
-#[cfg(test)]
-mod tests {
-    use std::boxed::Box;
-    use std::clone::Clone;
-    use std::sync::mpsc::channel;
-    use std::mem::drop;
-    use std::ops::Drop;
-    use std::option::Option::{self, None, Some};
-    use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}};
-    use std::thread;
-    use std::sync::Mutex;
-    use std::convert::From;
-
-    use super::{Arc, Weak};
-    use crate::vec::Vec;
-
-    struct Canary(*mut atomic::AtomicUsize);
-
-    impl Drop for Canary {
-        fn drop(&mut self) {
-            unsafe {
-                match *self {
-                    Canary(c) => {
-                        (*c).fetch_add(1, SeqCst);
-                    }
-                }
-            }
-        }
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    #[cfg(not(miri))] // Miri does not support threads
-    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()), None);
-        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), Some(1));
-        let w2 = w.clone();
-        assert_eq!(Weak::strong_count(&w), 1);
-        assert_eq!(Weak::weak_count(&w), Some(2));
-        assert_eq!(Weak::strong_count(&w2), 1);
-        assert_eq!(Weak::weak_count(&w2), Some(2));
-        drop(w);
-        assert_eq!(Weak::strong_count(&w2), 1);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        let a2 = a.clone();
-        assert_eq!(Weak::strong_count(&w2), 2);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        drop(a2);
-        drop(a);
-        assert_eq!(Weak::strong_count(&w2), 0);
-        assert_eq!(Weak::weak_count(&w2), Some(1));
-        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_from_raw() {
-        let x = Arc::new(box "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 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;
+#[unstable(feature = "boxed_slice_try_from", issue = "0")]
+impl<T, const N: usize> TryFrom<Arc<[T]>> for Arc<[T; N]>
+where
+    [T; N]: LengthAtMost32,
+{
+    type Error = Arc<[T]>;
 
-        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 = atomic::AtomicUsize::new(0);
-        let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
-        drop(x);
-        assert!(canary.load(Acquire) == 1);
-    }
-
-    #[test]
-    fn drop_arc_weak() {
-        let mut canary = atomic::AtomicUsize::new(0);
-        let arc = Arc::new(Canary(&mut canary as *mut atomic::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_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)]
-    #[cfg(not(miri))] // Miri does not support threads
-    fn test_weak_count_locked() {
-        let mut a = Arc::new(atomic::AtomicBool::new(false));
-        let a2 = a.clone();
-        let t = thread::spawn(move || {
-            for _i in 0..1000000 {
-                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);
+    fn try_from(boxed_slice: Arc<[T]>) -> Result<Self, Self::Error> {
+        if boxed_slice.len() == N {
+            Ok(unsafe { Arc::from_raw(Arc::into_raw(boxed_slice) as *mut [T; N]) })
+        } else {
+            Err(boxed_slice)
         }
-        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]);
+#[stable(feature = "shared_from_iter", since = "1.37.0")]
+impl<T> iter::FromIterator<T> for Arc<[T]> {
+    /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`.
+    ///
+    /// # Performance characteristics
+    ///
+    /// ## The general case
+    ///
+    /// In the general case, collecting into `Arc<[T]>` is done by first
+    /// collecting into a `Vec<T>`. That is, when writing the following:
+    ///
+    /// ```rust
+    /// # use std::sync::Arc;
+    /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();
+    /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
+    /// ```
+    ///
+    /// this behaves as if we wrote:
+    ///
+    /// ```rust
+    /// # use std::sync::Arc;
+    /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0)
+    ///     .collect::<Vec<_>>() // The first set of allocations happens here.
+    ///     .into(); // A second allocation for `Arc<[T]>` happens here.
+    /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
+    /// ```
+    ///
+    /// This will allocate as many times as needed for constructing the `Vec<T>`
+    /// and then it will allocate once for turning the `Vec<T>` into the `Arc<[T]>`.
+    ///
+    /// ## Iterators of known length
+    ///
+    /// When your `Iterator` implements `TrustedLen` and is of an exact size,
+    /// a single allocation will be made for the `Arc<[T]>`. For example:
+    ///
+    /// ```rust
+    /// # use std::sync::Arc;
+    /// let evens: Arc<[u8]> = (0..10).collect(); // Just a single allocation happens here.
+    /// # assert_eq!(&*evens, &*(0..10).collect::<Vec<_>>());
+    /// ```
+    fn from_iter<I: iter::IntoIterator<Item = T>>(iter: I) -> Self {
+        ArcFromIter::from_iter(iter.into_iter())
     }
+}
 
-    #[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);
+/// Specialization trait used for collecting into `Arc<[T]>`.
+trait ArcFromIter<T, I> {
+    fn from_iter(iter: I) -> Self;
+}
 
-        assert_eq!(&r[..], s);
+impl<T, I: Iterator<Item = T>> ArcFromIter<T, I> for Arc<[T]> {
+    default fn from_iter(iter: I) -> Self {
+        iter.collect::<Vec<T>>().into()
     }
+}
 
-    #[test]
-    #[should_panic]
-    fn test_clone_from_slice_panic() {
-        use std::string::{String, ToString};
-
-        struct Fail(u32, String);
+impl<T, I: iter::TrustedLen<Item = T>> ArcFromIter<T, I> for Arc<[T]> {
+    default fn from_iter(iter: I) -> Self {
+        // This is the case for a `TrustedLen` iterator.
+        let (low, high) = iter.size_hint();
+        if let Some(high) = high {
+            debug_assert_eq!(
+                low, high,
+                "TrustedLen iterator's size hint is not exact: {:?}",
+                (low, high)
+            );
 
-        impl Clone for Fail {
-            fn clone(&self) -> Fail {
-                if self.0 == 2 {
-                    panic!();
-                }
-                Fail(self.0, self.1.clone())
+            unsafe {
+                // SAFETY: We need to ensure that the iterator has an exact length and we have.
+                Arc::from_iter_exact(iter, low)
             }
+        } else {
+            // Fall back to normal implementation.
+            iter.collect::<Vec<T>>().into()
         }
-
-        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 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 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 ();
-        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_value());
-        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_value()));
-
-        assert!(r2.clone().downcast::<i32>().is_err());
-
-        let r2str = r2.downcast::<&'static str>();
-        assert!(r2str.is_ok());
-        assert_eq!(r2str.unwrap(), Arc::new("abc"));
+impl<'a, T: 'a + Clone> ArcFromIter<&'a T, slice::Iter<'a, T>> for Arc<[T]> {
+    fn from_iter(iter: slice::Iter<'a, T>) -> Self {
+        // Delegate to `impl<T: Clone> From<&[T]> for Arc<[T]>`.
+        //
+        // In the case that `T: Copy`, we get to use `ptr::copy_nonoverlapping`
+        // which is even more performant.
+        //
+        // In the fall-back case we have `T: Clone`. This is still better
+        // than the `TrustedLen` implementation as slices have a known length
+        // and so we get to avoid calling `size_hint` and avoid the branching.
+        iter.as_slice().into()
     }
 }
 
@@ -2150,3 +2127,23 @@ impl<T: ?Sized> AsRef<T> for Arc<T> {
 
 #[stable(feature = "pin", since = "1.33.0")]
 impl<T: ?Sized> Unpin for Arc<T> { }
+
+/// Computes the offset of the data field within `ArcInner`.
+unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
+    // Align the unsized value to the end of the `ArcInner`.
+    // Because it is `?Sized`, it will always be the last field in memory.
+    data_offset_align(align_of_val(&*ptr))
+}
+
+/// Computes the offset of the data field within `ArcInner`.
+///
+/// Unlike [`data_offset`], this doesn't need the pointer, but it works only on `T: Sized`.
+fn data_offset_sized<T>() -> isize {
+    data_offset_align(align_of::<T>())
+}
+
+#[inline]
+fn data_offset_align(align: usize) -> isize {
+    let layout = Layout::new::<ArcInner<()>>();
+    (layout.size() + layout.padding_needed_for(align)) as isize
+}
diff --git a/src/liballoc/sync/tests.rs b/src/liballoc/sync/tests.rs
new file mode 100644
index 00000000000..9220f5e0333
--- /dev/null
+++ b/src/liballoc/sync/tests.rs
@@ -0,0 +1,492 @@
+use super::*;
+
+use std::boxed::Box;
+use std::clone::Clone;
+use std::sync::mpsc::channel;
+use std::mem::drop;
+use std::ops::Drop;
+use std::option::Option::{self, None, Some};
+use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}};
+use std::thread;
+use std::sync::Mutex;
+use std::convert::{From, TryInto};
+
+use crate::vec::Vec;
+
+struct Canary(*mut atomic::AtomicUsize);
+
+impl Drop for Canary {
+    fn drop(&mut self) {
+        unsafe {
+            match *self {
+                Canary(c) => {
+                    (*c).fetch_add(1, SeqCst);
+                }
+            }
+        }
+    }
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+#[cfg(not(miri))] // Miri does not support threads
+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()), None);
+    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), Some(1));
+    let w2 = w.clone();
+    assert_eq!(Weak::strong_count(&w), 1);
+    assert_eq!(Weak::weak_count(&w), Some(2));
+    assert_eq!(Weak::strong_count(&w2), 1);
+    assert_eq!(Weak::weak_count(&w2), Some(2));
+    drop(w);
+    assert_eq!(Weak::strong_count(&w2), 1);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    let a2 = a.clone();
+    assert_eq!(Weak::strong_count(&w2), 2);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    drop(a2);
+    drop(a);
+    assert_eq!(Weak::strong_count(&w2), 0);
+    assert_eq!(Weak::weak_count(&w2), Some(1));
+    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_from_raw() {
+    let x = Arc::new(box "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 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 = atomic::AtomicUsize::new(0);
+    let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
+    drop(x);
+    assert!(canary.load(Acquire) == 1);
+}
+
+#[test]
+fn drop_arc_weak() {
+    let mut canary = atomic::AtomicUsize::new(0);
+    let arc = Arc::new(Canary(&mut canary as *mut atomic::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_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)]
+#[cfg(not(miri))] // Miri does not support threads
+fn test_weak_count_locked() {
+    let mut a = Arc::new(atomic::AtomicBool::new(false));
+    let a2 = a.clone();
+    let t = thread::spawn(move || {
+        for _i in 0..1000000 {
+            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);
+    }
+    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 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 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 ();
+    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_value());
+    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_value()));
+
+    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());
+}
diff --git a/src/liballoc/boxed_test.rs b/src/liballoc/tests.rs
index 654eabd0703..ed46ba8a1b9 100644
--- a/src/liballoc/boxed_test.rs
+++ b/src/liballoc/tests.rs
@@ -1,6 +1,7 @@
 //! Test for `boxed` mod.
 
 use core::any::Any;
+use core::convert::TryInto;
 use core::ops::Deref;
 use core::result::Result::{Err, Ok};
 use core::clone::Clone;
@@ -138,3 +139,15 @@ fn boxed_slice_from_iter() {
     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/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs
index 2759b1b1cac..cf2ad2a8e60 100644
--- a/src/liballoc/tests/arc.rs
+++ b/src/liballoc/tests/arc.rs
@@ -2,6 +2,8 @@ use std::any::Any;
 use std::sync::{Arc, Weak};
 use std::cell::RefCell;
 use std::cmp::PartialEq;
+use std::iter::TrustedLen;
+use std::mem;
 
 #[test]
 fn uninhabited() {
@@ -85,3 +87,122 @@ fn eq() {
     assert!(!(x != x));
     assert_eq!(*x.0.borrow(), 0);
 }
+
+// The test code below is identical to that in `rc.rs`.
+// For better maintainability we therefore define this type alias.
+type Rc<T> = Arc<T>;
+
+const SHARED_ITER_MAX: u16 = 100;
+
+fn assert_trusted_len<I: TrustedLen>(_: &I) {}
+
+#[test]
+fn shared_from_iter_normal() {
+    // Exercise the base implementation for non-`TrustedLen` iterators.
+    {
+        // `Filter` is never `TrustedLen` since we don't
+        // know statically how many elements will be kept:
+        let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new);
+
+        // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
+        let vec = iter.clone().collect::<Vec<_>>();
+        let rc = iter.collect::<Rc<[_]>>();
+        assert_eq!(&*vec, &*rc);
+
+        // Clone a bit and let these get dropped.
+        {
+            let _rc_2 = rc.clone();
+            let _rc_3 = rc.clone();
+            let _rc_4 = Rc::downgrade(&_rc_3);
+        }
+    } // Drop what hasn't been here.
+}
+
+#[test]
+fn shared_from_iter_trustedlen_normal() {
+    // Exercise the `TrustedLen` implementation under normal circumstances
+    // where `size_hint()` matches `(_, Some(exact_len))`.
+    {
+        let iter = (0..SHARED_ITER_MAX).map(Box::new);
+        assert_trusted_len(&iter);
+
+        // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
+        let vec = iter.clone().collect::<Vec<_>>();
+        let rc = iter.collect::<Rc<[_]>>();
+        assert_eq!(&*vec, &*rc);
+        assert_eq!(mem::size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc));
+
+        // Clone a bit and let these get dropped.
+        {
+            let _rc_2 = rc.clone();
+            let _rc_3 = rc.clone();
+            let _rc_4 = Rc::downgrade(&_rc_3);
+        }
+    } // Drop what hasn't been here.
+
+    // Try a ZST to make sure it is handled well.
+    {
+        let iter = (0..SHARED_ITER_MAX).map(|_| ());
+        let vec = iter.clone().collect::<Vec<_>>();
+        let rc = iter.collect::<Rc<[_]>>();
+        assert_eq!(&*vec, &*rc);
+        assert_eq!(0, mem::size_of_val(&*rc));
+        {
+            let _rc_2 = rc.clone();
+            let _rc_3 = rc.clone();
+            let _rc_4 = Rc::downgrade(&_rc_3);
+        }
+    }
+}
+
+#[test]
+#[should_panic = "I've almost got 99 problems."]
+fn shared_from_iter_trustedlen_panic() {
+    // Exercise the `TrustedLen` implementation when `size_hint()` matches
+    // `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
+    let iter = (0..SHARED_ITER_MAX)
+        .map(|val| {
+            match val {
+                98 => panic!("I've almost got 99 problems."),
+                _ => Box::new(val),
+            }
+        });
+    assert_trusted_len(&iter);
+    let _ = iter.collect::<Rc<[_]>>();
+
+    panic!("I am unreachable.");
+}
+
+#[test]
+fn shared_from_iter_trustedlen_no_fuse() {
+    // Exercise the `TrustedLen` implementation when `size_hint()` matches
+    // `(_, Some(exact_len))` but where the iterator does not behave in a fused manner.
+    struct Iter(std::vec::IntoIter<Option<Box<u8>>>);
+
+    unsafe impl TrustedLen for Iter {}
+
+    impl Iterator for Iter {
+        fn size_hint(&self) -> (usize, Option<usize>) {
+            (2, Some(2))
+        }
+
+        type Item = Box<u8>;
+
+        fn next(&mut self) -> Option<Self::Item> {
+            self.0.next().flatten()
+        }
+    }
+
+    let vec = vec![
+        Some(Box::new(42)),
+        Some(Box::new(24)),
+        None,
+        Some(Box::new(12)),
+    ];
+    let iter = Iter(vec.into_iter());
+    assert_trusted_len(&iter);
+    assert_eq!(
+        &[Box::new(42), Box::new(24)],
+        &*iter.collect::<Rc<[_]>>()
+    );
+}
diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs
index 844afe87076..266a0d055d5 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -689,7 +689,10 @@ fn test_split_off_empty_left() {
 
 #[test]
 fn test_split_off_large_random_sorted() {
+    #[cfg(not(miri))] // Miri is too slow
     let mut data = rand_data(1529);
+    #[cfg(miri)]
+    let mut data = rand_data(529);
     // special case with maximum height.
     data.sort();
 
diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs
index d52814118b3..62ccb53fcea 100644
--- a/src/liballoc/tests/btree/set.rs
+++ b/src/liballoc/tests/btree/set.rs
@@ -10,7 +10,7 @@ fn test_clone_eq() {
     m.insert(1);
     m.insert(2);
 
-    assert!(m.clone() == m);
+    assert_eq!(m.clone(), m);
 }
 
 #[test]
@@ -28,7 +28,7 @@ fn test_hash() {
     y.insert(2);
     y.insert(1);
 
-    assert!(hash(&x) == hash(&y));
+    assert_eq!(hash(&x), hash(&y));
 }
 
 fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
@@ -69,6 +69,11 @@ fn test_intersection() {
     check_intersection(&[11, 1, 3, 77, 103, 5, -5],
                        &[2, 11, 77, -9, -42, 5, 3],
                        &[3, 5, 11, 77]);
+
+    if cfg!(miri) { // Miri is too slow
+        return;
+    }
+
     let large = (0..1000).collect::<Vec<_>>();
     check_intersection(&[], &large, &[]);
     check_intersection(&large, &[], &[]);
@@ -98,6 +103,11 @@ fn test_difference() {
     check_difference(&[-5, 11, 22, 33, 40, 42],
                      &[-12, -5, 14, 23, 34, 38, 39, 50],
                      &[11, 22, 33, 40, 42]);
+
+    if cfg!(miri) { // Miri is too slow
+        return;
+    }
+
     let large = (0..1000).collect::<Vec<_>>();
     check_difference(&[], &large, &[]);
     check_difference(&[-1], &large, &[-1]);
@@ -143,8 +153,8 @@ fn test_union() {
 #[test]
 // Only tests the simple function definition with respect to intersection
 fn test_is_disjoint() {
-    let one = [1].into_iter().collect::<BTreeSet<_>>();
-    let two = [2].into_iter().collect::<BTreeSet<_>>();
+    let one = [1].iter().collect::<BTreeSet<_>>();
+    let two = [2].iter().collect::<BTreeSet<_>>();
     assert!(one.is_disjoint(&two));
 }
 
@@ -166,6 +176,17 @@ fn test_is_subset() {
     assert_eq!(is_subset(&[1, 2], &[1]), false);
     assert_eq!(is_subset(&[1, 2], &[1, 2]), true);
     assert_eq!(is_subset(&[1, 2], &[2, 3]), false);
+    assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42],
+                         &[-12, -5, 14, 23, 11, 34, 22, 38, 33, 42, 39, 40]),
+               true);
+    assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42],
+                         &[-12, -5, 14, 23, 34, 38, 22, 11]),
+               false);
+
+    if cfg!(miri) { // Miri is too slow
+        return;
+    }
+
     let large = (0..1000).collect::<Vec<_>>();
     assert_eq!(is_subset(&[], &large), true);
     assert_eq!(is_subset(&large, &[]), false);
@@ -371,7 +392,10 @@ fn test_split_off_empty_left() {
 
 #[test]
 fn test_split_off_large_random_sorted() {
+    #[cfg(not(miri))] // Miri is too slow
     let mut data = rand_data(1529);
+    #[cfg(miri)]
+    let mut data = rand_data(529);
     // special case with maximum height.
     data.sort();
 
diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs
index c225ebfa96b..904b3e7e1b0 100644
--- a/src/liballoc/tests/heap.rs
+++ b/src/liballoc/tests/heap.rs
@@ -1,6 +1,6 @@
 use std::alloc::{Global, Alloc, Layout, System};
 
-/// Issue #45955.
+/// Issue #45955 and #62251.
 #[test]
 fn alloc_system_overaligned_request() {
     check_overalign_requests(System)
@@ -12,21 +12,23 @@ fn std_heap_overaligned_request() {
 }
 
 fn check_overalign_requests<T: Alloc>(mut allocator: T) {
-    let size = 8;
-    let align = 16; // greater than size
-    let iterations = 100;
-    unsafe {
-        let pointers: Vec<_> = (0..iterations).map(|_| {
-            allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
-        }).collect();
-        for &ptr in &pointers {
-            assert_eq!((ptr.as_ptr() as usize) % align, 0,
-                       "Got a pointer less aligned than requested")
-        }
+    for &align in &[4, 8, 16, 32] { // less than and bigger than `MIN_ALIGN`
+        for &size in &[align/2, align-1] { // size less than alignment
+            let iterations = 128;
+            unsafe {
+                let pointers: Vec<_> = (0..iterations).map(|_| {
+                    allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
+                }).collect();
+                for &ptr in &pointers {
+                    assert_eq!((ptr.as_ptr() as usize) % align, 0,
+                               "Got a pointer less aligned than requested")
+                }
 
-        // Clean up
-        for &ptr in &pointers {
-            allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap())
+                // Clean up
+                for &ptr in &pointers {
+                    allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap())
+                }
+            }
         }
     }
 }
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index b736750c576..5723a30c0f3 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -2,12 +2,13 @@
 #![feature(box_syntax)]
 #![feature(drain_filter)]
 #![feature(exact_size_is_empty)]
+#![feature(option_flattening)]
 #![feature(pattern)]
 #![feature(repeat_generic_slice)]
+#![feature(trusted_len)]
 #![feature(try_reserve)]
 #![feature(unboxed_closures)]
-#![feature(vecdeque_rotate)]
-#![deny(rust_2018_idioms)]
+#![feature(associated_type_bounds)]
 
 use std::hash::{Hash, Hasher};
 use std::collections::hash_map::DefaultHasher;
diff --git a/src/liballoc/tests/linked_list.rs b/src/liballoc/tests/linked_list.rs
index 0fbfbdccd45..8a26454c389 100644
--- a/src/liballoc/tests/linked_list.rs
+++ b/src/liballoc/tests/linked_list.rs
@@ -40,12 +40,10 @@ fn test_basic() {
     assert_eq!(n.pop_front(), Some(1));
 }
 
-#[cfg(test)]
 fn generate_test() -> LinkedList<i32> {
     list_from(&[0, 1, 2, 3, 4, 5, 6])
 }
 
-#[cfg(test)]
 fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
     v.iter().cloned().collect()
 }
diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs
index 18f82e80410..7854ca0fc16 100644
--- a/src/liballoc/tests/rc.rs
+++ b/src/liballoc/tests/rc.rs
@@ -2,6 +2,8 @@ use std::any::Any;
 use std::rc::{Rc, Weak};
 use std::cell::RefCell;
 use std::cmp::PartialEq;
+use std::mem;
+use std::iter::TrustedLen;
 
 #[test]
 fn uninhabited() {
@@ -85,3 +87,118 @@ fn eq() {
     assert!(!(x != x));
     assert_eq!(*x.0.borrow(), 0);
 }
+
+const SHARED_ITER_MAX: u16 = 100;
+
+fn assert_trusted_len<I: TrustedLen>(_: &I) {}
+
+#[test]
+fn shared_from_iter_normal() {
+    // Exercise the base implementation for non-`TrustedLen` iterators.
+    {
+        // `Filter` is never `TrustedLen` since we don't
+        // know statically how many elements will be kept:
+        let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new);
+
+        // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
+        let vec = iter.clone().collect::<Vec<_>>();
+        let rc = iter.collect::<Rc<[_]>>();
+        assert_eq!(&*vec, &*rc);
+
+        // Clone a bit and let these get dropped.
+        {
+            let _rc_2 = rc.clone();
+            let _rc_3 = rc.clone();
+            let _rc_4 = Rc::downgrade(&_rc_3);
+        }
+    } // Drop what hasn't been here.
+}
+
+#[test]
+fn shared_from_iter_trustedlen_normal() {
+    // Exercise the `TrustedLen` implementation under normal circumstances
+    // where `size_hint()` matches `(_, Some(exact_len))`.
+    {
+        let iter = (0..SHARED_ITER_MAX).map(Box::new);
+        assert_trusted_len(&iter);
+
+        // Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
+        let vec = iter.clone().collect::<Vec<_>>();
+        let rc = iter.collect::<Rc<[_]>>();
+        assert_eq!(&*vec, &*rc);
+        assert_eq!(mem::size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc));
+
+        // Clone a bit and let these get dropped.
+        {
+            let _rc_2 = rc.clone();
+            let _rc_3 = rc.clone();
+            let _rc_4 = Rc::downgrade(&_rc_3);
+        }
+    } // Drop what hasn't been here.
+
+    // Try a ZST to make sure it is handled well.
+    {
+        let iter = (0..SHARED_ITER_MAX).map(|_| ());
+        let vec = iter.clone().collect::<Vec<_>>();
+        let rc = iter.collect::<Rc<[_]>>();
+        assert_eq!(&*vec, &*rc);
+        assert_eq!(0, mem::size_of_val(&*rc));
+        {
+            let _rc_2 = rc.clone();
+            let _rc_3 = rc.clone();
+            let _rc_4 = Rc::downgrade(&_rc_3);
+        }
+    }
+}
+
+#[test]
+#[should_panic = "I've almost got 99 problems."]
+fn shared_from_iter_trustedlen_panic() {
+    // Exercise the `TrustedLen` implementation when `size_hint()` matches
+    // `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
+    let iter = (0..SHARED_ITER_MAX)
+        .map(|val| {
+            match val {
+                98 => panic!("I've almost got 99 problems."),
+                _ => Box::new(val),
+            }
+        });
+    assert_trusted_len(&iter);
+    let _ = iter.collect::<Rc<[_]>>();
+
+    panic!("I am unreachable.");
+}
+
+#[test]
+fn shared_from_iter_trustedlen_no_fuse() {
+    // Exercise the `TrustedLen` implementation when `size_hint()` matches
+    // `(_, Some(exact_len))` but where the iterator does not behave in a fused manner.
+    struct Iter(std::vec::IntoIter<Option<Box<u8>>>);
+
+    unsafe impl TrustedLen for Iter {}
+
+    impl Iterator for Iter {
+        fn size_hint(&self) -> (usize, Option<usize>) {
+            (2, Some(2))
+        }
+
+        type Item = Box<u8>;
+
+        fn next(&mut self) -> Option<Self::Item> {
+            self.0.next().flatten()
+        }
+    }
+
+    let vec = vec![
+        Some(Box::new(42)),
+        Some(Box::new(24)),
+        None,
+        Some(Box::new(12)),
+    ];
+    let iter = Iter(vec.into_iter());
+    assert_trusted_len(&iter);
+    assert_eq!(
+        &[Box::new(42), Box::new(24)],
+        &*iter.collect::<Rc<[_]>>()
+    );
+}
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index b197516403f..4332b2e90fd 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -1109,6 +1109,16 @@ fn test_iterator_last() {
 }
 
 #[test]
+fn test_chars_debug() {
+    let s = "ศไทย中华Việt Nam";
+    let c = s.chars();
+    assert_eq!(
+        format!("{:?}", c),
+        r#"Chars(['ศ', 'ไ', 'ท', 'ย', '中', '华', 'V', 'i', 'ệ', 't', ' ', 'N', 'a', 'm'])"#
+    );
+}
+
+#[test]
 fn test_bytesator() {
     let s = "ศไทย中华Việt Nam";
     let v = [
@@ -1628,10 +1638,12 @@ mod pattern {
         }
     }
 
-    fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
-                                             right: Vec<SearchStep>)
-    where P::Searcher: ReverseSearcher<'a>
-    {
+    fn cmp_search_to_vec<'a>(
+        rev: bool,
+        pat: impl Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        haystack: &'a str,
+        right: Vec<SearchStep>
+    ) {
         let mut searcher = pat.into_searcher(haystack);
         let mut v = vec![];
         loop {
diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs
index 765210e5aa6..55edf56345b 100644
--- a/src/liballoc/tests/string.rs
+++ b/src/liballoc/tests/string.rs
@@ -1,5 +1,5 @@
 use std::borrow::Cow;
-use std::collections::CollectionAllocErr::*;
+use std::collections::TryReserveError::*;
 use std::mem::size_of;
 use std::{usize, isize};
 
@@ -566,11 +566,11 @@ fn test_try_reserve() {
             } else { panic!("usize::MAX should trigger an overflow!") }
         } else {
             // Check isize::MAX + 1 is an OOM
-            if let Err(AllocErr) = empty_string.try_reserve(MAX_CAP + 1) {
+            if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
 
             // Check usize::MAX is an OOM
-            if let Err(AllocErr) = empty_string.try_reserve(MAX_USIZE) {
+            if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an OOM!") }
         }
     }
@@ -590,7 +590,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should always overflow in the add-to-len
@@ -629,10 +629,10 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an overflow!") }
         } else {
-            if let Err(AllocErr) = empty_string.try_reserve_exact(MAX_CAP + 1) {
+            if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
 
-            if let Err(AllocErr) = empty_string.try_reserve_exact(MAX_USIZE) {
+            if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an OOM!") }
         }
     }
@@ -651,7 +651,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 545332bcd6a..29a22aa0315 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -1,10 +1,8 @@
-#![cfg(not(miri))]
-
 use std::borrow::Cow;
 use std::mem::size_of;
 use std::{usize, isize};
 use std::vec::{Drain, IntoIter};
-use std::collections::CollectionAllocErr::*;
+use std::collections::TryReserveError::*;
 
 struct DropCounter<'a> {
     count: &'a mut u32,
@@ -947,6 +945,115 @@ fn drain_filter_complex() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri does not support catching panics
+fn drain_filter_consumed_panic() {
+    use std::rc::Rc;
+    use std::sync::Mutex;
+
+    struct Check {
+        index: usize,
+        drop_counts: Rc<Mutex<Vec<usize>>>,
+    };
+
+    impl Drop for Check {
+        fn drop(&mut self) {
+            self.drop_counts.lock().unwrap()[self.index] += 1;
+            println!("drop: {}", self.index);
+        }
+    }
+
+    let check_count = 10;
+    let drop_counts = Rc::new(Mutex::new(vec![0_usize; check_count]));
+    let mut data: Vec<Check> = (0..check_count)
+        .map(|index| Check { index, drop_counts: Rc::clone(&drop_counts) })
+        .collect();
+
+    let _ = std::panic::catch_unwind(move || {
+        let filter = |c: &mut Check| {
+            if c.index == 2 {
+                panic!("panic at index: {}", c.index);
+            }
+            // Verify that if the filter could panic again on another element
+            // that it would not cause a double panic and all elements of the
+            // vec would still be dropped exactly once.
+            if c.index == 4 {
+                panic!("panic at index: {}", c.index);
+            }
+            c.index < 6
+        };
+        let drain = data.drain_filter(filter);
+
+        // NOTE: The DrainFilter is explictly consumed
+        drain.for_each(drop);
+    });
+
+    let drop_counts = drop_counts.lock().unwrap();
+    assert_eq!(check_count, drop_counts.len());
+
+    for (index, count) in drop_counts.iter().cloned().enumerate() {
+        assert_eq!(1, count, "unexpected drop count at index: {} (count: {})", index, count);
+    }
+}
+
+#[test]
+#[cfg(not(miri))] // Miri does not support catching panics
+fn drain_filter_unconsumed_panic() {
+    use std::rc::Rc;
+    use std::sync::Mutex;
+
+    struct Check {
+        index: usize,
+        drop_counts: Rc<Mutex<Vec<usize>>>,
+    };
+
+    impl Drop for Check {
+        fn drop(&mut self) {
+            self.drop_counts.lock().unwrap()[self.index] += 1;
+            println!("drop: {}", self.index);
+        }
+    }
+
+    let check_count = 10;
+    let drop_counts = Rc::new(Mutex::new(vec![0_usize; check_count]));
+    let mut data: Vec<Check> = (0..check_count)
+        .map(|index| Check { index, drop_counts: Rc::clone(&drop_counts) })
+        .collect();
+
+    let _ = std::panic::catch_unwind(move || {
+        let filter = |c: &mut Check| {
+            if c.index == 2 {
+                panic!("panic at index: {}", c.index);
+            }
+            // Verify that if the filter could panic again on another element
+            // that it would not cause a double panic and all elements of the
+            // vec would still be dropped exactly once.
+            if c.index == 4 {
+                panic!("panic at index: {}", c.index);
+            }
+            c.index < 6
+        };
+        let _drain = data.drain_filter(filter);
+
+        // NOTE: The DrainFilter is dropped without being consumed
+    });
+
+    let drop_counts = drop_counts.lock().unwrap();
+    assert_eq!(check_count, drop_counts.len());
+
+    for (index, count) in drop_counts.iter().cloned().enumerate() {
+        assert_eq!(1, count, "unexpected drop count at index: {} (count: {})", index, count);
+    }
+}
+
+#[test]
+fn drain_filter_unconsumed() {
+    let mut vec = vec![1, 2, 3, 4];
+    let drain = vec.drain_filter(|&mut x| x % 2 != 0);
+    drop(drain);
+    assert_eq!(vec, [2, 4]);
+}
+
+#[test]
 fn test_reserve_exact() {
     // This is all the same as test_reserve
 
@@ -971,6 +1078,7 @@ fn test_reserve_exact() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri does not support signalling OOM
 fn test_try_reserve() {
 
     // These are the interesting cases:
@@ -1013,11 +1121,11 @@ fn test_try_reserve() {
             } else { panic!("usize::MAX should trigger an overflow!") }
         } else {
             // Check isize::MAX + 1 is an OOM
-            if let Err(AllocErr) = empty_bytes.try_reserve(MAX_CAP + 1) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_CAP + 1) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
 
             // Check usize::MAX is an OOM
-            if let Err(AllocErr) = empty_bytes.try_reserve(MAX_USIZE) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an OOM!") }
         }
     }
@@ -1037,7 +1145,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should always overflow in the add-to-len
@@ -1060,7 +1168,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
+            if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should fail in the mul-by-size
@@ -1073,6 +1181,7 @@ fn test_try_reserve() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri does not support signalling OOM
 fn test_try_reserve_exact() {
 
     // This is exactly the same as test_try_reserve with the method changed.
@@ -1100,10 +1209,10 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an overflow!") }
         } else {
-            if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
 
-            if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_USIZE) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an OOM!") }
         }
     }
@@ -1122,7 +1231,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
@@ -1143,7 +1252,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
+            if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
@@ -1151,3 +1260,24 @@ fn test_try_reserve_exact() {
     }
 
 }
+
+#[test]
+fn test_stable_push_pop() {
+    // Test that, if we reserved enough space, adding and removing elements does not
+    // invalidate references into the vector (such as `v0`).  This test also
+    // runs in Miri, which would detect such problems.
+    let mut v = Vec::with_capacity(10);
+    v.push(13);
+
+    // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
+    let v0 = unsafe { &*(&v[0] as *const _) };
+
+    // Now do a bunch of things and occasionally use `v0` again to assert it is still valid.
+    v.push(1);
+    v.push(2);
+    v.insert(1, 1);
+    assert_eq!(*v0, 13);
+    v.remove(1);
+    v.pop().unwrap();
+    assert_eq!(*v0, 13);
+}
diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs
index e0fe10a55f5..d49b553fc02 100644
--- a/src/liballoc/tests/vec_deque.rs
+++ b/src/liballoc/tests/vec_deque.rs
@@ -1,6 +1,6 @@
 use std::fmt::Debug;
 use std::collections::{VecDeque, vec_deque::Drain};
-use std::collections::CollectionAllocErr::*;
+use std::collections::TryReserveError::*;
 use std::mem::size_of;
 use std::{usize, isize};
 
@@ -44,7 +44,6 @@ fn test_simple() {
     assert_eq!(d[3], 4);
 }
 
-#[cfg(test)]
 fn test_parameterized<T: Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
     let mut deq = VecDeque::new();
     assert_eq!(deq.len(), 0);
@@ -1169,7 +1168,7 @@ fn test_try_reserve() {
             // VecDeque starts with capacity 7, always adds 1 to the capacity
             // and also rounds the number to next power of 2 so this is the
             // furthest we can go without triggering CapacityOverflow
-            if let Err(AllocErr) = empty_bytes.try_reserve(MAX_CAP) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_CAP) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
     }
@@ -1189,7 +1188,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should always overflow in the add-to-len
@@ -1212,7 +1211,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
+            if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should fail in the mul-by-size
@@ -1257,7 +1256,7 @@ fn test_try_reserve_exact() {
             // VecDeque starts with capacity 7, always adds 1 to the capacity
             // and also rounds the number to next power of 2 so this is the
             // furthest we can go without triggering CapacityOverflow
-            if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_CAP) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_CAP) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
     }
@@ -1276,7 +1275,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
@@ -1297,7 +1296,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
+            if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index c0cdffe596b..d2798955c46 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -56,6 +56,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use core::array::LengthAtMost32;
 use core::cmp::{self, Ordering};
 use core::fmt;
 use core::hash::{self, Hash};
@@ -69,7 +70,7 @@ use core::ptr::{self, NonNull};
 use core::slice::{self, SliceIndex};
 
 use crate::borrow::{ToOwned, Cow};
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::boxed::Box;
 use crate::raw_vec::RawVec;
 
@@ -432,7 +433,7 @@ impl<T> Vec<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn capacity(&self) -> usize {
-        self.buf.cap()
+        self.buf.capacity()
     }
 
     /// Reserves capacity for at least `additional` more elements to be inserted
@@ -497,9 +498,9 @@ impl<T> Vec<T> {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     ///
-    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, CollectionAllocErr> {
+    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
     ///     let mut output = Vec::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -515,7 +516,7 @@ impl<T> Vec<T> {
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.buf.try_reserve(self.len, additional)
     }
 
@@ -537,9 +538,9 @@ impl<T> Vec<T> {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     ///
-    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, CollectionAllocErr> {
+    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
     ///     let mut output = Vec::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -555,7 +556,7 @@ impl<T> Vec<T> {
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr>  {
+    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError>  {
         self.buf.try_reserve_exact(self.len, additional)
     }
 
@@ -735,6 +736,75 @@ impl<T> Vec<T> {
         self
     }
 
+    /// Returns a raw pointer to the vector's buffer.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    /// Modifying the vector may cause its buffer to be reallocated,
+    /// which would also make any pointers to it invalid.
+    ///
+    /// The caller must also ensure that the memory the pointer (non-transitively) points to
+    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
+    /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x = vec![1, 2, 4];
+    /// let x_ptr = x.as_ptr();
+    ///
+    /// unsafe {
+    ///     for i in 0..x.len() {
+    ///         assert_eq!(*x_ptr.add(i), 1 << i);
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// [`as_mut_ptr`]: #method.as_mut_ptr
+    #[stable(feature = "vec_as_ptr", since = "1.37.0")]
+    #[inline]
+    pub fn as_ptr(&self) -> *const T {
+        // We shadow the slice method of the same name to avoid going through
+        // `deref`, which creates an intermediate reference.
+        let ptr = self.buf.ptr();
+        unsafe { assume(!ptr.is_null()); }
+        ptr
+    }
+
+    /// Returns an unsafe mutable pointer to the vector's buffer.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    /// Modifying the vector may cause its buffer to be reallocated,
+    /// which would also make any pointers to it invalid.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// // Allocate vector big enough for 4 elements.
+    /// let size = 4;
+    /// let mut x: Vec<i32> = Vec::with_capacity(size);
+    /// let x_ptr = x.as_mut_ptr();
+    ///
+    /// // Initialize elements via raw pointer writes, then set length.
+    /// unsafe {
+    ///     for i in 0..size {
+    ///         *x_ptr.add(i) = i as i32;
+    ///     }
+    ///     x.set_len(size);
+    /// }
+    /// assert_eq!(&*x, &[0,1,2,3]);
+    /// ```
+    #[stable(feature = "vec_as_ptr", since = "1.37.0")]
+    #[inline]
+    pub fn as_mut_ptr(&mut self) -> *mut T {
+        // We shadow the slice method of the same name to avoid going through
+        // `deref_mut`, which creates an intermediate reference.
+        let ptr = self.buf.ptr();
+        unsafe { assume(!ptr.is_null()); }
+        ptr
+    }
+
     /// Forces the length of the vector to `new_len`.
     ///
     /// This is a low-level operation that maintains none of the normal
@@ -878,7 +948,7 @@ impl<T> Vec<T> {
         assert!(index <= len);
 
         // space for the new element
-        if len == self.buf.cap() {
+        if len == self.buf.capacity() {
             self.reserve(1);
         }
 
@@ -1029,7 +1099,7 @@ impl<T> Vec<T> {
     pub fn push(&mut self, value: T) {
         // This will panic or abort if we would allocate > isize::MAX bytes
         // or if the length increment would overflow for zero-sized types.
-        if self.len == self.buf.cap() {
+        if self.len == self.buf.capacity() {
             self.reserve(1);
         }
         unsafe {
@@ -1094,7 +1164,7 @@ impl<T> Vec<T> {
         let count = (*other).len();
         self.reserve(count);
         let len = self.len();
-        ptr::copy_nonoverlapping(other as *const T, self.get_unchecked_mut(len), count);
+        ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count);
         self.len += count;
     }
 
@@ -1298,6 +1368,40 @@ impl<T> Vec<T> {
             self.truncate(new_len);
         }
     }
+
+    /// Consumes and leaks the `Vec`, returning a mutable reference to the contents,
+    /// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime
+    /// `'a`. If the type has only static references, or none at all, then this
+    /// may be chosen to be `'static`.
+    ///
+    /// This function is similar to the `leak` function on `Box`.
+    ///
+    /// This function is mainly useful for data that lives for the remainder of
+    /// the program's life. Dropping the returned reference will cause a memory
+    /// leak.
+    ///
+    /// # Examples
+    ///
+    /// Simple usage:
+    ///
+    /// ```
+    /// #![feature(vec_leak)]
+    ///
+    /// fn main() {
+    ///     let x = vec![1, 2, 3];
+    ///     let static_ref: &'static mut [usize] = Vec::leak(x);
+    ///     static_ref[0] += 1;
+    ///     assert_eq!(static_ref, &[2, 2, 3]);
+    /// }
+    /// ```
+    #[unstable(feature = "vec_leak", issue = "62195")]
+    #[inline]
+    pub fn leak<'a>(vec: Vec<T>) -> &'a mut [T]
+    where
+        T: 'a // Technically not needed, but kept to be explicit.
+    {
+        Box::leak(vec.into_boxed_slice())
+    }
 }
 
 impl<T: Clone> Vec<T> {
@@ -1706,9 +1810,7 @@ impl<T> ops::Deref for Vec<T> {
 
     fn deref(&self) -> &[T] {
         unsafe {
-            let p = self.buf.ptr();
-            assume(!p.is_null());
-            slice::from_raw_parts(p, self.len)
+            slice::from_raw_parts(self.as_ptr(), self.len)
         }
     }
 }
@@ -1717,9 +1819,7 @@ impl<T> ops::Deref for Vec<T> {
 impl<T> ops::DerefMut for Vec<T> {
     fn deref_mut(&mut self) -> &mut [T] {
         unsafe {
-            let ptr = self.buf.ptr();
-            assume(!ptr.is_null());
-            slice::from_raw_parts_mut(ptr, self.len)
+            slice::from_raw_parts_mut(self.as_mut_ptr(), self.len)
         }
     }
 }
@@ -1754,13 +1854,12 @@ impl<T> IntoIterator for Vec<T> {
     fn into_iter(mut self) -> IntoIter<T> {
         unsafe {
             let begin = self.as_mut_ptr();
-            assume(!begin.is_null());
             let end = if mem::size_of::<T>() == 0 {
                 arith_offset(begin as *const i8, self.len() as isize) as *const T
             } else {
                 begin.add(self.len()) as *const T
             };
-            let cap = self.buf.cap();
+            let cap = self.buf.capacity();
             mem::forget(self);
             IntoIter {
                 buf: NonNull::new_unchecked(begin),
@@ -1954,16 +2053,14 @@ impl<T> Vec<T> {
     /// with the given `replace_with` iterator and yields the removed items.
     /// `replace_with` does not need to be the same length as `range`.
     ///
-    /// Note 1: The element range is removed even if the iterator is not
-    /// consumed until the end.
+    /// The element range is removed even if the iterator is not consumed until the end.
     ///
-    /// Note 2: It is unspecified how many elements are removed from the vector,
+    /// It is unspecified how many elements are removed from the vector
     /// if the `Splice` value is leaked.
     ///
-    /// Note 3: The input iterator `replace_with` is only consumed
-    /// when the `Splice` value is dropped.
+    /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped.
     ///
-    /// Note 4: This is optimal if:
+    /// This is optimal if:
     ///
     /// * The tail (elements in the vector after `range`) is empty,
     /// * or `replace_with` yields fewer elements than `range`’s length
@@ -2056,6 +2153,7 @@ impl<T> Vec<T> {
             del: 0,
             old_len,
             pred: filter,
+            panic_flag: false,
         }
     }
 }
@@ -2074,47 +2172,36 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for Vec<T> {
 }
 
 macro_rules! __impl_slice_eq1 {
-    ($Lhs: ty, $Rhs: ty) => {
-        __impl_slice_eq1! { $Lhs, $Rhs, Sized }
-    };
-    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
+    ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => {
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
+        impl<A, B, $($vars)*> PartialEq<$rhs> for $lhs
+        where
+            A: PartialEq<B>,
+            $($constraints)*
+        {
             #[inline]
-            fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] }
+            fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] }
             #[inline]
-            fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] }
+            fn ne(&self, other: &$rhs) -> bool { self[..] != other[..] }
         }
     }
 }
 
-__impl_slice_eq1! { Vec<A>, Vec<B> }
-__impl_slice_eq1! { Vec<A>, &'b [B] }
-__impl_slice_eq1! { Vec<A>, &'b mut [B] }
-__impl_slice_eq1! { Cow<'a, [A]>, &'b [B], Clone }
-__impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B], Clone }
-__impl_slice_eq1! { Cow<'a, [A]>, Vec<B>, Clone }
+__impl_slice_eq1! { [] Vec<A>, Vec<B>, }
+__impl_slice_eq1! { [] Vec<A>, &[B], }
+__impl_slice_eq1! { [] Vec<A>, &mut [B], }
+__impl_slice_eq1! { [] Cow<'_, [A]>, &[B], A: Clone }
+__impl_slice_eq1! { [] Cow<'_, [A]>, &mut [B], A: Clone }
+__impl_slice_eq1! { [] Cow<'_, [A]>, Vec<B>, A: Clone }
+__impl_slice_eq1! { [const N: usize] Vec<A>, [B; N], [B; N]: LengthAtMost32 }
+__impl_slice_eq1! { [const N: usize] Vec<A>, &[B; N], [B; N]: LengthAtMost32 }
 
-macro_rules! array_impls {
-    ($($N: expr)+) => {
-        $(
-            // NOTE: some less important impls are omitted to reduce code bloat
-            __impl_slice_eq1! { Vec<A>, [B; $N] }
-            __impl_slice_eq1! { Vec<A>, &'b [B; $N] }
-            // __impl_slice_eq1! { Vec<A>, &'b mut [B; $N] }
-            // __impl_slice_eq1! { Cow<'a, [A]>, [B; $N], Clone }
-            // __impl_slice_eq1! { Cow<'a, [A]>, &'b [B; $N], Clone }
-            // __impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B; $N], Clone }
-        )+
-    }
-}
-
-array_impls! {
-     0  1  2  3  4  5  6  7  8  9
-    10 11 12 13 14 15 16 17 18 19
-    20 21 22 23 24 25 26 27 28 29
-    30 31 32
-}
+// NOTE: some less important impls are omitted to reduce code bloat
+// FIXME(Centril): Reconsider this?
+//__impl_slice_eq1! { [const N: usize] Vec<A>, &mut [B; N], [B; N]: LengthAtMost32 }
+//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, [B; N], [B; N]: LengthAtMost32 }
+//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &[B; N], [B; N]: LengthAtMost32 }
+//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &mut [B; N], [B; N]: LengthAtMost32 }
 
 /// Implements comparison of vectors, lexicographically.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2395,11 +2482,6 @@ impl<T> Iterator for IntoIter<T> {
     fn count(self) -> usize {
         self.len()
     }
-
-    #[inline]
-    fn last(mut self) -> Option<T> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2519,11 +2601,6 @@ impl<T> Iterator for Drain<'_, T> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
-
-    #[inline]
-    fn last(mut self) -> Option<T> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
@@ -2593,10 +2670,6 @@ impl<I: Iterator> Iterator for Splice<'_, I> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.drain.size_hint()
     }
-
-    fn last(mut self) -> Option<Self::Item> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "vec_splice", since = "1.21.0")]
@@ -2697,10 +2770,20 @@ pub struct DrainFilter<'a, T, F>
     where F: FnMut(&mut T) -> bool,
 {
     vec: &'a mut Vec<T>,
+    /// The index of the item that will be inspected by the next call to `next`.
     idx: usize,
+    /// The number of items that have been drained (removed) thus far.
     del: usize,
+    /// The original length of `vec` prior to draining.
     old_len: usize,
+    /// The filter test predicate.
     pred: F,
+    /// A flag that indicates a panic has occured in the filter test prodicate.
+    /// This is used as a hint in the drop implmentation to prevent consumption
+    /// of the remainder of the `DrainFilter`. Any unprocessed items will be
+    /// backshifted in the `vec`, but no further items will be dropped or
+    /// tested by the filter predicate.
+    panic_flag: bool,
 }
 
 #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
@@ -2711,20 +2794,23 @@ impl<T, F> Iterator for DrainFilter<'_, T, F>
 
     fn next(&mut self) -> Option<T> {
         unsafe {
-            while self.idx != self.old_len {
+            while self.idx < self.old_len {
                 let i = self.idx;
-                self.idx += 1;
                 let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len);
-                if (self.pred)(&mut v[i]) {
+                self.panic_flag = true;
+                let drained = (self.pred)(&mut v[i]);
+                self.panic_flag = false;
+                // Update the index *after* the predicate is called. If the index
+                // is updated prior and the predicate panics, the element at this
+                // index would be leaked.
+                self.idx += 1;
+                if drained {
                     self.del += 1;
                     return Some(ptr::read(&v[i]));
                 } else if self.del > 0 {
                     let del = self.del;
                     let src: *const T = &v[i];
                     let dst: *mut T = &mut v[i - del];
-                    // This is safe because self.vec has length 0
-                    // thus its elements will not have Drop::drop
-                    // called on them in the event of a panic.
                     ptr::copy_nonoverlapping(src, dst, 1);
                 }
             }
@@ -2742,9 +2828,46 @@ impl<T, F> Drop for DrainFilter<'_, T, F>
     where F: FnMut(&mut T) -> bool,
 {
     fn drop(&mut self) {
-        self.for_each(drop);
-        unsafe {
-            self.vec.set_len(self.old_len - self.del);
+        struct BackshiftOnDrop<'a, 'b, T, F>
+            where
+                F: FnMut(&mut T) -> bool,
+        {
+            drain: &'b mut DrainFilter<'a, T, F>,
+        }
+
+        impl<'a, 'b, T, F> Drop for BackshiftOnDrop<'a, 'b, T, F>
+            where
+                F: FnMut(&mut T) -> bool
+        {
+            fn drop(&mut self) {
+                unsafe {
+                    if self.drain.idx < self.drain.old_len && self.drain.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.drain.vec.as_mut_ptr();
+                        let src = ptr.add(self.drain.idx);
+                        let dst = src.sub(self.drain.del);
+                        let tail_len = self.drain.old_len - self.drain.idx;
+                        src.copy_to(dst, tail_len);
+                    }
+                    self.drain.vec.set_len(self.drain.old_len - self.drain.del);
+                }
+            }
+        }
+
+        let backshift = BackshiftOnDrop {
+            drain: self
+        };
+
+        // Attempt to consume any remaining elements if the filter predicate
+        // has not yet panicked. We'll backshift any remaining elements
+        // whether we've already panicked or if the consumption here panics.
+        if !backshift.drain.panic_flag {
+            backshift.drain.for_each(drop);
         }
     }
 }