about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorStein Somers <git@steinsomers.be>2019-02-18 00:31:41 +0100
committerStein Somers <git@steinsomers.be>2019-02-18 00:31:41 +0100
commit01bebdf19321a1597f35c2fc2130f1627e944bcf (patch)
tree2c71bc6a77545eacabdc67b1fcaa5f52dd22878c /src/liballoc
parent0b9ad6e6fd017837647eed8e5ae824d1f6e278b2 (diff)
parent9a3392e174a432a5f06c1157befc1ce0fae74bec (diff)
downloadrust-01bebdf19321a1597f35c2fc2130f1627e944bcf.tar.gz
rust-01bebdf19321a1597f35c2fc2130f1627e944bcf.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/benches/lib.rs1
-rw-r--r--src/liballoc/borrow.rs4
-rw-r--r--src/liballoc/boxed.rs17
-rw-r--r--src/liballoc/collections/binary_heap.rs13
-rw-r--r--src/liballoc/collections/btree/map.rs2
-rw-r--r--src/liballoc/collections/btree/node.rs14
-rw-r--r--src/liballoc/collections/btree/set.rs4
-rw-r--r--src/liballoc/collections/vec_deque.rs12
-rw-r--r--src/liballoc/fmt.rs6
-rw-r--r--src/liballoc/lib.rs13
-rw-r--r--src/liballoc/macros.rs11
-rw-r--r--src/liballoc/raw_vec.rs4
-rw-r--r--src/liballoc/rc.rs10
-rw-r--r--src/liballoc/slice.rs13
-rw-r--r--src/liballoc/str.rs42
-rw-r--r--src/liballoc/string.rs6
-rw-r--r--src/liballoc/sync.rs8
-rw-r--r--src/liballoc/task.rs130
-rw-r--r--src/liballoc/tests/binary_heap.rs1
-rw-r--r--src/liballoc/tests/btree/map.rs30
-rw-r--r--src/liballoc/tests/heap.rs2
-rw-r--r--src/liballoc/tests/lib.rs2
-rw-r--r--src/liballoc/tests/slice.rs20
-rw-r--r--src/liballoc/tests/str.rs79
-rw-r--r--src/liballoc/tests/string.rs11
-rw-r--r--src/liballoc/tests/vec.rs14
-rw-r--r--src/liballoc/tests/vec_deque.rs6
-rw-r--r--src/liballoc/vec.rs10
28 files changed, 210 insertions, 275 deletions
diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs
index 08c69ee6e85..a1884b7d548 100644
--- a/src/liballoc/benches/lib.rs
+++ b/src/liballoc/benches/lib.rs
@@ -1,5 +1,4 @@
 #![feature(repr_simd)]
-#![feature(slice_sort_by_cached_key)]
 #![feature(test)]
 
 extern crate rand;
diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs
index 270f48e8083..40c71f12cd8 100644
--- a/src/liballoc/borrow.rs
+++ b/src/liballoc/borrow.rs
@@ -137,11 +137,11 @@ impl<T> ToOwned for T
 /// ```
 /// use std::borrow::{Cow, ToOwned};
 ///
-/// struct Items<'a, X: 'a> where [X]: ToOwned<Owned=Vec<X>> {
+/// struct Items<'a, X: 'a> where [X]: ToOwned<Owned = Vec<X>> {
 ///     values: Cow<'a, [X]>,
 /// }
 ///
-/// impl<'a, X: Clone + 'a> Items<'a, X> where [X]: ToOwned<Owned=Vec<X>> {
+/// impl<'a, X: Clone + 'a> Items<'a, X> where [X]: ToOwned<Owned = Vec<X>> {
 ///     fn new(v: Cow<'a, [X]>) -> Self {
 ///         Items { values: v }
 ///     }
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 8e01e12e0b8..0cd2373c7f0 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -71,7 +71,7 @@ use core::ops::{
     CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState
 };
 use core::ptr::{self, NonNull, Unique};
-use core::task::{LocalWaker, Poll};
+use core::task::{Waker, Poll};
 
 use crate::vec::Vec;
 use crate::raw_vec::RawVec;
@@ -202,10 +202,15 @@ 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(b: Box<T>) -> Unique<T> {
-        let unique = b.0;
+    pub fn into_unique(mut b: Box<T>) -> Unique<T> {
+        // 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);
-        unique
+        unsafe { Unique::new_unchecked(unique) }
     }
 
     /// Consumes and leaks the `Box`, returning a mutable reference,
@@ -896,7 +901,7 @@ impl<G: ?Sized + Generator> Generator for Pin<Box<G>> {
 impl<F: ?Sized + Future + Unpin> Future for Box<F> {
     type Output = F::Output;
 
-    fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
-        F::poll(Pin::new(&mut *self), lw)
+    fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll<Self::Output> {
+        F::poll(Pin::new(&mut *self), waker)
     }
 }
diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs
index f97522140a8..3b94379b58f 100644
--- a/src/liballoc/collections/binary_heap.rs
+++ b/src/liballoc/collections/binary_heap.rs
@@ -248,14 +248,18 @@ impl<T: Ord> Drop for PeekMut<'_, T> {
 impl<T: Ord> Deref for PeekMut<'_, T> {
     type Target = T;
     fn deref(&self) -> &T {
-        &self.heap.data[0]
+        debug_assert!(!self.heap.is_empty());
+        // SAFE: PeekMut is only instantiated for non-empty heaps
+        unsafe { self.heap.data.get_unchecked(0) }
     }
 }
 
 #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
 impl<T: Ord> DerefMut for PeekMut<'_, T> {
     fn deref_mut(&mut self) -> &mut T {
-        &mut self.heap.data[0]
+        debug_assert!(!self.heap.is_empty());
+        // SAFE: PeekMut is only instantiated for non-empty heaps
+        unsafe { self.heap.data.get_unchecked_mut(0) }
     }
 }
 
@@ -859,13 +863,14 @@ struct Hole<'a, T: 'a> {
 }
 
 impl<'a, T> Hole<'a, T> {
-    /// Create a new Hole at index `pos`.
+    /// Create a new `Hole` at index `pos`.
     ///
     /// Unsafe because pos must be within the data slice.
     #[inline]
     unsafe fn new(data: &'a mut [T], pos: usize) -> Self {
         debug_assert!(pos < data.len());
-        let elt = ptr::read(&data[pos]);
+        // SAFE: pos should be inside the slice
+        let elt = ptr::read(data.get_unchecked(pos));
         Hole {
             data,
             elt: ManuallyDrop::new(elt),
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index aaaa419dcb8..5ec5064b735 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -2368,7 +2368,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
 
     /// Gets a mutable reference to the value in the entry.
     ///
-    /// If you need a reference to the `OccupiedEntry` which may outlive the
+    /// If you need a reference to the `OccupiedEntry` that may outlive the
     /// destruction of the `Entry` value, see [`into_mut`].
     ///
     /// [`into_mut`]: #method.into_mut
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs
index c4f39430533..fc1c1878924 100644
--- a/src/liballoc/collections/btree/node.rs
+++ b/src/liballoc/collections/btree/node.rs
@@ -50,11 +50,11 @@ pub const CAPACITY: usize = 2 * B - 1;
 ///
 /// We have a separate type for the header and rely on it matching the prefix of `LeafNode`, in
 /// order to statically allocate a single dummy node to avoid allocations. This struct is
-/// `repr(C)` to prevent them from being reordered.  `LeafNode` does not just contain a
+/// `repr(C)` to prevent them from being reordered. `LeafNode` does not just contain a
 /// `NodeHeader` because we do not want unnecessary padding between `len` and the keys.
-/// Crucially, `NodeHeader` can be safely transmuted to different K and V.  (This is exploited
+/// Crucially, `NodeHeader` can be safely transmuted to different K and V. (This is exploited
 /// by `as_header`.)
-/// See `into_key_slice` for an explanation of K2.  K2 cannot be safely transmuted around
+/// See `into_key_slice` for an explanation of K2. K2 cannot be safely transmuted around
 /// because the size of `NodeHeader` depends on its alignment!
 #[repr(C)]
 struct NodeHeader<K, V, K2 = ()> {
@@ -453,7 +453,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
                     root: self.root,
                     _marker: PhantomData
                 },
-                idx: unsafe { usize::from(*self.as_header().parent_idx.get_ref()) },
+                idx: unsafe { usize::from(*self.as_header().parent_idx.as_ptr()) },
                 _marker: PhantomData
             })
         } else {
@@ -1143,7 +1143,7 @@ impl<BorrowType, K, V>
         NodeRef {
             height: self.node.height - 1,
             node: unsafe {
-                self.node.as_internal().edges.get_unchecked(self.idx).get_ref().as_ptr()
+                (&*self.node.as_internal().edges.get_unchecked(self.idx).as_ptr()).as_ptr()
             },
             root: self.node.root,
             _marker: PhantomData
@@ -1295,7 +1295,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
         }
     }
 
-    /// Returns whether it is valid to call `.merge()`, i.e., whether there is enough room in
+    /// Returns `true` if it is valid to call `.merge()`, i.e., whether there is enough room in
     /// a node to hold the combination of the nodes to the left and right of this handle along
     /// with the key/value pair at this handle.
     pub fn can_merge(&self) -> bool {
@@ -1573,7 +1573,7 @@ unsafe fn move_edges<K, V>(
 impl<BorrowType, K, V, HandleType>
         Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, HandleType> {
 
-    /// Check whether the underlying node is an `Internal` node or a `Leaf` node.
+    /// Checks whether the underlying node is an `Internal` node or a `Leaf` node.
     pub fn force(self) -> ForceResult<
         Handle<NodeRef<BorrowType, K, V, marker::Leaf>, HandleType>,
         Handle<NodeRef<BorrowType, K, V, marker::Internal>, HandleType>
diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs
index 78cd21dd411..870e3e47692 100644
--- a/src/liballoc/collections/btree/set.rs
+++ b/src/liballoc/collections/btree/set.rs
@@ -556,7 +556,7 @@ impl<T: Ord> BTreeSet<T> {
         Recover::replace(&mut self.map, value)
     }
 
-    /// Removes a value from the set. Returns `true` if the value was
+    /// Removes a value from the set. Returns whether the value was
     /// present in the set.
     ///
     /// The value may be any borrowed form of the set's value type,
@@ -988,7 +988,7 @@ impl<'a, T> DoubleEndedIterator for Range<'a, T> {
 #[stable(feature = "fused", since = "1.26.0")]
 impl<T> FusedIterator for Range<'_, T> {}
 
-/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
+/// Compares `x` and `y`, but return `short` if x is None and `long` if y is None
 fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering {
     match (x, y) {
         (None, _) => short,
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 99fa54acb08..b6fdaa89992 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -124,7 +124,7 @@ impl<T> VecDeque<T> {
         ptr::write(self.ptr().add(off), value);
     }
 
-    /// Returns `true` if and only if the buffer is at full capacity.
+    /// Returns `true` if the buffer is at full capacity.
     #[inline]
     fn is_full(&self) -> bool {
         self.cap() - self.len() == 1
@@ -560,7 +560,7 @@ impl<T> VecDeque<T> {
     /// Does nothing if the capacity is already sufficient.
     ///
     /// Note that the allocator may give the collection more space than it
-    /// requests. Therefore capacity can not be relied upon to be precisely
+    /// requests. Therefore, capacity can not be relied upon to be precisely
     /// minimal. Prefer `reserve` if future insertions are expected.
     ///
     /// # Errors
@@ -924,7 +924,7 @@ impl<T> VecDeque<T> {
         self.tail == self.head
     }
 
-    /// Create a draining iterator that removes the specified range in the
+    /// Creates a draining iterator that removes the specified range in the
     /// `VecDeque` and yields the removed items.
     ///
     /// Note 1: The element range is removed even if the iterator is not
@@ -932,7 +932,7 @@ impl<T> VecDeque<T> {
     ///
     /// Note 2: It is unspecified how many elements are removed from the deque,
     /// if the `Drain` value is not dropped, but the borrow it holds expires
-    /// (eg. due to mem::forget).
+    /// (e.g., due to `mem::forget`).
     ///
     /// # Panics
     ///
@@ -1922,7 +1922,7 @@ impl<T> VecDeque<T> {
     ///
     /// # Panics
     ///
-    /// If `mid` is greater than `len()`.  Note that `mid == len()`
+    /// If `mid` is greater than `len()`. Note that `mid == len()`
     /// does _not_ panic and is a no-op rotation.
     ///
     /// # Complexity
@@ -1967,7 +1967,7 @@ impl<T> VecDeque<T> {
     ///
     /// # Panics
     ///
-    /// If `k` is greater than `len()`.  Note that `k == len()`
+    /// If `k` is greater than `len()`. Note that `k == len()`
     /// does _not_ panic and is a no-op rotation.
     ///
     /// # Complexity
diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs
index 9bda7034a62..d2ba9b00191 100644
--- a/src/liballoc/fmt.rs
+++ b/src/liballoc/fmt.rs
@@ -27,7 +27,7 @@
 //! will then parse the format string and determine if the list of arguments
 //! provided is suitable to pass to this format string.
 //!
-//! To convert a single value to a string, use the [`to_string`] method.  This
+//! To convert a single value to a string, use the [`to_string`] method. This
 //! will use the [`Display`] formatting trait.
 //!
 //! ## Positional parameters
@@ -102,7 +102,7 @@
 //! When requesting that an argument be formatted with a particular type, you
 //! are actually requesting that an argument ascribes to a particular trait.
 //! This allows multiple actual types to be formatted via `{:x}` (like [`i8`] as
-//! well as [`isize`]).  The current mapping of types to traits is:
+//! well as [`isize`]). The current mapping of types to traits is:
 //!
 //! * *nothing* ⇒ [`Display`]
 //! * `?` ⇒ [`Debug`]
@@ -427,7 +427,7 @@
 //! 3. An asterisk `.*`:
 //!
 //!    `.*` means that this `{...}` is associated with *two* format inputs rather than one: the
-//!    first input holds the `usize` precision, and the second holds the value to print.  Note that
+//!    first input holds the `usize` precision, and the second holds the value to print. Note that
 //!    in this case, if one uses the format string `{<arg>:<spec>.*}`, then the `<arg>` part refers
 //!    to the *value* to print, and the `precision` must come in the input preceding `<arg>`.
 //!
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 80097a128a5..440ce8ac5e8 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -55,9 +55,7 @@
             reason = "this library is unlikely to be stabilized in its current \
                       form or name",
             issue = "27783")]
-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
-       html_root_url = "https://doc.rust-lang.org/nightly/",
+#![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
        issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
        test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
 #![no_std]
@@ -70,7 +68,6 @@
 #![warn(intra_doc_link_resolution_failure)]
 #![warn(missing_debug_implementations)]
 
-#![cfg_attr(not(test), feature(fn_traits))]
 #![cfg_attr(not(test), feature(generator_trait))]
 #![cfg_attr(test, feature(test))]
 
@@ -88,6 +85,7 @@
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
 #![feature(fmt_internals)]
+#![feature(fn_traits)]
 #![feature(fundamental)]
 #![feature(futures_api)]
 #![feature(lang_items)]
@@ -102,6 +100,7 @@
 #![feature(receiver_trait)]
 #![feature(specialization)]
 #![feature(staged_api)]
+#![feature(std_internals)]
 #![feature(str_internals)]
 #![feature(trusted_len)]
 #![feature(try_reserve)]
@@ -113,7 +112,7 @@
 #![feature(rustc_const_unstable)]
 #![feature(const_vec_new)]
 #![feature(slice_partition_dedup)]
-#![feature(maybe_uninit)]
+#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)]
 #![feature(alloc_layout_extra)]
 #![feature(try_trait)]
 
@@ -133,10 +132,6 @@ mod macros;
 
 pub mod alloc;
 
-#[unstable(feature = "futures_api",
-           reason = "futures in libcore are unstable",
-           issue = "50547")]
-pub mod task;
 // Primitive types using the heaps above
 
 // Need to conditionally define the mod from `boxed.rs` to avoid
diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs
index db91b07fa71..eb341007851 100644
--- a/src/liballoc/macros.rs
+++ b/src/liballoc/macros.rs
@@ -34,7 +34,8 @@
 #[cfg(not(test))]
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow_internal_unstable]
+#[cfg_attr(not(stage0), allow_internal_unstable(box_syntax))]
+#[cfg_attr(stage0, allow_internal_unstable)]
 macro_rules! vec {
     ($elem:expr; $n:expr) => (
         $crate::vec::from_elem($elem, $n)
@@ -62,18 +63,18 @@ macro_rules! vec {
 
 /// Creates a `String` using interpolation of runtime expressions.
 ///
-/// The first argument `format!` receives is a format string.  This must be a string
-/// literal.  The power of the formatting string is in the `{}`s contained.
+/// The first argument `format!` receives is a format string. This must be a string
+/// literal. The power of the formatting string is in the `{}`s contained.
 ///
 /// Additional parameters passed to `format!` replace the `{}`s within the
 /// formatting string in the order given unless named or positional parameters
-/// are used, see [`std::fmt`][fmt] for more information.
+/// are used; see [`std::fmt`][fmt] for more information.
 ///
 /// A common use for `format!` is concatenation and interpolation of strings.
 /// The same convention is used with [`print!`] and [`write!`] macros,
 /// depending on the intended destination of the string.
 ///
-/// To convert a single value to a string, use the [`to_string`] method.  This
+/// To convert a single value to a string, use the [`to_string`] method. This
 /// will use the [`Display`] formatting trait.
 ///
 /// [fmt]: ../std/fmt/index.html
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index dcecf9bc76d..fe28fe5095c 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -335,7 +335,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// enough to want to do that it's easiest to just have a dedicated method. Slightly
     /// more efficient logic can be provided for this than the general case.
     ///
-    /// Returns true if the reallocation attempt has succeeded, or false otherwise.
+    /// Returns `true` if the reallocation attempt has succeeded.
     ///
     /// # Panics
     ///
@@ -504,7 +504,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// the requested space. This is not really unsafe, but the unsafe
     /// code *you* write that relies on the behavior of this function may break.
     ///
-    /// Returns true if the reallocation attempt has succeeded, or false otherwise.
+    /// Returns `true` if the reallocation attempt has succeeded.
     ///
     /// # Panics
     ///
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index d78869270d5..12f75d84211 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -512,7 +512,7 @@ impl<T: ?Sized> Rc<T> {
         this.strong()
     }
 
-    /// Returns true if there are no other `Rc` or [`Weak`][weak] pointers to
+    /// Returns `true` if there are no other `Rc` or [`Weak`][weak] pointers to
     /// this inner value.
     ///
     /// [weak]: struct.Weak.html
@@ -561,7 +561,7 @@ impl<T: ?Sized> Rc<T> {
 
     #[inline]
     #[stable(feature = "ptr_eq", since = "1.17.0")]
-    /// Returns true if the two `Rc`s point to the same value (not
+    /// Returns `true` if the two `Rc`s point to the same value (not
     /// just values that compare as equal).
     ///
     /// # Examples
@@ -1334,8 +1334,8 @@ impl<T: ?Sized> Weak<T> {
         })
     }
 
-    /// Return `None` when the pointer is dangling and there is no allocated `RcBox`,
-    /// i.e., this `Weak` was created by `Weak::new`
+    /// Returns `None` when the pointer is dangling and there is no allocated `RcBox`
+    /// (i.e., when this `Weak` was created by `Weak::new`).
     #[inline]
     fn inner(&self) -> Option<&RcBox<T>> {
         if is_dangling(self.ptr) {
@@ -1345,7 +1345,7 @@ impl<T: ?Sized> Weak<T> {
         }
     }
 
-    /// Returns true if the two `Weak`s point to the same value (not just values
+    /// Returns `true` if the two `Weak`s point to the same value (not just values
     /// that compare as equal).
     ///
     /// # Notes
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 479959deeb1..f4b2d463778 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -205,10 +205,10 @@ impl<T> [T] {
     ///
     /// The comparator function must define a total ordering for the elements in the slice. If
     /// the ordering is not total, the order of the elements is unspecified. An order is a
-    /// total order if it is (for all a, b and c):
+    /// total order if it is (for all `a`, `b` and `c`):
     ///
-    /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and
-    /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >.
+    /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
+    /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
     ///
     /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
     /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
@@ -257,6 +257,10 @@ impl<T> [T] {
     /// This sort is stable (i.e., does not reorder equal elements) and `O(m n log(m n))`
     /// worst-case, where the key function is `O(m)`.
     ///
+    /// For expensive key functions (e.g. functions that are not simple property accesses or
+    /// basic operations), [`sort_by_cached_key`](#method.sort_by_cached_key) is likely to be
+    /// significantly faster, as it does not recompute element keys.
+    ///
     /// When applicable, unstable sorting is preferred because it is generally faster than stable
     /// sorting and it doesn't allocate auxiliary memory.
     /// See [`sort_unstable_by_key`](#method.sort_unstable_by_key).
@@ -312,7 +316,6 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_sort_by_cached_key)]
     /// let mut v = [-5i32, 4, 32, -3, 2];
     ///
     /// v.sort_by_cached_key(|k| k.to_string());
@@ -320,7 +323,7 @@ impl<T> [T] {
     /// ```
     ///
     /// [pdqsort]: https://github.com/orlp/pdqsort
-    #[unstable(feature = "slice_sort_by_cached_key", issue = "34447")]
+    #[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")]
     #[inline]
     pub fn sort_by_cached_key<K, F>(&mut self, f: F)
         where F: FnMut(&T) -> K, K: Ord
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 1fd4c9978a6..a36804bddff 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -29,8 +29,6 @@
 #![allow(unused_imports)]
 
 use core::borrow::Borrow;
-use core::fmt;
-use core::str as core_str;
 use core::str::pattern::{Pattern, Searcher, ReverseSearcher, DoubleEndedSearcher};
 use core::mem;
 use core::ptr;
@@ -443,45 +441,6 @@ impl str {
         return s;
     }
 
-    /// Escapes each char in `s` with [`char::escape_debug`].
-    ///
-    /// Note: only extended grapheme codepoints that begin the string will be
-    /// escaped.
-    ///
-    /// [`char::escape_debug`]: primitive.char.html#method.escape_debug
-    #[unstable(feature = "str_escape",
-               reason = "return type may change to be an iterator",
-               issue = "27791")]
-    pub fn escape_debug(&self) -> String {
-        let mut string = String::with_capacity(self.len());
-        let mut chars = self.chars();
-        if let Some(first) = chars.next() {
-            string.extend(first.escape_debug_ext(true))
-        }
-        string.extend(chars.flat_map(|c| c.escape_debug_ext(false)));
-        string
-    }
-
-    /// Escapes each char in `s` with [`char::escape_default`].
-    ///
-    /// [`char::escape_default`]: primitive.char.html#method.escape_default
-    #[unstable(feature = "str_escape",
-               reason = "return type may change to be an iterator",
-               issue = "27791")]
-    pub fn escape_default(&self) -> String {
-        self.chars().flat_map(|c| c.escape_default()).collect()
-    }
-
-    /// Escapes each char in `s` with [`char::escape_unicode`].
-    ///
-    /// [`char::escape_unicode`]: primitive.char.html#method.escape_unicode
-    #[unstable(feature = "str_escape",
-               reason = "return type may change to be an iterator",
-               issue = "27791")]
-    pub fn escape_unicode(&self) -> String {
-        self.chars().flat_map(|c| c.escape_unicode()).collect()
-    }
-
     /// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
     ///
     /// [`String`]: string/struct.String.html
@@ -612,3 +571,4 @@ impl str {
 pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
     Box::from_raw(Box::into_raw(v) as *mut str)
 }
+
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 73f67e98f36..84c35c6f1bd 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -963,7 +963,7 @@ impl String {
     /// Does nothing if the capacity is already sufficient.
     ///
     /// Note that the allocator may give the collection more space than it
-    /// requests. Therefore capacity can not be relied upon to be precisely
+    /// requests. Therefore, capacity can not be relied upon to be precisely
     /// minimal. Prefer `reserve` if future insertions are expected.
     ///
     /// # Errors
@@ -1377,9 +1377,7 @@ impl String {
         self.vec.len()
     }
 
-    /// Returns `true` if this `String` has a length of zero.
-    ///
-    /// Returns `false` otherwise.
+    /// Returns `true` if this `String` has a length of zero, and `false` otherwise.
     ///
     /// # Examples
     ///
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 5bdb3616ed2..b7d7995b540 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -560,7 +560,7 @@ impl<T: ?Sized> Arc<T> {
 
     #[inline]
     #[stable(feature = "ptr_eq", since = "1.17.0")]
-    /// Returns true if the two `Arc`s point to the same value (not
+    /// Returns `true` if the two `Arc`s point to the same value (not
     /// just values that compare as equal).
     ///
     /// # Examples
@@ -1191,8 +1191,8 @@ impl<T: ?Sized> Weak<T> {
         })
     }
 
-    /// Return `None` when the pointer is dangling and there is no allocated `ArcInner`,
-    /// i.e., this `Weak` was created by `Weak::new`
+    /// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,
+    /// (i.e., when this `Weak` was created by `Weak::new`).
     #[inline]
     fn inner(&self) -> Option<&ArcInner<T>> {
         if is_dangling(self.ptr) {
@@ -1202,7 +1202,7 @@ impl<T: ?Sized> Weak<T> {
         }
     }
 
-    /// Returns true if the two `Weak`s point to the same value (not just values
+    /// Returns `true` if the two `Weak`s point to the same value (not just values
     /// that compare as equal).
     ///
     /// # Notes
diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs
deleted file mode 100644
index 2261dabe277..00000000000
--- a/src/liballoc/task.rs
+++ /dev/null
@@ -1,130 +0,0 @@
-//! Types and Traits for working with asynchronous tasks.
-
-pub use core::task::*;
-
-#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
-pub use if_arc::*;
-
-#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
-mod if_arc {
-    use super::*;
-    use core::marker::PhantomData;
-    use core::mem;
-    use core::ptr::{self, NonNull};
-    use crate::sync::Arc;
-
-    /// A way of waking up a specific task.
-    ///
-    /// Any task executor must provide a way of signaling that a task it owns
-    /// is ready to be `poll`ed again. Executors do so by implementing this trait.
-    pub trait Wake: Send + Sync {
-        /// Indicates that the associated task is ready to make progress and should
-        /// be `poll`ed.
-        ///
-        /// Executors generally maintain a queue of "ready" tasks; `wake` should place
-        /// the associated task onto this queue.
-        fn wake(arc_self: &Arc<Self>);
-
-        /// Indicates that the associated task is ready to make progress and should
-        /// be `poll`ed. This function is like `wake`, but can only be called from the
-        /// thread on which this `Wake` was created.
-        ///
-        /// Executors generally maintain a queue of "ready" tasks; `wake_local` should place
-        /// the associated task onto this queue.
-        #[inline]
-        unsafe fn wake_local(arc_self: &Arc<Self>) {
-            Self::wake(arc_self);
-        }
-    }
-
-    #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
-    struct ArcWrapped<T>(PhantomData<T>);
-
-    unsafe impl<T: Wake + 'static> UnsafeWake for ArcWrapped<T> {
-        #[inline]
-        unsafe fn clone_raw(&self) -> Waker {
-            let me: *const ArcWrapped<T> = self;
-            let arc = (*(&me as *const *const ArcWrapped<T> as *const Arc<T>)).clone();
-            Waker::from(arc)
-        }
-
-        #[inline]
-        unsafe fn drop_raw(&self) {
-            let mut me: *const ArcWrapped<T> = self;
-            let me = &mut me as *mut *const ArcWrapped<T> as *mut Arc<T>;
-            ptr::drop_in_place(me);
-        }
-
-        #[inline]
-        unsafe fn wake(&self) {
-            let me: *const ArcWrapped<T> = self;
-            T::wake(&*(&me as *const *const ArcWrapped<T> as *const Arc<T>))
-        }
-
-        #[inline]
-        unsafe fn wake_local(&self) {
-            let me: *const ArcWrapped<T> = self;
-            T::wake_local(&*(&me as *const *const ArcWrapped<T> as *const Arc<T>))
-        }
-    }
-
-    impl<T> From<Arc<T>> for Waker
-        where T: Wake + 'static,
-    {
-        fn from(rc: Arc<T>) -> Self {
-            unsafe {
-                let ptr = mem::transmute::<Arc<T>, NonNull<ArcWrapped<T>>>(rc);
-                Waker::new(ptr)
-            }
-        }
-    }
-
-    /// Creates a `LocalWaker` from a local `wake`.
-    ///
-    /// This function requires that `wake` is "local" (created on the current thread).
-    /// The resulting `LocalWaker` will call `wake.wake_local()` when awoken, and
-    /// will call `wake.wake()` if awoken after being converted to a `Waker`.
-    #[inline]
-    pub unsafe fn local_waker<W: Wake + 'static>(wake: Arc<W>) -> LocalWaker {
-        let ptr = mem::transmute::<Arc<W>, NonNull<ArcWrapped<W>>>(wake);
-        LocalWaker::new(ptr)
-    }
-
-    struct NonLocalAsLocal<T>(ArcWrapped<T>);
-
-    unsafe impl<T: Wake + 'static> UnsafeWake for NonLocalAsLocal<T> {
-        #[inline]
-        unsafe fn clone_raw(&self) -> Waker {
-            self.0.clone_raw()
-        }
-
-        #[inline]
-        unsafe fn drop_raw(&self) {
-            self.0.drop_raw()
-        }
-
-        #[inline]
-        unsafe fn wake(&self) {
-            self.0.wake()
-        }
-
-        #[inline]
-        unsafe fn wake_local(&self) {
-            // Since we're nonlocal, we can't call wake_local
-            self.0.wake()
-        }
-    }
-
-    /// Creates a `LocalWaker` from a non-local `wake`.
-    ///
-    /// This function is similar to `local_waker`, but does not require that `wake`
-    /// is local to the current thread. The resulting `LocalWaker` will call
-    /// `wake.wake()` when awoken.
-    #[inline]
-    pub fn local_waker_from_nonlocal<W: Wake + 'static>(wake: Arc<W>) -> LocalWaker {
-        unsafe {
-            let ptr = mem::transmute::<Arc<W>, NonNull<NonLocalAsLocal<W>>>(wake);
-            LocalWaker::new(ptr)
-        }
-    }
-}
diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs
index 94ae43237d1..1d4a3edc1ac 100644
--- a/src/liballoc/tests/binary_heap.rs
+++ b/src/liballoc/tests/binary_heap.rs
@@ -282,6 +282,7 @@ fn assert_covariance() {
 //
 // Destructors must be called exactly once per element.
 #[test]
+#[cfg(not(miri))] // Miri does not support panics
 fn panic_safe() {
     static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
 
diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs
index aaf50407328..f14750089c9 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -9,7 +9,10 @@ use super::DeterministicRng;
 #[test]
 fn test_basic_large() {
     let mut map = BTreeMap::new();
+    #[cfg(not(miri))] // Miri is too slow
     let size = 10000;
+    #[cfg(miri)]
+    let size = 200;
     assert_eq!(map.len(), 0);
 
     for i in 0..size {
@@ -69,7 +72,10 @@ fn test_basic_small() {
 
 #[test]
 fn test_iter() {
+    #[cfg(not(miri))] // Miri is too slow
     let size = 10000;
+    #[cfg(miri)]
+    let size = 200;
 
     // Forwards
     let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
@@ -91,7 +97,10 @@ fn test_iter() {
 
 #[test]
 fn test_iter_rev() {
+    #[cfg(not(miri))] // Miri is too slow
     let size = 10000;
+    #[cfg(miri)]
+    let size = 200;
 
     // Forwards
     let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
@@ -127,7 +136,10 @@ fn test_values_mut() {
 
 #[test]
 fn test_iter_mixed() {
+    #[cfg(not(miri))] // Miri is too slow
     let size = 10000;
+    #[cfg(miri)]
+    let size = 200;
 
     // Forwards
     let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
@@ -214,6 +226,7 @@ fn test_range_equal_empty_cases() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_range_equal_excluded() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Excluded(2), Excluded(2)));
@@ -221,6 +234,7 @@ fn test_range_equal_excluded() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_range_backwards_1() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Included(3), Included(2)));
@@ -228,6 +242,7 @@ fn test_range_backwards_1() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_range_backwards_2() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Included(3), Excluded(2)));
@@ -235,6 +250,7 @@ fn test_range_backwards_2() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_range_backwards_3() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Excluded(3), Included(2)));
@@ -242,6 +258,7 @@ fn test_range_backwards_3() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_range_backwards_4() {
     let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
     map.range((Excluded(3), Excluded(2)));
@@ -249,7 +266,10 @@ fn test_range_backwards_4() {
 
 #[test]
 fn test_range_1000() {
+    #[cfg(not(miri))] // Miri is too slow
     let size = 1000;
+    #[cfg(miri)]
+    let size = 200;
     let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
 
     fn test(map: &BTreeMap<u32, u32>, size: u32, min: Bound<&u32>, max: Bound<&u32>) {
@@ -286,7 +306,10 @@ fn test_range_borrowed_key() {
 
 #[test]
 fn test_range() {
+    #[cfg(not(miri))] // Miri is too slow
     let size = 200;
+    #[cfg(miri)]
+    let size = 30;
     let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
 
     for i in 0..size {
@@ -305,7 +328,10 @@ fn test_range() {
 
 #[test]
 fn test_range_mut() {
+    #[cfg(not(miri))] // Miri is too slow
     let size = 200;
+    #[cfg(miri)]
+    let size = 30;
     let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
 
     for i in 0..size {
@@ -479,7 +505,10 @@ fn test_bad_zst() {
 #[test]
 fn test_clone() {
     let mut map = BTreeMap::new();
+    #[cfg(not(miri))] // Miri is too slow
     let size = 100;
+    #[cfg(miri)]
+    let size = 30;
     assert_eq!(map.len(), 0);
 
     for i in 0..size {
@@ -631,6 +660,7 @@ create_append_test!(test_append_145, 145);
 create_append_test!(test_append_170, 170);
 create_append_test!(test_append_181, 181);
 create_append_test!(test_append_239, 239);
+#[cfg(not(miri))] // Miri is too slow
 create_append_test!(test_append_1700, 1700);
 
 fn rand_data(len: usize) -> Vec<(u32, u32)> {
diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs
index 24eea1d2949..c225ebfa96b 100644
--- a/src/liballoc/tests/heap.rs
+++ b/src/liballoc/tests/heap.rs
@@ -1,6 +1,6 @@
 use std::alloc::{Global, Alloc, Layout, System};
 
-/// https://github.com/rust-lang/rust/issues/45955
+/// Issue #45955.
 #[test]
 fn alloc_system_overaligned_request() {
     check_overalign_requests(System)
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index a76fd87a1a9..2361a7db1f7 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -4,8 +4,6 @@
 #![feature(exact_size_is_empty)]
 #![feature(pattern)]
 #![feature(repeat_generic_slice)]
-#![feature(slice_sort_by_cached_key)]
-#![feature(str_escape)]
 #![feature(try_reserve)]
 #![feature(unboxed_closures)]
 #![feature(vecdeque_rotate)]
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index 334466dfb25..feba46b0fad 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -258,6 +258,7 @@ fn test_swap_remove() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_swap_remove_fail() {
     let mut v = vec![1];
     let _ = v.swap_remove(0);
@@ -389,6 +390,7 @@ fn test_reverse() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri does not support entropy
 fn test_sort() {
     let mut rng = thread_rng();
 
@@ -465,6 +467,7 @@ fn test_sort() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri does not support entropy
 fn test_sort_stability() {
     for len in (2..25).chain(500..510) {
         for _ in 0..10 {
@@ -629,6 +632,7 @@ fn test_insert() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_insert_oob() {
     let mut a = vec![1, 2, 3];
     a.insert(4, 5);
@@ -653,6 +657,7 @@ fn test_remove() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_remove_fail() {
     let mut a = vec![1];
     let _ = a.remove(0);
@@ -934,6 +939,7 @@ fn test_windowsator() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_windowsator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.windows(0);
@@ -958,6 +964,7 @@ fn test_chunksator() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_chunksator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.chunks(0);
@@ -982,6 +989,7 @@ fn test_chunks_exactator() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_chunks_exactator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.chunks_exact(0);
@@ -1006,6 +1014,7 @@ fn test_rchunksator() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_rchunksator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.rchunks(0);
@@ -1030,6 +1039,7 @@ fn test_rchunks_exactator() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_rchunks_exactator_0() {
     let v = &[1, 2, 3, 4];
     let _it = v.rchunks_exact(0);
@@ -1082,6 +1092,7 @@ fn test_vec_default() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_overflow_does_not_cause_segfault() {
     let mut v = vec![];
     v.reserve_exact(!0);
@@ -1091,6 +1102,7 @@ fn test_overflow_does_not_cause_segfault() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_overflow_does_not_cause_segfault_managed() {
     let mut v = vec![Rc::new(1)];
     v.reserve_exact(!0);
@@ -1266,6 +1278,7 @@ fn test_mut_chunks_rev() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_mut_chunks_0() {
     let mut v = [1, 2, 3, 4];
     let _it = v.chunks_mut(0);
@@ -1298,6 +1311,7 @@ fn test_mut_chunks_exact_rev() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_mut_chunks_exact_0() {
     let mut v = [1, 2, 3, 4];
     let _it = v.chunks_exact_mut(0);
@@ -1330,6 +1344,7 @@ fn test_mut_rchunks_rev() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_mut_rchunks_0() {
     let mut v = [1, 2, 3, 4];
     let _it = v.rchunks_mut(0);
@@ -1362,6 +1377,7 @@ fn test_mut_rchunks_exact_rev() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_mut_rchunks_exact_0() {
     let mut v = [1, 2, 3, 4];
     let _it = v.rchunks_exact_mut(0);
@@ -1395,6 +1411,7 @@ fn test_box_slice_clone() {
 #[test]
 #[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
 #[cfg_attr(target_os = "emscripten", ignore)]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_box_slice_clone_panics() {
     use std::sync::Arc;
     use std::sync::atomic::{AtomicUsize, Ordering};
@@ -1459,6 +1476,7 @@ fn test_copy_from_slice() {
 
 #[test]
 #[should_panic(expected = "destination and source slices have different lengths")]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_copy_from_slice_dst_longer() {
     let src = [0, 1, 2, 3];
     let mut dst = [0; 5];
@@ -1467,6 +1485,7 @@ fn test_copy_from_slice_dst_longer() {
 
 #[test]
 #[should_panic(expected = "destination and source slices have different lengths")]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_copy_from_slice_dst_shorter() {
     let src = [0, 1, 2, 3];
     let mut dst = [0; 3];
@@ -1586,6 +1605,7 @@ thread_local!(static SILENCE_PANIC: Cell<bool> = Cell::new(false));
 
 #[test]
 #[cfg_attr(target_os = "emscripten", ignore)] // no threads
+#[cfg(not(miri))] // Miri does not support panics
 fn panic_safe() {
     let prev = panic::take_hook();
     panic::set_hook(Box::new(move |info| {
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index 1bc1bd8d78c..b33a5642188 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -166,6 +166,7 @@ fn test_join_for_different_lengths_with_long_separator() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri is too slow
 fn test_unsafe_slice() {
     assert_eq!("ab", unsafe {"abc".get_unchecked(0..2)});
     assert_eq!("bc", unsafe {"abc".get_unchecked(1..3)});
@@ -350,6 +351,7 @@ mod slice_index {
     //  to be used in `should_panic`)
     #[test]
     #[should_panic(expected = "out of bounds")]
+    #[cfg(not(miri))] // Miri does not support panics
     fn assert_range_eq_can_fail_by_panic() {
         assert_range_eq!("abc", 0..5, "abc");
     }
@@ -359,6 +361,7 @@ mod slice_index {
     //  to be used in `should_panic`)
     #[test]
     #[should_panic(expected = "==")]
+    #[cfg(not(miri))] // Miri does not support panics
     fn assert_range_eq_can_fail_by_inequality() {
         assert_range_eq!("abc", 0..2, "abc");
     }
@@ -406,6 +409,7 @@ mod slice_index {
 
                 #[test]
                 #[should_panic(expected = $expect_msg)]
+                #[cfg(not(miri))] // Miri does not support panics
                 fn index_fail() {
                     let v: String = $data.into();
                     let v: &str = &v;
@@ -414,6 +418,7 @@ mod slice_index {
 
                 #[test]
                 #[should_panic(expected = $expect_msg)]
+                #[cfg(not(miri))] // Miri does not support panics
                 fn index_mut_fail() {
                     let mut v: String = $data.into();
                     let v: &mut str = &mut v;
@@ -483,6 +488,7 @@ mod slice_index {
 
     #[test]
     #[cfg(not(target_arch = "asmjs"))] // hits an OOM
+    #[cfg(not(miri))] // Miri is too slow
     fn simple_big() {
         fn a_million_letter_x() -> String {
             let mut i = 0;
@@ -508,6 +514,7 @@ mod slice_index {
 
     #[test]
     #[should_panic]
+    #[cfg(not(miri))] // Miri does not support panics
     fn test_slice_fail() {
         &"中华Việt Nam"[0..2];
     }
@@ -659,12 +666,14 @@ mod slice_index {
     // check the panic includes the prefix of the sliced string
     #[test]
     #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
+    #[cfg(not(miri))] // Miri does not support panics
     fn test_slice_fail_truncated_1() {
         &LOREM_PARAGRAPH[..1024];
     }
     // check the truncation in the panic message
     #[test]
     #[should_panic(expected="luctus, im`[...]")]
+    #[cfg(not(miri))] // Miri does not support panics
     fn test_slice_fail_truncated_2() {
         &LOREM_PARAGRAPH[..1024];
     }
@@ -679,6 +688,7 @@ fn test_str_slice_rangetoinclusive_ok() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_str_slice_rangetoinclusive_notok() {
     let s = "abcαβγ";
     &s[..=3];
@@ -694,6 +704,7 @@ fn test_str_slicemut_rangetoinclusive_ok() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_str_slicemut_rangetoinclusive_notok() {
     let mut s = "abcαβγ".to_owned();
     let s: &mut str = &mut s;
@@ -883,6 +894,7 @@ fn test_as_bytes() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_as_bytes_fail() {
     // Don't double free. (I'm not sure if this exercises the
     // original problem code path anymore.)
@@ -972,6 +984,7 @@ fn test_split_at_mut() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_split_at_boundscheck() {
     let s = "ศไทย中华Việt Nam";
     s.split_at(1);
@@ -979,15 +992,15 @@ fn test_split_at_boundscheck() {
 
 #[test]
 fn test_escape_unicode() {
-    assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
-    assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
-    assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
-    assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
-    assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
-    assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
-    assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
-    assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
-    assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
+    assert_eq!("abc".escape_unicode().to_string(), "\\u{61}\\u{62}\\u{63}");
+    assert_eq!("a c".escape_unicode().to_string(), "\\u{61}\\u{20}\\u{63}");
+    assert_eq!("\r\n\t".escape_unicode().to_string(), "\\u{d}\\u{a}\\u{9}");
+    assert_eq!("'\"\\".escape_unicode().to_string(), "\\u{27}\\u{22}\\u{5c}");
+    assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode().to_string(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
+    assert_eq!("\u{100}\u{ffff}".escape_unicode().to_string(), "\\u{100}\\u{ffff}");
+    assert_eq!("\u{10000}\u{10ffff}".escape_unicode().to_string(), "\\u{10000}\\u{10ffff}");
+    assert_eq!("ab\u{fb00}".escape_unicode().to_string(), "\\u{61}\\u{62}\\u{fb00}");
+    assert_eq!("\u{1d4ea}\r".escape_unicode().to_string(), "\\u{1d4ea}\\u{d}");
 }
 
 #[test]
@@ -998,31 +1011,32 @@ fn test_escape_debug() {
     // they are escaped. However, when the character is unescaped (e.g., for
     // printable characters), only a single backslash appears (as the character
     // itself appears in the debug string).
-    assert_eq!("abc".escape_debug(), "abc");
-    assert_eq!("a c".escape_debug(), "a c");
-    assert_eq!("éèê".escape_debug(), "éèê");
-    assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t");
-    assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\");
-    assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
-    assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
-    assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
-    assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
-    assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
-    assert_eq!("\u{301}a\u{301}bé\u{e000}".escape_debug(), "\\u{301}a\u{301}bé\\u{e000}");
+    assert_eq!("abc".escape_debug().to_string(), "abc");
+    assert_eq!("a c".escape_debug().to_string(), "a c");
+    assert_eq!("éèê".escape_debug().to_string(), "éèê");
+    assert_eq!("\r\n\t".escape_debug().to_string(), "\\r\\n\\t");
+    assert_eq!("'\"\\".escape_debug().to_string(), "\\'\\\"\\\\");
+    assert_eq!("\u{7f}\u{ff}".escape_debug().to_string(), "\\u{7f}\u{ff}");
+    assert_eq!("\u{100}\u{ffff}".escape_debug().to_string(), "\u{100}\\u{ffff}");
+    assert_eq!("\u{10000}\u{10ffff}".escape_debug().to_string(), "\u{10000}\\u{10ffff}");
+    assert_eq!("ab\u{200b}".escape_debug().to_string(), "ab\\u{200b}");
+    assert_eq!("\u{10d4ea}\r".escape_debug().to_string(), "\\u{10d4ea}\\r");
+    assert_eq!("\u{301}a\u{301}bé\u{e000}".escape_debug().to_string(),
+               "\\u{301}a\u{301}bé\\u{e000}");
 }
 
 #[test]
 fn test_escape_default() {
-    assert_eq!("abc".escape_default(), "abc");
-    assert_eq!("a c".escape_default(), "a c");
-    assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
-    assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
-    assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
-    assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
-    assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
-    assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
-    assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
-    assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
+    assert_eq!("abc".escape_default().to_string(), "abc");
+    assert_eq!("a c".escape_default().to_string(), "a c");
+    assert_eq!("éèê".escape_default().to_string(), "\\u{e9}\\u{e8}\\u{ea}");
+    assert_eq!("\r\n\t".escape_default().to_string(), "\\r\\n\\t");
+    assert_eq!("'\"\\".escape_default().to_string(), "\\'\\\"\\\\");
+    assert_eq!("\u{7f}\u{ff}".escape_default().to_string(), "\\u{7f}\\u{ff}");
+    assert_eq!("\u{100}\u{ffff}".escape_default().to_string(), "\\u{100}\\u{ffff}");
+    assert_eq!("\u{10000}\u{10ffff}".escape_default().to_string(), "\\u{10000}\\u{10ffff}");
+    assert_eq!("ab\u{200b}".escape_default().to_string(), "ab\\u{200b}");
+    assert_eq!("\u{10d4ea}\r".escape_default().to_string(), "\\u{10d4ea}\\r");
 }
 
 #[test]
@@ -1066,6 +1080,7 @@ fn test_rev_iterator() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri is too slow
 fn test_chars_decoding() {
     let mut bytes = [0; 4];
     for c in (0..0x110000).filter_map(std::char::from_u32) {
@@ -1077,6 +1092,7 @@ fn test_chars_decoding() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri is too slow
 fn test_chars_rev_decoding() {
     let mut bytes = [0; 4];
     for c in (0..0x110000).filter_map(std::char::from_u32) {
@@ -1365,6 +1381,7 @@ fn test_bool_from_str() {
     assert_eq!("not even a boolean".parse::<bool>().ok(), None);
 }
 
+#[cfg(not(miri))] // Miri is too slow
 fn check_contains_all_substrings(s: &str) {
     assert!(s.contains(""));
     for i in 0..s.len() {
@@ -1375,6 +1392,7 @@ fn check_contains_all_substrings(s: &str) {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri is too slow
 fn strslice_issue_16589() {
     assert!("bananas".contains("nana"));
 
@@ -1391,6 +1409,7 @@ fn strslice_issue_16878() {
 
 
 #[test]
+#[cfg(not(miri))] // Miri is too slow
 fn test_strslice_contains() {
     let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
     check_contains_all_substrings(x);
diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs
index e5ce51a36ee..7e93d84fe3b 100644
--- a/src/liballoc/tests/string.rs
+++ b/src/liballoc/tests/string.rs
@@ -231,6 +231,7 @@ fn test_split_off_empty() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_split_off_past_end() {
     let orig = "Hello, world!";
     let mut split = String::from(orig);
@@ -239,6 +240,7 @@ fn test_split_off_past_end() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_split_off_mid_char() {
     let mut orig = String::from("山");
     orig.split_off(1);
@@ -287,6 +289,7 @@ fn test_str_truncate_invalid_len() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_str_truncate_split_codepoint() {
     let mut s = String::from("\u{FC}"); // ü
     s.truncate(1);
@@ -321,6 +324,7 @@ fn remove() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn remove_bad() {
     "ศ".to_string().remove(1);
 }
@@ -356,11 +360,13 @@ fn insert() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn insert_bad1() {
     "".to_string().insert(1, 't');
 }
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn insert_bad2() {
     "ệ".to_string().insert(1, 't');
 }
@@ -441,6 +447,7 @@ fn test_replace_range() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_replace_range_char_boundary() {
     let mut s = "Hello, 世界!".to_owned();
     s.replace_range(..8, "");
@@ -457,6 +464,7 @@ fn test_replace_range_inclusive_range() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_replace_range_out_of_bounds() {
     let mut s = String::from("12345");
     s.replace_range(5..6, "789");
@@ -464,6 +472,7 @@ fn test_replace_range_out_of_bounds() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_replace_range_inclusive_out_of_bounds() {
     let mut s = String::from("12345");
     s.replace_range(5..=5, "789");
@@ -523,6 +532,7 @@ fn test_reserve_exact() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri does not support signalling OOM
 fn test_try_reserve() {
 
     // These are the interesting cases:
@@ -600,6 +610,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.
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 89f2e0a046d..6e4ca1d90e6 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -1,3 +1,5 @@
+#![cfg(not(miri))]
+
 use std::borrow::Cow;
 use std::mem::size_of;
 use std::{usize, isize};
@@ -366,6 +368,7 @@ fn test_vec_truncate_drop() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_vec_truncate_fail() {
     struct BadElem(i32);
     impl Drop for BadElem {
@@ -389,6 +392,7 @@ fn test_index() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_index_out_of_bounds() {
     let vec = vec![1, 2, 3];
     let _ = vec[3];
@@ -396,6 +400,7 @@ fn test_index_out_of_bounds() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_1() {
     let x = vec![1, 2, 3, 4, 5];
     &x[!0..];
@@ -403,6 +408,7 @@ fn test_slice_out_of_bounds_1() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_2() {
     let x = vec![1, 2, 3, 4, 5];
     &x[..6];
@@ -410,6 +416,7 @@ fn test_slice_out_of_bounds_2() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_3() {
     let x = vec![1, 2, 3, 4, 5];
     &x[!0..4];
@@ -417,6 +424,7 @@ fn test_slice_out_of_bounds_3() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_4() {
     let x = vec![1, 2, 3, 4, 5];
     &x[1..6];
@@ -424,6 +432,7 @@ fn test_slice_out_of_bounds_4() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_slice_out_of_bounds_5() {
     let x = vec![1, 2, 3, 4, 5];
     &x[3..2];
@@ -431,6 +440,7 @@ fn test_slice_out_of_bounds_5() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_swap_remove_empty() {
     let mut vec = Vec::<i32>::new();
     vec.swap_remove(0);
@@ -501,6 +511,7 @@ fn test_drain_items_zero_sized() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_drain_out_of_bounds() {
     let mut v = vec![1, 2, 3, 4, 5];
     v.drain(5..6);
@@ -574,6 +585,7 @@ fn test_drain_max_vec_size() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_drain_inclusive_out_of_bounds() {
     let mut v = vec![1, 2, 3, 4, 5];
     v.drain(5..=5);
@@ -603,6 +615,7 @@ fn test_splice_inclusive_range() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_splice_out_of_bounds() {
     let mut v = vec![1, 2, 3, 4, 5];
     let a = [10, 11, 12];
@@ -611,6 +624,7 @@ fn test_splice_out_of_bounds() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_splice_inclusive_out_of_bounds() {
     let mut v = vec![1, 2, 3, 4, 5];
     let a = [10, 11, 12];
diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs
index aa49bdb0090..e0cb0e7a9e7 100644
--- a/src/liballoc/tests/vec_deque.rs
+++ b/src/liballoc/tests/vec_deque.rs
@@ -108,6 +108,7 @@ fn test_index() {
 
 #[test]
 #[should_panic]
+#[cfg(not(miri))] // Miri does not support panics
 fn test_index_out_of_bounds() {
     let mut deq = VecDeque::new();
     for i in 1..4 {
@@ -943,7 +944,10 @@ fn test_append_permutations() {
         out
     }
 
+    #[cfg(not(miri))] // Miri is too slow
     const MAX: usize = 5;
+    #[cfg(miri)]
+    const MAX: usize = 3;
 
     // Many different permutations of both the `VecDeque` getting appended to
     // and the one getting appended are generated to check `append`.
@@ -1120,6 +1124,7 @@ fn test_reserve_exact_2() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri does not support signalling OOM
 fn test_try_reserve() {
 
     // These are the interesting cases:
@@ -1221,6 +1226,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.
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 57e10498b92..57723e4d212 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -463,7 +463,7 @@ impl<T> Vec<T> {
     /// Does nothing if the capacity is already sufficient.
     ///
     /// Note that the allocator may give the collection more space than it
-    /// requests. Therefore capacity can not be relied upon to be precisely
+    /// requests. Therefore, capacity can not be relied upon to be precisely
     /// minimal. Prefer `reserve` if future insertions are expected.
     ///
     /// # Panics
@@ -525,7 +525,7 @@ impl<T> Vec<T> {
     /// Does nothing if the capacity is already sufficient.
     ///
     /// Note that the allocator may give the collection more space than it
-    /// requests. Therefore capacity can not be relied upon to be precisely
+    /// requests. Therefore, capacity can not be relied upon to be precisely
     /// minimal. Prefer `reserve` if future insertions are expected.
     ///
     /// # Errors
@@ -738,7 +738,7 @@ impl<T> Vec<T> {
     /// Forces the length of the vector to `new_len`.
     ///
     /// This is a low-level operation that maintains none of the normal
-    /// invariants of the type.  Normally changing the length of a vector
+    /// invariants of the type. Normally changing the length of a vector
     /// is done using one of the safe operations instead, such as
     /// [`truncate`], [`resize`], [`extend`], or [`clear`].
     ///
@@ -2608,7 +2608,7 @@ impl<T> Drain<'_, T> {
     /// The range from `self.vec.len` to `self.tail_start` contains elements
     /// that have been moved out.
     /// Fill that range as much as possible with new elements from the `replace_with` iterator.
-    /// Return whether we filled the entire range. (`replace_with.next()` didn’t return `None`.)
+    /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.)
     unsafe fn fill<I: Iterator<Item=T>>(&mut self, replace_with: &mut I) -> bool {
         let vec = self.vec.as_mut();
         let range_start = vec.len;
@@ -2628,7 +2628,7 @@ impl<T> Drain<'_, T> {
         true
     }
 
-    /// Make room for inserting more elements before the tail.
+    /// Makes room for inserting more elements before the tail.
     unsafe fn move_tail(&mut self, extra_capacity: usize) {
         let vec = self.vec.as_mut();
         let used_capacity = self.tail_start + self.tail_len;