about summary refs log tree commit diff
path: root/src/libcore
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/libcore
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/libcore')
-rw-r--r--src/libcore/Cargo.toml2
-rw-r--r--src/libcore/alloc.rs17
-rw-r--r--src/libcore/any.rs22
-rw-r--r--src/libcore/array.rs444
-rw-r--r--src/libcore/ascii.rs10
-rw-r--r--src/libcore/benches/ascii.rs8
-rw-r--r--src/libcore/benches/slice.rs26
-rw-r--r--src/libcore/cell.rs96
-rw-r--r--src/libcore/char/convert.rs2
-rw-r--r--src/libcore/char/methods.rs63
-rw-r--r--src/libcore/clone.rs7
-rw-r--r--src/libcore/cmp.rs30
-rw-r--r--src/libcore/convert.rs62
-rw-r--r--src/libcore/default.rs7
-rw-r--r--src/libcore/ffi.rs228
-rw-r--r--src/libcore/fmt/builders.rs173
-rw-r--r--src/libcore/fmt/float.rs7
-rw-r--r--src/libcore/fmt/mod.rs27
-rw-r--r--src/libcore/fmt/num.rs4
-rw-r--r--src/libcore/future/future.rs10
-rw-r--r--src/libcore/hash/mod.rs21
-rw-r--r--src/libcore/hint.rs52
-rw-r--r--src/libcore/internal_macros.rs81
-rw-r--r--src/libcore/intrinsics.rs125
-rw-r--r--src/libcore/iter/adapters/chain.rs23
-rw-r--r--src/libcore/iter/adapters/flatten.rs137
-rw-r--r--src/libcore/iter/adapters/mod.rs765
-rw-r--r--src/libcore/iter/adapters/zip.rs8
-rw-r--r--src/libcore/iter/mod.rs7
-rw-r--r--src/libcore/iter/range.rs76
-rw-r--r--src/libcore/iter/sources.rs10
-rw-r--r--src/libcore/iter/traits/accum.rs128
-rw-r--r--src/libcore/iter/traits/collect.rs5
-rw-r--r--src/libcore/iter/traits/double_ended.rs32
-rw-r--r--src/libcore/iter/traits/iterator.rs386
-rw-r--r--src/libcore/lib.rs22
-rw-r--r--src/libcore/macros.rs744
-rw-r--r--src/libcore/marker.rs23
-rw-r--r--src/libcore/mem.rs1435
-rw-r--r--src/libcore/mem/manually_drop.rs148
-rw-r--r--src/libcore/mem/maybe_uninit.rs554
-rw-r--r--src/libcore/mem/mod.rs830
-rw-r--r--src/libcore/num/f32.rs144
-rw-r--r--src/libcore/num/f64.rs144
-rw-r--r--src/libcore/num/mod.rs151
-rw-r--r--src/libcore/num/wrapping.rs4
-rw-r--r--src/libcore/ops/arith.rs2
-rw-r--r--src/libcore/ops/deref.rs12
-rw-r--r--src/libcore/ops/function.rs4
-rw-r--r--src/libcore/ops/index.rs4
-rw-r--r--src/libcore/ops/range.rs23
-rw-r--r--src/libcore/ops/try.rs4
-rw-r--r--src/libcore/ops/unsize.rs2
-rw-r--r--src/libcore/option.rs261
-rw-r--r--src/libcore/pin.rs327
-rw-r--r--src/libcore/prelude/v1.rs46
-rw-r--r--src/libcore/ptr/mod.rs (renamed from src/libcore/ptr.rs)829
-rw-r--r--src/libcore/ptr/non_null.rs226
-rw-r--r--src/libcore/ptr/unique.rs188
-rw-r--r--src/libcore/raw.rs4
-rw-r--r--src/libcore/result.rs190
-rw-r--r--src/libcore/slice/mod.rs360
-rw-r--r--src/libcore/slice/rotate.rs221
-rw-r--r--src/libcore/slice/sort.rs4
-rw-r--r--src/libcore/str/lossy.rs4
-rw-r--r--src/libcore/str/mod.rs200
-rw-r--r--src/libcore/sync/atomic.rs16
-rw-r--r--src/libcore/task/poll.rs28
-rw-r--r--src/libcore/task/wake.rs32
-rw-r--r--src/libcore/tests/alloc.rs10
-rw-r--r--src/libcore/tests/ascii.rs2
-rw-r--r--src/libcore/tests/fmt/builders.rs93
-rw-r--r--src/libcore/tests/fmt/mod.rs2
-rw-r--r--src/libcore/tests/iter.rs360
-rw-r--r--src/libcore/tests/lib.rs11
-rw-r--r--src/libcore/tests/num/dec2flt/mod.rs3
-rw-r--r--src/libcore/tests/num/flt2dec/estimator.rs7
-rw-r--r--src/libcore/tests/num/flt2dec/mod.rs16
-rw-r--r--src/libcore/tests/num/flt2dec/random.rs31
-rw-r--r--src/libcore/tests/num/flt2dec/strategy/dragon.rs1
-rw-r--r--src/libcore/tests/num/flt2dec/strategy/grisu.rs1
-rw-r--r--src/libcore/tests/ops.rs17
-rw-r--r--src/libcore/tests/option.rs30
-rw-r--r--src/libcore/tests/pattern.rs2
-rw-r--r--src/libcore/tests/ptr.rs8
-rw-r--r--src/libcore/tests/result.rs185
-rw-r--r--src/libcore/tests/slice.rs212
-rw-r--r--src/libcore/tests/time.rs2
-rw-r--r--src/libcore/time.rs36
-rw-r--r--src/libcore/unicode/printable.py6
-rw-r--r--src/libcore/unicode/printable.rs156
-rw-r--r--src/libcore/unicode/tables.rs1377
-rwxr-xr-xsrc/libcore/unicode/unicode.py1098
93 files changed, 9060 insertions, 4893 deletions
diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml
index ede5fff5f4a..ac07ffb14fe 100644
--- a/src/libcore/Cargo.toml
+++ b/src/libcore/Cargo.toml
@@ -21,7 +21,7 @@ name = "corebenches"
 path = "../libcore/benches/lib.rs"
 
 [dev-dependencies]
-rand = "0.6"
+rand = "0.7"
 
 [features]
 # Make panics and failed asserts immediately abort without formatting any message
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index c124457118c..5d0333d5226 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -99,7 +99,7 @@ impl Layout {
     /// [`Layout::from_size_align`](#method.from_size_align).
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[inline]
-    pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
+    pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
         Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
     }
 
@@ -359,9 +359,12 @@ impl fmt::Display for AllocErr {
     }
 }
 
-/// The `CannotReallocInPlace` error is used when `grow_in_place` or
-/// `shrink_in_place` were unable to reuse the given memory block for
+/// The `CannotReallocInPlace` error is used when [`grow_in_place`] or
+/// [`shrink_in_place`] were unable to reuse the given memory block for
 /// a requested layout.
+///
+/// [`grow_in_place`]: ./trait.Alloc.html#method.grow_in_place
+/// [`shrink_in_place`]: ./trait.Alloc.html#method.shrink_in_place
 #[unstable(feature = "allocator_api", issue = "32838")]
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct CannotReallocInPlace;
@@ -480,7 +483,7 @@ pub unsafe trait GlobalAlloc {
     ///   this allocator,
     ///
     /// * `layout` must be the same layout that was used
-    ///   to allocated that block of memory,
+    ///   to allocate that block of memory,
     #[stable(feature = "global_alloc", since = "1.28.0")]
     unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
 
@@ -535,7 +538,7 @@ pub unsafe trait GlobalAlloc {
     /// * `ptr` must be currently allocated via this allocator,
     ///
     /// * `layout` must be the same layout that was used
-    ///   to allocated that block of memory,
+    ///   to allocate that block of memory,
     ///
     /// * `new_size` must be greater than zero.
     ///
@@ -824,11 +827,11 @@ pub unsafe trait Alloc {
         let old_size = layout.size();
 
         if new_size >= old_size {
-            if let Ok(()) = self.grow_in_place(ptr, layout.clone(), new_size) {
+            if let Ok(()) = self.grow_in_place(ptr, layout, new_size) {
                 return Ok(ptr);
             }
         } else if new_size < old_size {
-            if let Ok(()) = self.shrink_in_place(ptr, layout.clone(), new_size) {
+            if let Ok(()) = self.shrink_in_place(ptr, layout, new_size) {
                 return Ok(ptr);
             }
         }
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index d043ce34eff..e8a0a88f12a 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -450,3 +450,25 @@ impl TypeId {
         }
     }
 }
+
+/// Returns the name of a type as a string slice.
+///
+/// # Note
+///
+/// This is intended for diagnostic use. The exact contents and format of the
+/// string are not specified, other than being a best-effort description of the
+/// type. For example, `type_name::<Option<String>>()` could return the
+/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
+/// `"foobar"`. In addition, the output may change between versions of the
+/// compiler.
+///
+/// The type name should not be considered a unique identifier of a type;
+/// multiple types may share the same type name.
+///
+/// The current implementation uses the same infrastructure as compiler
+/// diagnostics and debuginfo, but this is not guaranteed.
+#[stable(feature = "type_name", since = "1.38.0")]
+#[rustc_const_unstable(feature = "const_type_name")]
+pub const fn type_name<T: ?Sized>() -> &'static str {
+    intrinsics::type_name::<T>()
+}
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 03094bfd333..b5614010e5c 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -24,9 +24,12 @@ use crate::slice::{Iter, IterMut};
 /// layout in memory of a fixed size array (for example, for unsafe
 /// initialization).
 ///
-/// Note that the traits AsRef and AsMut provide similar methods for types that
+/// Note that the traits [`AsRef`] and [`AsMut`] provide similar methods for types that
 /// may not be fixed-size arrays. Implementors should prefer those traits
 /// instead.
+///
+/// [`AsRef`]: ../convert/trait.AsRef.html
+/// [`AsMut`]: ../convert/trait.AsMut.html
 #[unstable(feature = "fixed_size_array", issue = "27778")]
 pub unsafe trait FixedSizeArray<T> {
     /// Converts the array to immutable slice
@@ -81,185 +84,312 @@ impl From<Infallible> for TryFromSliceError {
     }
 }
 
-macro_rules! __impl_slice_eq1 {
-    ($Lhs: ty, $Rhs: ty) => {
-        __impl_slice_eq1! { $Lhs, $Rhs, Sized }
-    };
-    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
-            #[inline]
-            fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] }
-            #[inline]
-            fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, const N: usize> AsRef<[T]> for [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    #[inline]
+    fn as_ref(&self) -> &[T] {
+        &self[..]
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, const N: usize> AsMut<[T]> for [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    #[inline]
+    fn as_mut(&mut self) -> &mut [T] {
+        &mut self[..]
+    }
+}
+
+#[stable(feature = "array_borrow", since = "1.4.0")]
+impl<T, const N: usize> Borrow<[T]> for [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    fn borrow(&self) -> &[T] {
+        self
+    }
+}
+
+#[stable(feature = "array_borrow", since = "1.4.0")]
+impl<T, const N: usize> BorrowMut<[T]> for [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    fn borrow_mut(&mut self) -> &mut [T] {
+        self
+    }
+}
+
+#[stable(feature = "try_from", since = "1.34.0")]
+impl<T, const N: usize> TryFrom<&[T]> for [T; N]
+where
+    T: Copy,
+    [T; N]: LengthAtMost32,
+{
+    type Error = TryFromSliceError;
+
+    fn try_from(slice: &[T]) -> Result<[T; N], TryFromSliceError> {
+        <&Self>::try_from(slice).map(|r| *r)
+    }
+}
+
+#[stable(feature = "try_from", since = "1.34.0")]
+impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    type Error = TryFromSliceError;
+
+    fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> {
+        if slice.len() == N {
+            let ptr = slice.as_ptr() as *const [T; N];
+            unsafe { Ok(&*ptr) }
+        } else {
+            Err(TryFromSliceError(()))
         }
     }
 }
 
-macro_rules! __impl_slice_eq2 {
-    ($Lhs: ty, $Rhs: ty) => {
-        __impl_slice_eq2! { $Lhs, $Rhs, Sized }
-    };
-    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
-        __impl_slice_eq1!($Lhs, $Rhs, $Bound);
-
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> {
-            #[inline]
-            fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] }
-            #[inline]
-            fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] }
+#[stable(feature = "try_from", since = "1.34.0")]
+impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    type Error = TryFromSliceError;
+
+    fn try_from(slice: &mut [T]) -> Result<&mut [T; N], TryFromSliceError> {
+        if slice.len() == N {
+            let ptr = slice.as_mut_ptr() as *mut [T; N];
+            unsafe { Ok(&mut *ptr) }
+        } else {
+            Err(TryFromSliceError(()))
         }
     }
 }
 
-// macro for implementing n-element array functions and operations
-macro_rules! array_impls {
-    ($($N:expr)+) => {
-        $(
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<T> AsRef<[T]> for [T; $N] {
-                #[inline]
-                fn as_ref(&self) -> &[T] {
-                    &self[..]
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Hash, const N: usize> Hash for [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        Hash::hash(&self[..], state)
+    }
+}
 
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<T> AsMut<[T]> for [T; $N] {
-                #[inline]
-                fn as_mut(&mut self) -> &mut [T] {
-                    &mut self[..]
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: fmt::Debug, const N: usize> fmt::Debug for [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(&&self[..], f)
+    }
+}
 
-            #[stable(feature = "array_borrow", since = "1.4.0")]
-            impl<T> Borrow<[T]> for [T; $N] {
-                fn borrow(&self) -> &[T] {
-                    self
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, const N: usize> IntoIterator for &'a [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    type Item = &'a T;
+    type IntoIter = Iter<'a, T>;
 
-            #[stable(feature = "array_borrow", since = "1.4.0")]
-            impl<T> BorrowMut<[T]> for [T; $N] {
-                fn borrow_mut(&mut self) -> &mut [T] {
-                    self
-                }
-            }
+    fn into_iter(self) -> Iter<'a, T> {
+        self.iter()
+    }
+}
 
-            #[stable(feature = "try_from", since = "1.34.0")]
-            impl<T> TryFrom<&[T]> for [T; $N] where T: Copy {
-                type Error = TryFromSliceError;
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    type Item = &'a mut T;
+    type IntoIter = IterMut<'a, T>;
 
-                fn try_from(slice: &[T]) -> Result<[T; $N], TryFromSliceError> {
-                    <&Self>::try_from(slice).map(|r| *r)
-                }
-            }
+    fn into_iter(self) -> IterMut<'a, T> {
+        self.iter_mut()
+    }
+}
 
-            #[stable(feature = "try_from", since = "1.34.0")]
-            impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
-                type Error = TryFromSliceError;
-
-                fn try_from(slice: &[T]) -> Result<&[T; $N], TryFromSliceError> {
-                    if slice.len() == $N {
-                        let ptr = slice.as_ptr() as *const [T; $N];
-                        unsafe { Ok(&*ptr) }
-                    } else {
-                        Err(TryFromSliceError(()))
-                    }
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<[B; N]> for [A; N]
+where
+    A: PartialEq<B>,
+    [A; N]: LengthAtMost32,
+    [B; N]: LengthAtMost32,
+{
+    #[inline]
+    fn eq(&self, other: &[B; N]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &[B; N]) -> bool {
+        self[..] != other[..]
+    }
+}
 
-            #[stable(feature = "try_from", since = "1.34.0")]
-            impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
-                type Error = TryFromSliceError;
-
-                fn try_from(slice: &mut [T]) -> Result<&mut [T; $N], TryFromSliceError> {
-                    if slice.len() == $N {
-                        let ptr = slice.as_mut_ptr() as *mut [T; $N];
-                        unsafe { Ok(&mut *ptr) }
-                    } else {
-                        Err(TryFromSliceError(()))
-                    }
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<[B]> for [A; N]
+where
+    A: PartialEq<B>,
+    [A; N]: LengthAtMost32,
+{
+    #[inline]
+    fn eq(&self, other: &[B]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &[B]) -> bool {
+        self[..] != other[..]
+    }
+}
 
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<T: Hash> Hash for [T; $N] {
-                fn hash<H: hash::Hasher>(&self, state: &mut H) {
-                    Hash::hash(&self[..], state)
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<[A; N]> for [B]
+where
+    B: PartialEq<A>,
+    [A; N]: LengthAtMost32,
+{
+    #[inline]
+    fn eq(&self, other: &[A; N]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &[A; N]) -> bool {
+        self[..] != other[..]
+    }
+}
 
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<T: fmt::Debug> fmt::Debug for [T; $N] {
-                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                    fmt::Debug::fmt(&&self[..], f)
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'b, A, B, const N: usize> PartialEq<&'b [B]> for [A; N]
+where
+    A: PartialEq<B>,
+    [A; N]: LengthAtMost32,
+{
+    #[inline]
+    fn eq(&self, other: &&'b [B]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &&'b [B]) -> bool {
+        self[..] != other[..]
+    }
+}
 
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<'a, T> IntoIterator for &'a [T; $N] {
-                type Item = &'a T;
-                type IntoIter = Iter<'a, T>;
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b [B]
+where
+    B: PartialEq<A>,
+    [A; N]: LengthAtMost32,
+{
+    #[inline]
+    fn eq(&self, other: &[A; N]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &[A; N]) -> bool {
+        self[..] != other[..]
+    }
+}
 
-                fn into_iter(self) -> Iter<'a, T> {
-                    self.iter()
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'b, A, B, const N: usize> PartialEq<&'b mut [B]> for [A; N]
+where
+    A: PartialEq<B>,
+    [A; N]: LengthAtMost32,
+{
+    #[inline]
+    fn eq(&self, other: &&'b mut [B]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &&'b mut [B]) -> bool {
+        self[..] != other[..]
+    }
+}
 
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<'a, T> IntoIterator for &'a mut [T; $N] {
-                type Item = &'a mut T;
-                type IntoIter = IterMut<'a, T>;
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'b, A, B, const N: usize> PartialEq<[A; N]> for &'b mut [B]
+where
+    B: PartialEq<A>,
+    [A; N]: LengthAtMost32,
+{
+    #[inline]
+    fn eq(&self, other: &[A; N]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &[A; N]) -> bool {
+        self[..] != other[..]
+    }
+}
 
-                fn into_iter(self) -> IterMut<'a, T> {
-                    self.iter_mut()
-                }
-            }
+// NOTE: some less important impls are omitted to reduce code bloat
+// __impl_slice_eq2! { [A; $N], &'b [B; $N] }
+// __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
 
-            // NOTE: some less important impls are omitted to reduce code bloat
-            __impl_slice_eq1! { [A; $N], [B; $N] }
-            __impl_slice_eq2! { [A; $N], [B] }
-            __impl_slice_eq2! { [A; $N], &'b [B] }
-            __impl_slice_eq2! { [A; $N], &'b mut [B] }
-            // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
-            // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
-
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<T:Eq> Eq for [T; $N] { }
-
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<T:PartialOrd> PartialOrd for [T; $N] {
-                #[inline]
-                fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
-                    PartialOrd::partial_cmp(&&self[..], &&other[..])
-                }
-                #[inline]
-                fn lt(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::lt(&&self[..], &&other[..])
-                }
-                #[inline]
-                fn le(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::le(&&self[..], &&other[..])
-                }
-                #[inline]
-                fn ge(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::ge(&&self[..], &&other[..])
-                }
-                #[inline]
-                fn gt(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::gt(&&self[..], &&other[..])
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Eq, const N: usize> Eq for [T; N] where [T; N]: LengthAtMost32 {}
 
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<T:Ord> Ord for [T; $N] {
-                #[inline]
-                fn cmp(&self, other: &[T; $N]) -> Ordering {
-                    Ord::cmp(&&self[..], &&other[..])
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: PartialOrd, const N: usize> PartialOrd for [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    #[inline]
+    fn partial_cmp(&self, other: &[T; N]) -> Option<Ordering> {
+        PartialOrd::partial_cmp(&&self[..], &&other[..])
+    }
+    #[inline]
+    fn lt(&self, other: &[T; N]) -> bool {
+        PartialOrd::lt(&&self[..], &&other[..])
+    }
+    #[inline]
+    fn le(&self, other: &[T; N]) -> bool {
+        PartialOrd::le(&&self[..], &&other[..])
+    }
+    #[inline]
+    fn ge(&self, other: &[T; N]) -> bool {
+        PartialOrd::ge(&&self[..], &&other[..])
+    }
+    #[inline]
+    fn gt(&self, other: &[T; N]) -> bool {
+        PartialOrd::gt(&&self[..], &&other[..])
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Ord, const N: usize> Ord for [T; N]
+where
+    [T; N]: LengthAtMost32,
+{
+    #[inline]
+    fn cmp(&self, other: &[T; N]) -> Ordering {
+        Ord::cmp(&&self[..], &&other[..])
+    }
+}
+
+/// Implemented for lengths where trait impls are allowed on arrays in core/std
+#[rustc_on_unimplemented(
+    message="arrays only have std trait implementations for lengths 0..=32",
+)]
+#[unstable(feature = "const_generic_impls_guard", issue = "0",
+    reason = "will never be stable, just a temporary step until const generics are stable")]
+pub trait LengthAtMost32 {}
+
+macro_rules! array_impls {
+    ($($N:literal)+) => {
+        $(
+            #[unstable(feature = "const_generic_impls_guard", issue = "0")]
+            impl<T> LengthAtMost32 for [T; $N] {}
         )+
     }
 }
diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs
index ddee02ea232..4087333e2cf 100644
--- a/src/libcore/ascii.rs
+++ b/src/libcore/ascii.rs
@@ -14,6 +14,7 @@
 use crate::fmt;
 use crate::ops::Range;
 use crate::iter::FusedIterator;
+use crate::str::from_utf8_unchecked;
 
 /// An iterator over the escaped version of a byte.
 ///
@@ -22,6 +23,7 @@ use crate::iter::FusedIterator;
 ///
 /// [`escape_default`]: fn.escape_default.html
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone)]
 pub struct EscapeDefault {
     range: Range<usize>,
     data: [u8; 4],
@@ -117,7 +119,6 @@ impl Iterator for EscapeDefault {
     type Item = u8;
     fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
     fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
-    #[inline]
     fn last(mut self) -> Option<u8> { self.next_back() }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -131,6 +132,13 @@ impl ExactSizeIterator for EscapeDefault {}
 #[stable(feature = "fused", since = "1.26.0")]
 impl FusedIterator for EscapeDefault {}
 
+#[stable(feature = "ascii_escape_display", since = "1.39.0")]
+impl fmt::Display for EscapeDefault {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(unsafe { from_utf8_unchecked(&self.data[self.range.clone()]) })
+    }
+}
+
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for EscapeDefault {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/src/libcore/benches/ascii.rs b/src/libcore/benches/ascii.rs
index 10b6cc61d99..a337c467131 100644
--- a/src/libcore/benches/ascii.rs
+++ b/src/libcore/benches/ascii.rs
@@ -191,7 +191,7 @@ benches! {
     fn case11_mask_mult_bool_match_range(bytes: &mut [u8]) {
         fn is_ascii_lowercase(b: u8) -> bool {
             match b {
-                b'a'...b'z' => true,
+                b'a'..=b'z' => true,
                 _ => false
             }
         }
@@ -203,7 +203,7 @@ benches! {
     fn case12_mask_shifted_bool_match_range(bytes: &mut [u8]) {
         fn is_ascii_lowercase(b: u8) -> bool {
             match b {
-                b'a'...b'z' => true,
+                b'a'..=b'z' => true,
                 _ => false
             }
         }
@@ -215,7 +215,7 @@ benches! {
     fn case13_subtract_shifted_bool_match_range(bytes: &mut [u8]) {
         fn is_ascii_lowercase(b: u8) -> bool {
             match b {
-                b'a'...b'z' => true,
+                b'a'..=b'z' => true,
                 _ => false
             }
         }
@@ -227,7 +227,7 @@ benches! {
     fn case14_subtract_multiplied_bool_match_range(bytes: &mut [u8]) {
         fn is_ascii_lowercase(b: u8) -> bool {
             match b {
-                b'a'...b'z' => true,
+                b'a'..=b'z' => true,
                 _ => false
             }
         }
diff --git a/src/libcore/benches/slice.rs b/src/libcore/benches/slice.rs
index 484753c1a04..711a8dff2c0 100644
--- a/src/libcore/benches/slice.rs
+++ b/src/libcore/benches/slice.rs
@@ -55,3 +55,29 @@ fn binary_search_l2_with_dups(b: &mut Bencher) {
 fn binary_search_l3_with_dups(b: &mut Bencher) {
     binary_search(b, Cache::L3, |i| i / 16 * 16);
 }
+
+macro_rules! rotate {
+    ($fn:ident, $n:expr, $mapper:expr) => {
+        #[bench]
+        fn $fn(b: &mut Bencher) {
+            let mut x = (0usize..$n).map(&$mapper).collect::<Vec<_>>();
+            b.iter(|| {
+                for s in 0..x.len() {
+                    x[..].rotate_right(s);
+                }
+                black_box(x[0].clone())
+            })
+        }
+    };
+}
+
+#[derive(Clone)]
+struct Rgb(u8, u8, u8);
+
+rotate!(rotate_u8, 32, |i| i as u8);
+rotate!(rotate_rgb, 32, |i| Rgb(i as u8, (i as u8).wrapping_add(7), (i as u8).wrapping_add(42)));
+rotate!(rotate_usize, 32, |i| i);
+rotate!(rotate_16_usize_4, 16, |i| [i; 4]);
+rotate!(rotate_16_usize_5, 16, |i| [i; 5]);
+rotate!(rotate_64_usize_4, 64, |i| [i; 4]);
+rotate!(rotate_64_usize_5, 64, |i| [i; 5]);
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index fcfd80d9266..8579dbf353e 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -11,7 +11,7 @@
 //! mutate it.
 //!
 //! Shareable mutable containers exist to permit mutability in a controlled manner, even in the
-//! presence of aliasing. Both `Cell<T>` and `RefCell<T>` allows to do this in a single threaded
+//! presence of aliasing. Both `Cell<T>` and `RefCell<T>` allow doing this in a single-threaded
 //! way. However, neither `Cell<T>` nor `RefCell<T>` are thread safe (they do not implement
 //! `Sync`). If you need to do aliasing and mutation between multiple threads it is possible to
 //! use [`Mutex`](../../std/sync/struct.Mutex.html),
@@ -67,16 +67,26 @@
 //! mutability:
 //!
 //! ```
+//! use std::cell::{RefCell, RefMut};
 //! use std::collections::HashMap;
-//! use std::cell::RefCell;
 //! use std::rc::Rc;
 //!
 //! fn main() {
 //!     let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
-//!     shared_map.borrow_mut().insert("africa", 92388);
-//!     shared_map.borrow_mut().insert("kyoto", 11837);
-//!     shared_map.borrow_mut().insert("piccadilly", 11826);
-//!     shared_map.borrow_mut().insert("marbles", 38);
+//!     // Create a new block to limit the scope of the dynamic borrow
+//!     {
+//!         let mut map: RefMut<_> = shared_map.borrow_mut();
+//!         map.insert("africa", 92388);
+//!         map.insert("kyoto", 11837);
+//!         map.insert("piccadilly", 11826);
+//!         map.insert("marbles", 38);
+//!     }
+//!
+//!     // Note that if we had not let the previous borrow of the cache fall out
+//!     // of scope then the subsequent borrow would cause a dynamic thread panic.
+//!     // This is the major hazard of using `RefCell`.
+//!     let total: i32 = shared_map.borrow().values().sum();
+//!     println!("{}", total);
 //! }
 //! ```
 //!
@@ -102,27 +112,15 @@
 //!
 //! impl Graph {
 //!     fn minimum_spanning_tree(&self) -> Vec<(i32, i32)> {
-//!         // Create a new scope to contain the lifetime of the
-//!         // dynamic borrow
-//!         {
-//!             // Take a reference to the inside of cache cell
-//!             let mut cache = self.span_tree_cache.borrow_mut();
-//!             if cache.is_some() {
-//!                 return cache.as_ref().unwrap().clone();
-//!             }
-//!
-//!             let span_tree = self.calc_span_tree();
-//!             *cache = Some(span_tree);
-//!         }
+//!         self.span_tree_cache.borrow_mut()
+//!             .get_or_insert_with(|| self.calc_span_tree())
+//!             .clone()
+//!     }
 //!
-//!         // Recursive call to return the just-cached value.
-//!         // Note that if we had not let the previous borrow
-//!         // of the cache fall out of scope then the subsequent
-//!         // recursive borrow would cause a dynamic thread panic.
-//!         // This is the major hazard of using `RefCell`.
-//!         self.minimum_spanning_tree()
+//!     fn calc_span_tree(&self) -> Vec<(i32, i32)> {
+//!         // Expensive computation goes here
+//!         vec![]
 //!     }
-//! #   fn calc_span_tree(&self) -> Vec<(i32, i32)> { vec![] }
 //! }
 //! ```
 //!
@@ -292,7 +290,7 @@ impl<T:Copy> Clone for Cell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T:Default> Default for Cell<T> {
+impl<T: Default> Default for Cell<T> {
     /// Creates a `Cell<T>`, with the `Default` value for T.
     #[inline]
     fn default() -> Cell<T> {
@@ -301,7 +299,7 @@ impl<T:Default> Default for Cell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T:PartialEq + Copy> PartialEq for Cell<T> {
+impl<T: PartialEq + Copy> PartialEq for Cell<T> {
     #[inline]
     fn eq(&self, other: &Cell<T>) -> bool {
         self.get() == other.get()
@@ -309,10 +307,10 @@ impl<T:PartialEq + Copy> PartialEq for Cell<T> {
 }
 
 #[stable(feature = "cell_eq", since = "1.2.0")]
-impl<T:Eq + Copy> Eq for Cell<T> {}
+impl<T: Eq + Copy> Eq for Cell<T> {}
 
 #[stable(feature = "cell_ord", since = "1.10.0")]
-impl<T:PartialOrd + Copy> PartialOrd for Cell<T> {
+impl<T: PartialOrd + Copy> PartialOrd for Cell<T> {
     #[inline]
     fn partial_cmp(&self, other: &Cell<T>) -> Option<Ordering> {
         self.get().partial_cmp(&other.get())
@@ -340,7 +338,7 @@ impl<T:PartialOrd + Copy> PartialOrd for Cell<T> {
 }
 
 #[stable(feature = "cell_ord", since = "1.10.0")]
-impl<T:Ord + Copy> Ord for Cell<T> {
+impl<T: Ord + Copy> Ord for Cell<T> {
     #[inline]
     fn cmp(&self, other: &Cell<T>) -> Ordering {
         self.get().cmp(&other.get())
@@ -496,7 +494,6 @@ impl<T: ?Sized> Cell<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(as_cell)]
     /// use std::cell::Cell;
     ///
     /// let slice: &mut [i32] = &mut [1, 2, 3];
@@ -506,7 +503,7 @@ impl<T: ?Sized> Cell<T> {
     /// assert_eq!(slice_cell.len(), 3);
     /// ```
     #[inline]
-    #[unstable(feature = "as_cell", issue="43038")]
+    #[stable(feature = "as_cell", since = "1.37.0")]
     pub fn from_mut(t: &mut T) -> &Cell<T> {
         unsafe {
             &*(t as *mut T as *const Cell<T>)
@@ -543,7 +540,6 @@ impl<T> Cell<[T]> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(as_cell)]
     /// use std::cell::Cell;
     ///
     /// let slice: &mut [i32] = &mut [1, 2, 3];
@@ -552,7 +548,7 @@ impl<T> Cell<[T]> {
     ///
     /// assert_eq!(slice_cell.len(), 3);
     /// ```
-    #[unstable(feature = "as_cell", issue="43038")]
+    #[stable(feature = "as_cell", since = "1.37.0")]
     pub fn as_slice_of_cells(&self) -> &[Cell<T>] {
         unsafe {
             &*(self as *const Cell<[T]> as *const [Cell<T>])
@@ -969,7 +965,6 @@ impl<T: ?Sized> RefCell<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(borrow_state)]
     /// use std::cell::RefCell;
     ///
     /// let c = RefCell::new(5);
@@ -984,7 +979,7 @@ impl<T: ?Sized> RefCell<T> {
     ///     assert!(unsafe { c.try_borrow_unguarded() }.is_ok());
     /// }
     /// ```
-    #[unstable(feature = "borrow_state", issue = "27733")]
+    #[stable(feature = "borrow_state", since = "1.37.0")]
     #[inline]
     pub unsafe fn try_borrow_unguarded(&self) -> Result<&T, BorrowError> {
         if !is_writing(self.borrow.get()) {
@@ -1013,7 +1008,7 @@ impl<T: Clone> Clone for RefCell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T:Default> Default for RefCell<T> {
+impl<T: Default> Default for RefCell<T> {
     /// Creates a `RefCell<T>`, with the `Default` value for T.
     #[inline]
     fn default() -> RefCell<T> {
@@ -1106,13 +1101,23 @@ struct BorrowRef<'b> {
 impl<'b> BorrowRef<'b> {
     #[inline]
     fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
-        let b = borrow.get();
-        if is_writing(b) || b == isize::max_value() {
-            // If there's currently a writing borrow, or if incrementing the
-            // refcount would overflow into a writing borrow.
+        let b = borrow.get().wrapping_add(1);
+        if !is_reading(b) {
+            // Incrementing borrow can result in a non-reading value (<= 0) in these cases:
+            // 1. It was < 0, i.e. there are writing borrows, so we can't allow a read borrow
+            //    due to Rust's reference aliasing rules
+            // 2. It was isize::max_value() (the max amount of reading borrows) and it overflowed
+            //    into isize::min_value() (the max amount of writing borrows) so we can't allow
+            //    an additional read borrow because isize can't represent so many read borrows
+            //    (this can only happen if you mem::forget more than a small constant amount of
+            //    `Ref`s, which is not good practice)
             None
         } else {
-            borrow.set(b + 1);
+            // Incrementing borrow can result in a reading value (> 0) in these cases:
+            // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow
+            // 2. It was > 0 and < isize::max_value(), i.e. there were read borrows, and isize
+            //    is large enough to represent having one more read borrow
+            borrow.set(b);
             Some(BorrowRef { borrow })
         }
     }
@@ -1354,7 +1359,7 @@ impl<'b> BorrowRefMut<'b> {
         }
     }
 
-    // Clone a `BorrowRefMut`.
+    // Clones a `BorrowRefMut`.
     //
     // This is only valid if each `BorrowRefMut` is used to track a mutable
     // reference to a distinct, nonoverlapping range of the original object.
@@ -1417,8 +1422,9 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are
 /// immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably
 /// aliased or mutated, and that `&mut T` is unique. `UnsafeCell<T>` is the only core language
-/// feature to work around this restriction. All other types that allow internal mutability, such as
-/// `Cell<T>` and `RefCell<T>`, use `UnsafeCell` to wrap their internal data.
+/// feature to work around the restriction that `&T` may not be mutated. All other types that
+/// allow internal mutability, such as `Cell<T>` and `RefCell<T>`, use `UnsafeCell` to wrap their
+/// internal data. There is *no* legal way to obtain aliasing `&mut`, not even with `UnsafeCell<T>`.
 ///
 /// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to
 /// its contents. It is up to _you_ as the abstraction designer to use that raw pointer correctly.
diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs
index ec9ac7ce8b1..0a870c67518 100644
--- a/src/libcore/char/convert.rs
+++ b/src/libcore/char/convert.rs
@@ -123,7 +123,7 @@ impl From<char> for u32 {
     }
 }
 
-/// Maps a byte in 0x00...0xFF to a `char` whose code point has the same value, in U+0000 to U+00FF.
+/// Maps a byte in 0x00..=0xFF to a `char` whose code point has the same value, in U+0000..=U+00FF.
 ///
 /// Unicode is designed such that this effectively decodes bytes
 /// with the character encoding that IANA calls ISO-8859-1.
diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index 18557e0c11d..e91bf53c5b4 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -337,16 +337,16 @@ impl char {
     /// ```
     /// // as chars
     /// let eastern = '東';
-    /// let capitol = '京';
+    /// let capital = '京';
     ///
     /// // both can be represented as three bytes
     /// assert_eq!(3, eastern.len_utf8());
-    /// assert_eq!(3, capitol.len_utf8());
+    /// assert_eq!(3, capital.len_utf8());
     ///
     /// // as a &str, these two are encoded in UTF-8
     /// let tokyo = "東京";
     ///
-    /// let len = eastern.len_utf8() + capitol.len_utf8();
+    /// let len = eastern.len_utf8() + capital.len_utf8();
     ///
     /// // we can see that they take six bytes total...
     /// assert_eq!(6, tokyo.len());
@@ -547,29 +547,24 @@ impl char {
         }
     }
 
-    /// Returns `true` if this `char` satisfies the 'XID_Start' Unicode property, and false
+    /// Returns `true` if this `char` satisfies the `XID_Start` Unicode property, and false
     /// otherwise.
     ///
-    /// 'XID_Start' is a Unicode Derived Property specified in
+    /// `XID_Start` is a Unicode Derived Property specified in
     /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
     /// mostly similar to `ID_Start` but modified for closure under `NFKx`.
-    #[unstable(feature = "rustc_private",
-               reason = "mainly needed for compiler internals",
-               issue = "27812")]
-    #[inline]
+    #[unstable(feature = "unicode_internals", issue = "0")]
     pub fn is_xid_start(self) -> bool {
         derived_property::XID_Start(self)
     }
 
-    /// Returns `true` if this `char` satisfies the 'XID_Continue' Unicode property, and false
+    /// Returns `true` if this `char` satisfies the `XID_Continue` Unicode property, and false
     /// otherwise.
     ///
-    /// 'XID_Continue' is a Unicode Derived Property specified in
+    /// `XID_Continue` is a Unicode Derived Property specified in
     /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
-    #[unstable(feature = "rustc_private",
-               reason = "mainly needed for compiler internals",
-               issue = "27812")]
+    /// mostly similar to `ID_Continue` but modified for closure under NFKx.
+    #[unstable(feature = "unicode_internals", issue = "0")]
     #[inline]
     pub fn is_xid_continue(self) -> bool {
         derived_property::XID_Continue(self)
@@ -661,7 +656,7 @@ impl char {
     /// Returns `true` if this `char` is alphanumeric.
     ///
     /// 'Alphanumeric'-ness is defined in terms of the Unicode General Categories
-    /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+    /// `Nd`, `Nl`, `No` and the Derived Core Property `Alphabetic`.
     ///
     /// # Examples
     ///
@@ -715,7 +710,7 @@ impl char {
     /// Returns `true` if this `char` is numeric.
     ///
     /// 'Numeric'-ness is defined in terms of the Unicode General Categories
-    /// 'Nd', 'Nl', 'No'.
+    /// `Nd`, `Nl`, `No`.
     ///
     /// # Examples
     ///
@@ -1042,8 +1037,8 @@ impl char {
 
     /// Checks if the value is an ASCII alphabetic character:
     ///
-    /// - U+0041 'A' ... U+005A 'Z', or
-    /// - U+0061 'a' ... U+007A 'z'.
+    /// - U+0041 'A' ..= U+005A 'Z', or
+    /// - U+0061 'a' ..= U+007A 'z'.
     ///
     /// # Examples
     ///
@@ -1075,7 +1070,7 @@ impl char {
     }
 
     /// Checks if the value is an ASCII uppercase character:
-    /// U+0041 'A' ... U+005A 'Z'.
+    /// U+0041 'A' ..= U+005A 'Z'.
     ///
     /// # Examples
     ///
@@ -1107,7 +1102,7 @@ impl char {
     }
 
     /// Checks if the value is an ASCII lowercase character:
-    /// U+0061 'a' ... U+007A 'z'.
+    /// U+0061 'a' ..= U+007A 'z'.
     ///
     /// # Examples
     ///
@@ -1140,9 +1135,9 @@ impl char {
 
     /// Checks if the value is an ASCII alphanumeric character:
     ///
-    /// - U+0041 'A' ... U+005A 'Z', or
-    /// - U+0061 'a' ... U+007A 'z', or
-    /// - U+0030 '0' ... U+0039 '9'.
+    /// - U+0041 'A' ..= U+005A 'Z', or
+    /// - U+0061 'a' ..= U+007A 'z', or
+    /// - U+0030 '0' ..= U+0039 '9'.
     ///
     /// # Examples
     ///
@@ -1174,7 +1169,7 @@ impl char {
     }
 
     /// Checks if the value is an ASCII decimal digit:
-    /// U+0030 '0' ... U+0039 '9'.
+    /// U+0030 '0' ..= U+0039 '9'.
     ///
     /// # Examples
     ///
@@ -1207,9 +1202,9 @@ impl char {
 
     /// Checks if the value is an ASCII hexadecimal digit:
     ///
-    /// - U+0030 '0' ... U+0039 '9', or
-    /// - U+0041 'A' ... U+0046 'F', or
-    /// - U+0061 'a' ... U+0066 'f'.
+    /// - U+0030 '0' ..= U+0039 '9', or
+    /// - U+0041 'A' ..= U+0046 'F', or
+    /// - U+0061 'a' ..= U+0066 'f'.
     ///
     /// # Examples
     ///
@@ -1242,10 +1237,10 @@ impl char {
 
     /// Checks if the value is an ASCII punctuation character:
     ///
-    /// - U+0021 ... U+002F `! " # $ % & ' ( ) * + , - . /`, or
-    /// - U+003A ... U+0040 `: ; < = > ? @`, or
-    /// - U+005B ... U+0060 ``[ \ ] ^ _ ` ``, or
-    /// - U+007B ... U+007E `{ | } ~`
+    /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
+    /// - U+003A ..= U+0040 `: ; < = > ? @`, or
+    /// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
+    /// - U+007B ..= U+007E `{ | } ~`
     ///
     /// # Examples
     ///
@@ -1277,7 +1272,7 @@ impl char {
     }
 
     /// Checks if the value is an ASCII graphic character:
-    /// U+0021 '!' ... U+007E '~'.
+    /// U+0021 '!' ..= U+007E '~'.
     ///
     /// # Examples
     ///
@@ -1358,7 +1353,7 @@ impl char {
     }
 
     /// Checks if the value is an ASCII control character:
-    /// U+0000 NUL ... U+001F UNIT SEPARATOR, or U+007F DELETE.
+    /// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
     /// Note that most ASCII whitespace characters are control
     /// characters, but SPACE is not.
     ///
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index 9e32acb97d3..ec70d396e96 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -133,6 +133,13 @@ pub trait Clone : Sized {
     }
 }
 
+/// Derive macro generating an impl of the trait `Clone`.
+#[rustc_builtin_macro]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
+pub macro Clone($item:item) { /* compiler built-in */ }
+
 // FIXME(aburka): these structs are used solely by #[derive] to
 // assert that every component of a type implements Clone or Copy.
 //
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 59088e43291..cb9feb074dd 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -200,6 +200,13 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
     fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
 }
 
+/// Derive macro generating an impl of the trait `PartialEq`.
+#[rustc_builtin_macro]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics)]
+pub macro PartialEq($item:item) { /* compiler built-in */ }
+
 /// Trait for equality comparisons which are [equivalence relations](
 /// https://en.wikipedia.org/wiki/Equivalence_relation).
 ///
@@ -256,6 +263,13 @@ pub trait Eq: PartialEq<Self> {
     fn assert_receiver_is_total_eq(&self) {}
 }
 
+/// Derive macro generating an impl of the trait `Eq`.
+#[rustc_builtin_macro]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics, derive_eq)]
+pub macro Eq($item:item) { /* compiler built-in */ }
+
 // FIXME: this struct is used solely by #[derive] to
 // assert that every component of a type implements Eq.
 //
@@ -319,7 +333,7 @@ impl Ordering {
     /// This method can be used to reverse a comparison:
     ///
     /// ```
-    /// let mut data: &mut [_] = &mut [2, 10, 5, 8];
+    /// let data: &mut [_] = &mut [2, 10, 5, 8];
     ///
     /// // sort the array from largest to smallest.
     /// data.sort_by(|a, b| a.cmp(b).reverse());
@@ -600,6 +614,13 @@ pub trait Ord: Eq + PartialOrd<Self> {
     }
 }
 
+/// Derive macro generating an impl of the trait `Ord`.
+#[rustc_builtin_macro]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics)]
+pub macro Ord($item:item) { /* compiler built-in */ }
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Eq for Ordering {}
 
@@ -842,6 +863,13 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     }
 }
 
+/// Derive macro generating an impl of the trait `PartialOrd`.
+#[rustc_builtin_macro]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics)]
+pub macro PartialOrd($item:item) { /* compiler built-in */ }
+
 /// Compares and returns the minimum of two values.
 ///
 /// Returns the first argument if the comparison determines them to be equal.
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index b3ff447be5e..641621f492b 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -129,7 +129,7 @@ pub const fn identity<T>(x: T) -> T { x }
 /// # Examples
 ///
 /// By using trait bounds we can accept arguments of different types as long as they can be
-/// converted a the specified type `T`.
+/// converted to the specified type `T`.
 ///
 /// For example: By creating a generic function that takes an `AsRef<str>` we express that we
 /// want to accept all references that can be converted to `&str` as an argument.
@@ -177,8 +177,8 @@ pub trait AsRef<T: ?Sized> {
 ///
 /// Using `AsMut` as trait bound for a generic function we can accept all mutable references
 /// that can be converted to type `&mut T`. Because [`Box<T>`] implements `AsMut<T>` we can
-/// write a function `add_one`that takes all arguments that can be converted to `&mut u64`.
-/// Because [`Box<T>`] implements `AsMut<T>` `add_one` accepts arguments of type
+/// write a function `add_one` that takes all arguments that can be converted to `&mut u64`.
+/// Because [`Box<T>`] implements `AsMut<T>`, `add_one` accepts arguments of type
 /// `&mut Box<u64>` as well:
 ///
 /// ```
@@ -202,9 +202,9 @@ pub trait AsMut<T: ?Sized> {
 /// A value-to-value conversion that consumes the input value. The
 /// opposite of [`From`].
 ///
-/// One should only implement `Into` if a conversion to a type outside the current crate is
-/// required. Otherwise one should always prefer implementing [`From`] over `Into` because
-/// implementing [`From`] automatically provides one with a implementation of `Into` thanks to
+/// One should only implement [`Into`] if a conversion to a type outside the current crate is
+/// required. Otherwise one should always prefer implementing [`From`] over [`Into`] because
+/// implementing [`From`] automatically provides one with a implementation of [`Into`] thanks to
 /// the blanket implementation in the standard library. [`From`] cannot do these type of
 /// conversions because of Rust's orphaning rules.
 ///
@@ -213,9 +213,9 @@ pub trait AsMut<T: ?Sized> {
 /// # Generic Implementations
 ///
 /// - [`From`]`<T> for U` implies `Into<U> for T`
-/// - `Into` is reflexive, which means that `Into<T> for T` is implemented
+/// - [`Into`] is reflexive, which means that `Into<T> for T` is implemented
 ///
-/// # Implementing `Into` for conversions to external types
+/// # Implementing [`Into`] for conversions to external types
 ///
 /// If the destination type is not part of the current crate
 /// then you can't implement [`From`] directly.
@@ -231,7 +231,7 @@ pub trait AsMut<T: ?Sized> {
 /// ```
 /// This will fail to compile because we cannot implement a trait for a type
 /// if both the trait and the type are not defined by the current crate.
-/// This is due to Rust's orphaning rules. To bypass this, you can implement `Into` directly:
+/// This is due to Rust's orphaning rules. To bypass this, you can implement [`Into`] directly:
 ///
 /// ```
 /// struct Wrapper<T>(Vec<T>);
@@ -242,21 +242,21 @@ pub trait AsMut<T: ?Sized> {
 /// }
 /// ```
 ///
-/// It is important to understand that `Into` does not provide a [`From`] implementation
-/// (as [`From`] does with `Into`). Therefore, you should always try to implement [`From`]
-/// and then fall back to `Into` if [`From`] can't be implemented.
+/// It is important to understand that [`Into`] does not provide a [`From`] implementation
+/// (as [`From`] does with [`Into`]). Therefore, you should always try to implement [`From`]
+/// and then fall back to [`Into`] if [`From`] can't be implemented.
 ///
-/// Prefer using `Into` over [`From`] when specifying trait bounds on a generic function
-/// to ensure that types that only implement `Into` can be used as well.
+/// Prefer using [`Into`] over [`From`] when specifying trait bounds on a generic function
+/// to ensure that types that only implement [`Into`] can be used as well.
 ///
 /// # Examples
 ///
-/// [`String`] implements `Into<Vec<u8>>`:
+/// [`String`] implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>`:
 ///
 /// In order to express that we want a generic function to take all arguments that can be
-/// converted to a specified type `T`, we can use a trait bound of `Into<T>`.
+/// converted to a specified type `T`, we can use a trait bound of [`Into`]`<T>`.
 /// For example: The function `is_hello` takes all arguments that can be converted into a
-/// `Vec<u8>`.
+/// [`Vec`]`<`[`u8`]`>`.
 ///
 /// ```
 /// fn is_hello<T: Into<Vec<u8>>>(s: T) {
@@ -273,7 +273,8 @@ pub trait AsMut<T: ?Sized> {
 /// [`Result<T, E>`]: ../../std/result/enum.Result.html
 /// [`String`]: ../../std/string/struct.String.html
 /// [`From`]: trait.From.html
-/// [`into`]: trait.Into.html#tymethod.into
+/// [`Into`]: trait.Into.html
+/// [`Vec`]: ../../std/vec/struct.Vec.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Into<T>: Sized {
     /// Performs the conversion.
@@ -410,12 +411,12 @@ pub trait TryInto<T>: Sized {
 ///
 /// This is useful when you are doing a type conversion that may
 /// trivially succeed but may also need special handling.
-/// For example, there is no way to convert an `i64` into an `i32`
-/// using the [`From`] trait, because an `i64` may contain a value
-/// that an `i32` cannot represent and so the conversion would lose data.
-/// This might be handled by truncating the `i64` to an `i32` (essentially
-/// giving the `i64`'s value modulo `i32::MAX`) or by simply returning
-/// `i32::MAX`, or by some other method.  The `From` trait is intended
+/// For example, there is no way to convert an [`i64`] into an [`i32`]
+/// using the [`From`] trait, because an [`i64`] may contain a value
+/// that an [`i32`] cannot represent and so the conversion would lose data.
+/// This might be handled by truncating the [`i64`] to an [`i32`] (essentially
+/// giving the [`i64`]'s value modulo [`i32::MAX`]) or by simply returning
+/// [`i32::MAX`], or by some other method.  The [`From`] trait is intended
 /// for perfect conversions, so the `TryFrom` trait informs the
 /// programmer when a type conversion could go bad and lets them
 /// decide how to handle it.
@@ -425,8 +426,8 @@ pub trait TryInto<T>: Sized {
 /// - `TryFrom<T> for U` implies [`TryInto`]`<U> for T`
 /// - [`try_from`] is reflexive, which means that `TryFrom<T> for T`
 /// is implemented and cannot fail -- the associated `Error` type for
-/// calling `T::try_from()` on a value of type `T` is `Infallible`.
-/// When the `!` type is stablized `Infallible` and `!` will be
+/// calling `T::try_from()` on a value of type `T` is [`Infallible`].
+/// When the [`!`] type is stabilized [`Infallible`] and [`!`] will be
 /// equivalent.
 ///
 /// `TryFrom<T>` can be implemented as follows:
@@ -451,7 +452,7 @@ pub trait TryInto<T>: Sized {
 ///
 /// # Examples
 ///
-/// As described, [`i32`] implements `TryFrom<i64>`:
+/// As described, [`i32`] implements `TryFrom<`[`i64`]`>`:
 ///
 /// ```
 /// use std::convert::TryFrom;
@@ -474,6 +475,9 @@ pub trait TryInto<T>: Sized {
 ///
 /// [`try_from`]: trait.TryFrom.html#tymethod.try_from
 /// [`TryInto`]: trait.TryInto.html
+/// [`i32::MAX`]: ../../std/i32/constant.MAX.html
+/// [`!`]: ../../std/primitive.never.html
+/// [`Infallible`]: enum.Infallible.html
 #[stable(feature = "try_from", since = "1.34.0")]
 pub trait TryFrom<T>: Sized {
     /// The type returned in the event of a conversion error.
@@ -509,7 +513,7 @@ impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T where T: AsRef<U>
 
 // FIXME (#45742): replace the above impls for &/&mut with the following more general one:
 // // As lifts over Deref
-// impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> {
+// impl<D: ?Sized + Deref<Target: AsRef<U>>, U: ?Sized> AsRef<U> for D {
 //     fn as_ref(&self) -> &U {
 //         self.deref().as_ref()
 //     }
@@ -526,7 +530,7 @@ impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T where T: AsMut<U>
 
 // FIXME (#45742): replace the above impl for &mut with the following more general one:
 // // AsMut lifts over DerefMut
-// impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> {
+// impl<D: ?Sized + Deref<Target: AsMut<U>>, U: ?Sized> AsMut<U> for D {
 //     fn as_mut(&mut self) -> &mut U {
 //         self.deref_mut().as_mut()
 //     }
diff --git a/src/libcore/default.rs b/src/libcore/default.rs
index 5ad05b38247..66acc5165fc 100644
--- a/src/libcore/default.rs
+++ b/src/libcore/default.rs
@@ -115,6 +115,13 @@ pub trait Default: Sized {
     fn default() -> Self;
 }
 
+/// Derive macro generating an impl of the trait `Default`.
+#[rustc_builtin_macro]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics)]
+pub macro Default($item:item) { /* compiler built-in */ }
+
 macro_rules! default_impl {
     ($t:ty, $v:expr, $doc:tt) => {
         #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index 2906e5824ae..eda0e7c518c 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -5,6 +5,8 @@
 //! Utilities related to FFI bindings.
 
 use crate::fmt;
+use crate::marker::PhantomData;
+use crate::ops::{Deref, DerefMut};
 
 /// Equivalent to C's `void` type when used as a [pointer].
 ///
@@ -45,25 +47,36 @@ impl fmt::Debug for c_void {
 }
 
 /// Basic implementation of a `va_list`.
+// The name is WIP, using `VaListImpl` for now.
 #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
-              not(target_arch = "x86_64")),
+              not(target_arch = "x86_64"), not(target_arch = "asmjs")),
           all(target_arch = "aarch64", target_os = "ios"),
           windows))]
+#[repr(transparent)]
 #[unstable(feature = "c_variadic",
            reason = "the `c_variadic` feature has not been properly tested on \
                      all supported platforms",
            issue = "44930")]
-extern {
-    type VaListImpl;
+#[lang = "va_list"]
+pub struct VaListImpl<'f> {
+    ptr: *mut c_void,
+
+    // Invariant over `'f`, so each `VaListImpl<'f>` object is tied to
+    // the region of the function it's defined in
+    _marker: PhantomData<&'f mut &'f c_void>,
 }
 
 #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
-              not(target_arch = "x86_64")),
+              not(target_arch = "x86_64"), not(target_arch = "asmjs")),
           all(target_arch = "aarch64", target_os = "ios"),
           windows))]
-impl fmt::Debug for VaListImpl {
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+impl<'f> fmt::Debug for VaListImpl<'f> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "va_list* {:p}", self)
+        write!(f, "va_list* {:p}", self.ptr)
     }
 }
 
@@ -79,12 +92,14 @@ impl fmt::Debug for VaListImpl {
            reason = "the `c_variadic` feature has not been properly tested on \
                      all supported platforms",
            issue = "44930")]
-struct VaListImpl {
+#[lang = "va_list"]
+pub struct VaListImpl<'f> {
     stack: *mut c_void,
     gr_top: *mut c_void,
     vr_top: *mut c_void,
     gr_offs: i32,
     vr_offs: i32,
+    _marker: PhantomData<&'f mut &'f c_void>,
 }
 
 /// PowerPC ABI implementation of a `va_list`.
@@ -95,12 +110,14 @@ struct VaListImpl {
            reason = "the `c_variadic` feature has not been properly tested on \
                      all supported platforms",
            issue = "44930")]
-struct VaListImpl {
+#[lang = "va_list"]
+pub struct VaListImpl<'f> {
     gpr: u8,
     fpr: u8,
     reserved: u16,
     overflow_arg_area: *mut c_void,
     reg_save_area: *mut c_void,
+    _marker: PhantomData<&'f mut &'f c_void>,
 }
 
 /// x86_64 ABI implementation of a `va_list`.
@@ -111,22 +128,131 @@ struct VaListImpl {
            reason = "the `c_variadic` feature has not been properly tested on \
                      all supported platforms",
            issue = "44930")]
-struct VaListImpl {
+#[lang = "va_list"]
+pub struct VaListImpl<'f> {
     gp_offset: i32,
     fp_offset: i32,
     overflow_arg_area: *mut c_void,
     reg_save_area: *mut c_void,
+    _marker: PhantomData<&'f mut &'f c_void>,
 }
 
-/// A wrapper for a `va_list`
+/// asm.js ABI implementation of a `va_list`.
+// asm.js uses the PNaCl ABI, which specifies that a `va_list` is
+// an array of 4 32-bit integers, according to the old PNaCl docs at
+// https://web.archive.org/web/20130518054430/https://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Derived-Types
+// and clang does the same in `CreatePNaClABIBuiltinVaListDecl` from `lib/AST/ASTContext.cpp`
+#[cfg(all(target_arch = "asmjs", not(windows)))]
+#[repr(C)]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
 #[lang = "va_list"]
-#[derive(Debug)]
+pub struct VaListImpl<'f> {
+    inner: [crate::mem::MaybeUninit<i32>; 4],
+    _marker: PhantomData<&'f mut &'f c_void>,
+}
+
+#[cfg(all(target_arch = "asmjs", not(windows)))]
 #[unstable(feature = "c_variadic",
            reason = "the `c_variadic` feature has not been properly tested on \
                      all supported platforms",
            issue = "44930")]
+impl<'f> fmt::Debug for VaListImpl<'f> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        unsafe {
+            write!(f, "va_list* [{:#x}, {:#x}, {:#x}, {:#x}]",
+                   self.inner[0].read(), self.inner[1].read(),
+                   self.inner[2].read(), self.inner[3].read())
+        }
+    }
+}
+
+/// A wrapper for a `va_list`
 #[repr(transparent)]
-pub struct VaList<'a>(&'a mut VaListImpl);
+#[derive(Debug)]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+pub struct VaList<'a, 'f: 'a> {
+    #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
+                  not(target_arch = "x86_64"), not(target_arch = "asmjs")),
+              all(target_arch = "aarch64", target_os = "ios"),
+              windows))]
+    inner: VaListImpl<'f>,
+
+    #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc",
+                  target_arch = "x86_64", target_arch = "asmjs"),
+              any(not(target_arch = "aarch64"), not(target_os = "ios")),
+              not(windows)))]
+    inner: &'a mut VaListImpl<'f>,
+
+    _marker: PhantomData<&'a mut VaListImpl<'f>>,
+}
+
+#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
+              not(target_arch = "x86_64"), not(target_arch = "asmjs")),
+          all(target_arch = "aarch64", target_os = "ios"),
+          windows))]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+impl<'f> VaListImpl<'f> {
+    /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
+    #[inline]
+    pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
+        VaList {
+            inner: VaListImpl { ..*self },
+            _marker: PhantomData,
+        }
+    }
+}
+
+#[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc",
+              target_arch = "x86_64", target_arch = "asmjs"),
+          any(not(target_arch = "aarch64"), not(target_os = "ios")),
+          not(windows)))]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+impl<'f> VaListImpl<'f> {
+    /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
+    #[inline]
+    pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
+        VaList {
+            inner: self,
+            _marker: PhantomData,
+        }
+    }
+}
+
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+impl<'a, 'f: 'a> Deref for VaList<'a, 'f> {
+    type Target = VaListImpl<'f>;
+
+    #[inline]
+    fn deref(&self) -> &VaListImpl<'f> {
+        &self.inner
+    }
+}
+
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> {
+    #[inline]
+    fn deref_mut(&mut self) -> &mut VaListImpl<'f> {
+        &mut self.inner
+    }
+}
 
 // The VaArgSafe trait needs to be used in public interfaces, however, the trait
 // itself must not be allowed to be used outside this module. Allowing users to
@@ -175,56 +301,70 @@ impl<T> sealed_trait::VaArgSafe for *mut T {}
            issue = "44930")]
 impl<T> sealed_trait::VaArgSafe for *const T {}
 
-impl<'a> VaList<'a> {
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+impl<'f> VaListImpl<'f> {
     /// Advance to the next arg.
-    #[unstable(feature = "c_variadic",
-               reason = "the `c_variadic` feature has not been properly tested on \
-                         all supported platforms",
-               issue = "44930")]
+    #[inline]
     pub unsafe fn arg<T: sealed_trait::VaArgSafe>(&mut self) -> T {
         va_arg(self)
     }
 
     /// Copies the `va_list` at the current location.
-    #[unstable(feature = "c_variadic",
-               reason = "the `c_variadic` feature has not been properly tested on \
-                         all supported platforms",
-               issue = "44930")]
     pub unsafe fn with_copy<F, R>(&self, f: F) -> R
-            where F: for<'copy> FnOnce(VaList<'copy>) -> R {
-        #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
-                      not(target_arch = "x86_64")),
-                  all(target_arch = "aarch64", target_os = "ios"),
-                  windows))]
-        let mut ap = va_copy(self);
-        #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
-                  not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))]
-        let mut ap_inner = va_copy(self);
-        #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
-                  not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))]
-        let mut ap = VaList(&mut ap_inner);
-        let ret = f(VaList(ap.0));
+            where F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R {
+        let mut ap = self.clone();
+        let ret = f(ap.as_va_list());
         va_end(&mut ap);
         ret
     }
 }
 
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+impl<'f> Clone for VaListImpl<'f> {
+    #[inline]
+    fn clone(&self) -> Self {
+        let mut dest = crate::mem::MaybeUninit::uninit();
+        unsafe {
+            va_copy(dest.as_mut_ptr(), self);
+            dest.assume_init()
+        }
+    }
+}
+
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+impl<'f> Drop for VaListImpl<'f> {
+    fn drop(&mut self) {
+        // FIXME: this should call `va_end`, but there's no clean way to
+        // guarantee that `drop` always gets inlined into its caller,
+        // so the `va_end` would get directly called from the same function as
+        // the corresponding `va_copy`. `man va_end` states that C requires this,
+        // and LLVM basically follows the C semantics, so we need to make sure
+        // that `va_end` is always called from the same function as `va_copy`.
+        // For more details, see https://github.com/rust-lang/rust/pull/59625
+        // and https://llvm.org/docs/LangRef.html#llvm-va-end-intrinsic.
+        //
+        // This works for now, since `va_end` is a no-op on all current LLVM targets.
+    }
+}
+
 extern "rust-intrinsic" {
     /// Destroy the arglist `ap` after initialization with `va_start` or
     /// `va_copy`.
-    fn va_end(ap: &mut VaList<'_>);
+    fn va_end(ap: &mut VaListImpl<'_>);
 
     /// Copies the current location of arglist `src` to the arglist `dst`.
-    #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
-                  not(target_arch = "x86_64")),
-              all(target_arch = "aarch64", target_os = "ios"),
-              windows))]
-    fn va_copy<'a>(src: &VaList<'a>) -> VaList<'a>;
-    #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
-              not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))]
-    fn va_copy(src: &VaList<'_>) -> VaListImpl;
+    fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>);
 
     /// Loads an argument of type `T` from the `va_list` `ap` and increment the
     /// argument `ap` points to.
-    fn va_arg<T: sealed_trait::VaArgSafe>(ap: &mut VaList<'_>) -> T;
+    fn va_arg<T: sealed_trait::VaArgSafe>(ap: &mut VaListImpl<'_>) -> T;
 }
diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs
index df86da5fc39..15ce2277fa0 100644
--- a/src/libcore/fmt/builders.rs
+++ b/src/libcore/fmt/builders.rs
@@ -1,37 +1,50 @@
 use crate::fmt;
 
-struct PadAdapter<'a> {
-    buf: &'a mut (dyn fmt::Write + 'a),
+struct PadAdapter<'buf, 'state> {
+    buf: &'buf mut (dyn fmt::Write + 'buf),
+    state: &'state mut PadAdapterState,
+}
+
+struct PadAdapterState {
     on_newline: bool,
 }
 
-impl<'a> PadAdapter<'a> {
-    fn wrap<'b, 'c: 'a+'b>(fmt: &'c mut fmt::Formatter<'_>, slot: &'b mut Option<Self>)
-                        -> fmt::Formatter<'b> {
+impl Default for PadAdapterState {
+    fn default() -> Self {
+        PadAdapterState {
+            on_newline: true,
+        }
+    }
+}
+
+impl<'buf, 'state> PadAdapter<'buf, 'state> {
+    fn wrap<'slot, 'fmt: 'buf+'slot>(fmt: &'fmt mut fmt::Formatter<'_>,
+                                     slot: &'slot mut Option<Self>,
+                                     state: &'state mut PadAdapterState) -> fmt::Formatter<'slot> {
         fmt.wrap_buf(move |buf| {
             *slot = Some(PadAdapter {
                 buf,
-                on_newline: true,
+                state,
             });
             slot.as_mut().unwrap()
         })
     }
 }
 
-impl fmt::Write for PadAdapter<'_> {
+impl fmt::Write for PadAdapter<'_, '_> {
     fn write_str(&mut self, mut s: &str) -> fmt::Result {
         while !s.is_empty() {
-            if self.on_newline {
+            if self.state.on_newline {
                 self.buf.write_str("    ")?;
             }
 
             let split = match s.find('\n') {
                 Some(pos) => {
-                    self.on_newline = true;
+                    self.state.on_newline = true;
                     pos + 1
                 }
                 None => {
-                    self.on_newline = false;
+                    self.state.on_newline = false;
                     s.len()
                 }
             };
@@ -85,7 +98,7 @@ pub struct DebugStruct<'a, 'b: 'a> {
     has_fields: bool,
 }
 
-pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
+pub(super) fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
                                 name: &str)
                                 -> DebugStruct<'a, 'b> {
     let result = fmt.write_str(name);
@@ -133,7 +146,8 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
                     self.fmt.write_str(" {\n")?;
                 }
                 let mut slot = None;
-                let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
+                let mut state = Default::default();
+                let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state);
                 writer.write_str(name)?;
                 writer.write_str(": ")?;
                 value.fmt(&mut writer)?;
@@ -237,7 +251,10 @@ pub struct DebugTuple<'a, 'b: 'a> {
     empty_name: bool,
 }
 
-pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
+pub(super) fn debug_tuple_new<'a, 'b>(
+    fmt: &'a mut fmt::Formatter<'b>,
+    name: &str,
+) -> DebugTuple<'a, 'b> {
     let result = fmt.write_str(name);
     DebugTuple {
         fmt,
@@ -279,7 +296,8 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
                     self.fmt.write_str("(\n")?;
                 }
                 let mut slot = None;
-                let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
+                let mut state = Default::default();
+                let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state);
                 value.fmt(&mut writer)?;
                 writer.write_str(",\n")
             } else {
@@ -349,7 +367,8 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
                     self.fmt.write_str("\n")?;
                 }
                 let mut slot = None;
-                let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
+                let mut state = Default::default();
+                let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state);
                 entry.fmt(&mut writer)?;
                 writer.write_str(",\n")
             } else {
@@ -402,7 +421,7 @@ pub struct DebugSet<'a, 'b: 'a> {
     inner: DebugInner<'a, 'b>,
 }
 
-pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
+pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
     let result = fmt.write_str("{");
     DebugSet {
         inner: DebugInner {
@@ -539,7 +558,7 @@ pub struct DebugList<'a, 'b: 'a> {
     inner: DebugInner<'a, 'b>,
 }
 
-pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
+pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
     let result = fmt.write_str("[");
     DebugList {
         inner: DebugInner {
@@ -676,14 +695,19 @@ pub struct DebugMap<'a, 'b: 'a> {
     fmt: &'a mut fmt::Formatter<'b>,
     result: fmt::Result,
     has_fields: bool,
+    has_key: bool,
+    // The state of newlines is tracked between keys and values
+    state: PadAdapterState,
 }
 
-pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
+pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
     let result = fmt.write_str("{");
     DebugMap {
         fmt,
         result,
         has_fields: false,
+        has_key: false,
+        state: Default::default(),
     }
 }
 
@@ -712,25 +736,123 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
     pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> {
+        self.key(key).value(value)
+    }
+
+    /// Adds the key part of a new entry to the map output.
+    ///
+    /// This method, together with `value`, is an alternative to `entry` that
+    /// can be used when the complete entry isn't known upfront. Prefer the `entry`
+    /// method when it's possible to use.
+    ///
+    /// # Panics
+    ///
+    /// `key` must be called before `value` and each call to `key` must be followed
+    /// by a corresponding call to `value`. Otherwise this method will panic.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(debug_map_key_value)]
+    /// use std::fmt;
+    ///
+    /// struct Foo(Vec<(String, i32)>);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+    ///         fmt.debug_map()
+    ///            .key(&"whole").value(&self.0) // We add the "whole" entry.
+    ///            .finish()
+    ///     }
+    /// }
+    ///
+    /// assert_eq!(
+    ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
+    ///     "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
+    /// );
+    /// ```
+    #[unstable(feature = "debug_map_key_value",
+               reason = "recently added",
+               issue = "62482")]
+    pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> {
+        assert!(!self.has_key, "attempted to begin a new map entry \
+                                without completing the previous one");
+
         self.result = self.result.and_then(|_| {
             if self.is_pretty() {
                 if !self.has_fields {
                     self.fmt.write_str("\n")?;
                 }
                 let mut slot = None;
-                let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
+                self.state = Default::default();
+                let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut self.state);
                 key.fmt(&mut writer)?;
                 writer.write_str(": ")?;
-                value.fmt(&mut writer)?;
-                writer.write_str(",\n")
             } else {
                 if self.has_fields {
                     self.fmt.write_str(", ")?
                 }
                 key.fmt(self.fmt)?;
                 self.fmt.write_str(": ")?;
-                value.fmt(self.fmt)
             }
+
+            self.has_key = true;
+            Ok(())
+        });
+
+        self
+    }
+
+    /// Adds the value part of a new entry to the map output.
+    ///
+    /// This method, together with `key`, is an alternative to `entry` that
+    /// can be used when the complete entry isn't known upfront. Prefer the `entry`
+    /// method when it's possible to use.
+    ///
+    /// # Panics
+    ///
+    /// `key` must be called before `value` and each call to `key` must be followed
+    /// by a corresponding call to `value`. Otherwise this method will panic.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(debug_map_key_value)]
+    /// use std::fmt;
+    ///
+    /// struct Foo(Vec<(String, i32)>);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+    ///         fmt.debug_map()
+    ///            .key(&"whole").value(&self.0) // We add the "whole" entry.
+    ///            .finish()
+    ///     }
+    /// }
+    ///
+    /// assert_eq!(
+    ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
+    ///     "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
+    /// );
+    /// ```
+    #[unstable(feature = "debug_map_key_value",
+               reason = "recently added",
+               issue = "62482")]
+    pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> {
+        assert!(self.has_key, "attempted to format a map value before its key");
+
+        self.result = self.result.and_then(|_| {
+            if self.is_pretty() {
+                let mut slot = None;
+                let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut self.state);
+                value.fmt(&mut writer)?;
+                writer.write_str(",\n")?;
+            } else {
+                value.fmt(self.fmt)?;
+            }
+
+            self.has_key = false;
+            Ok(())
         });
 
         self.has_fields = true;
@@ -775,6 +897,11 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
 
     /// Finishes output and returns any error encountered.
     ///
+    /// # Panics
+    ///
+    /// `key` must be called before `value` and each call to `key` must be followed
+    /// by a corresponding call to `value`. Otherwise this method will panic.
+    ///
     /// # Examples
     ///
     /// ```
@@ -797,6 +924,8 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
     pub fn finish(&mut self) -> fmt::Result {
+        assert!(!self.has_key, "attempted to finish a map with a partial entry");
+
         self.result.and_then(|_| self.fmt.write_str("}"))
     }
 
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index 4bd7d3b4b22..a2fff913ac7 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -12,10 +12,11 @@ fn float_to_decimal_common_exact<T>(fmt: &mut Formatter<'_>, num: &T,
     unsafe {
         let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64
         let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit();
-        // FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized
-        // `MaybeUninit` (here and elsewhere in this file).  Revisit this once
+        // FIXME(#53491): This is calling `get_mut` on an uninitialized
+        // `MaybeUninit` (here and elsewhere in this file). Revisit this once
         // we decided whether that is valid or not.
-        // Using `freeze` is *not enough*; `flt2dec::Part` is an enum!
+        // We can do this only because we are libstd and coupled to the compiler.
+        // (FWIW, using `freeze` would not be enough; `flt2dec::Part` is an enum!)
         let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
                                                     *num, sign, precision,
                                                     false, buf.get_mut(), parts.get_mut());
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 43c1a3b7767..bd31d25dd03 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -545,6 +545,19 @@ pub trait Debug {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result;
 }
 
+// Separate module to reexport the macro `Debug` from prelude without the trait `Debug`.
+pub(crate) mod macros {
+    /// Derive macro generating an impl of the trait `Debug`.
+    #[rustc_builtin_macro]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+    #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+    #[allow_internal_unstable(core_intrinsics)]
+    pub macro Debug($item:item) { /* compiler built-in */ }
+}
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(inline)]
+pub use macros::Debug;
+
 /// Format trait for an empty format, `{}`.
 ///
 /// `Display` is similar to [`Debug`][debug], but `Display` is for user-facing
@@ -886,7 +899,7 @@ pub trait Pointer {
 ///
 /// # Examples
 ///
-/// Basic usage with `i32`:
+/// Basic usage with `f64`:
 ///
 /// ```
 /// let x = 42.0; // 42.0 is '4.2e1' in scientific notation
@@ -929,7 +942,7 @@ pub trait LowerExp {
 ///
 /// # Examples
 ///
-/// Basic usage with `f32`:
+/// Basic usage with `f64`:
 ///
 /// ```
 /// let x = 42.0; // 42.0 is '4.2E1' in scientific notation
@@ -2070,19 +2083,19 @@ macro_rules! tuple {
     () => ();
     ( $($name:ident,)+ ) => (
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized {
+        impl<$($name:Debug),+> Debug for ($($name,)+) where last_type!($($name,)+): ?Sized {
             #[allow(non_snake_case, unused_assignments)]
             fn fmt(&self, f: &mut Formatter<'_>) -> Result {
                 let mut builder = f.debug_tuple("");
-                let ($(ref $name,)*) = *self;
+                let ($(ref $name,)+) = *self;
                 $(
                     builder.field(&$name);
-                )*
+                )+
 
                 builder.finish()
             }
         }
-        peel! { $($name,)* }
+        peel! { $($name,)+ }
     )
 }
 
@@ -2172,5 +2185,5 @@ impl<T: ?Sized + Debug> Debug for UnsafeCell<T> {
     }
 }
 
-// If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
+// If you expected tests to be here, look instead at the ui/ifmt.rs test,
 // it's a lot easier than creating all of the rt::Piece structures here.
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index f9b4c26496c..3b5c9fbff25 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -51,7 +51,7 @@ trait GenericRadix {
         // characters for a base 2 number.
         let zero = T::zero();
         let is_nonnegative = x >= zero;
-        let mut buf = uninitialized_array![u8; 128];
+        let mut buf = [MaybeUninit::<u8>::uninit(); 128];
         let mut curr = buf.len();
         let base = T::from_u8(Self::BASE);
         if is_nonnegative {
@@ -189,7 +189,7 @@ static DEC_DIGITS_LUT: &[u8; 200] =
 macro_rules! impl_Display {
     ($($t:ident),* as $u:ident via $conv_fn:ident named $name:ident) => {
         fn $name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            let mut buf = uninitialized_array![u8; 39];
+            let mut buf = [MaybeUninit::<u8>::uninit(); 39];
             let mut curr = buf.len() as isize;
             let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf);
             let lut_ptr = DEC_DIGITS_LUT.as_ptr();
diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs
index 3f76ac20192..f14ed38b9b0 100644
--- a/src/libcore/future/future.rs
+++ b/src/libcore/future/future.rs
@@ -17,14 +17,17 @@ use crate::task::{Context, Poll};
 /// final value. This method does not block if the value is not ready. Instead,
 /// the current task is scheduled to be woken up when it's possible to make
 /// further progress by `poll`ing again. The `context` passed to the `poll`
-/// method can provide a `Waker`, which is a handle for waking up the current
+/// method can provide a [`Waker`], which is a handle for waking up the current
 /// task.
 ///
 /// When using a future, you generally won't call `poll` directly, but instead
-/// `await!` the value.
+/// `.await` the value.
+///
+/// [`Waker`]: ../task/struct.Waker.html
 #[doc(spotlight)]
 #[must_use = "futures do nothing unless you `.await` or poll them"]
 #[stable(feature = "futures_api", since = "1.36.0")]
+#[lang = "future_trait"]
 pub trait Future {
     /// The type of value produced on completion.
     #[stable(feature = "futures_api", since = "1.36.0")]
@@ -108,8 +111,7 @@ impl<F: ?Sized + Future + Unpin> Future for &mut F {
 #[stable(feature = "futures_api", since = "1.36.0")]
 impl<P> Future for Pin<P>
 where
-    P: Unpin + ops::DerefMut,
-    P::Target: Future,
+    P: Unpin + ops::DerefMut<Target: Future>,
 {
     type Output = <<P as ops::Deref>::Target as Future>::Output;
 
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 98150fd9f82..bf3daa32840 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -198,6 +198,19 @@ pub trait Hash {
     }
 }
 
+// Separate module to reexport the macro `Hash` from prelude without the trait `Hash`.
+pub(crate) mod macros {
+    /// Derive macro generating an impl of the trait `Hash`.
+    #[rustc_builtin_macro]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+    #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+    #[allow_internal_unstable(core_intrinsics)]
+    pub macro Hash($item:item) { /* compiler built-in */ }
+}
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(inline)]
+pub use macros::Hash;
+
 /// A trait for hashing an arbitrary stream of bytes.
 ///
 /// Instances of `Hasher` usually represent state that is changed while hashing
@@ -538,8 +551,6 @@ impl<H> PartialEq for BuildHasherDefault<H> {
 #[stable(since = "1.29.0", feature = "build_hasher_eq")]
 impl<H> Eq for BuildHasherDefault<H> {}
 
-//////////////////////////////////////////////////////////////////////////////
-
 mod impls {
     use crate::mem;
     use crate::slice;
@@ -617,11 +628,11 @@ mod impls {
 
         ( $($name:ident)+) => (
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($name: Hash),*> Hash for ($($name,)*) where last_type!($($name,)+): ?Sized {
+            impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized {
                 #[allow(non_snake_case)]
                 fn hash<S: Hasher>(&self, state: &mut S) {
-                    let ($(ref $name,)*) = *self;
-                    $($name.hash(state);)*
+                    let ($(ref $name,)+) = *self;
+                    $($name.hash(state);)+
                 }
             }
         );
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 94eddbeda2b..3b2b28217f9 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -110,32 +110,32 @@ pub fn spin_loop() {
 ///
 /// This function is a no-op, and does not even read from `dummy`.
 #[inline]
-#[unstable(feature = "test", issue = "27812")]
+#[unstable(feature = "test", issue = "50297")]
+#[allow(unreachable_code)] // this makes #[cfg] a bit easier below.
 pub fn black_box<T>(dummy: T) -> T {
-    cfg_if! {
-        if #[cfg(any(
-            target_arch = "asmjs",
-            all(
-                target_arch = "wasm32",
-                target_os = "emscripten"
-            )
-        ))] {
-            #[inline]
-            unsafe fn black_box_impl<T>(d: T) -> T {
-                // these targets do not support inline assembly
-                let ret = crate::ptr::read_volatile(&d);
-                crate::mem::forget(d);
-                ret
-            }
-        } else {
-            #[inline]
-            unsafe fn black_box_impl<T>(d: T) -> T {
-                // we need to "use" the argument in some way LLVM can't
-                // introspect.
-                asm!("" : : "r"(&d));
-                d
-            }
-        }
+    // We need to "use" the argument in some way LLVM can't introspect, and on
+    // targets that support it we can typically leverage inline assembly to do
+    // this. LLVM's intepretation of inline assembly is that it's, well, a black
+    // box. This isn't the greatest implementation since it probably deoptimizes
+    // more than we want, but it's so far good enough.
+    #[cfg(not(any(
+        target_arch = "asmjs",
+        all(
+            target_arch = "wasm32",
+            target_os = "emscripten"
+        )
+    )))]
+    unsafe {
+        asm!("" : : "r"(&dummy));
+        return dummy;
+    }
+
+    // Not all platforms support inline assembly so try to do something without
+    // inline assembly which in theory still hinders at least some optimizations
+    // on those targets. This is the "best effort" scenario.
+    unsafe {
+        let ret = crate::ptr::read_volatile(&dummy);
+        crate::mem::forget(dummy);
+        ret
     }
-    unsafe { black_box_impl(dummy) }
 }
diff --git a/src/libcore/internal_macros.rs b/src/libcore/internal_macros.rs
index dd5b92857be..3acf2ec837d 100644
--- a/src/libcore/internal_macros.rs
+++ b/src/libcore/internal_macros.rs
@@ -117,84 +117,3 @@ macro_rules! impl_fn_for_zst {
         )+
     }
 }
-
-/// A macro for defining `#[cfg]` if-else statements.
-///
-/// The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C
-/// preprocessor macro by allowing definition of a cascade of `#[cfg]` cases,
-/// emitting the implementation which matches first.
-///
-/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
-/// without having to rewrite each clause multiple times.
-///
-/// # Example
-///
-/// ```
-/// #[macro_use]
-/// extern crate cfg_if;
-///
-/// cfg_if! {
-///     if #[cfg(unix)] {
-///         fn foo() { /* unix specific functionality */ }
-///     } else if #[cfg(target_pointer_width = "32")] {
-///         fn foo() { /* non-unix, 32-bit functionality */ }
-///     } else {
-///         fn foo() { /* fallback implementation */ }
-///     }
-/// }
-///
-/// # fn main() {}
-/// ```
-macro_rules! cfg_if {
-    // match if/else chains with a final `else`
-    ($(
-        if #[cfg($($meta:meta),*)] { $($it:item)* }
-    ) else * else {
-        $($it2:item)*
-    }) => {
-        cfg_if! {
-            @__items
-            () ;
-            $( ( ($($meta),*) ($($it)*) ), )*
-            ( () ($($it2)*) ),
-        }
-    };
-
-    // match if/else chains lacking a final `else`
-    (
-        if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
-        $(
-            else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
-        )*
-    ) => {
-        cfg_if! {
-            @__items
-            () ;
-            ( ($($i_met),*) ($($i_it)*) ),
-            $( ( ($($e_met),*) ($($e_it)*) ), )*
-            ( () () ),
-        }
-    };
-
-    // Internal and recursive macro to emit all the items
-    //
-    // Collects all the negated cfgs in a list at the beginning and after the
-    // semicolon is all the remaining items
-    (@__items ($($not:meta,)*) ; ) => {};
-    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
-        // Emit all items within one block, applying an approprate #[cfg]. The
-        // #[cfg] will require all `$m` matchers specified and must also negate
-        // all previous matchers.
-        cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
-
-        // Recurse to emit all other items in `$rest`, and when we do so add all
-        // our `$m` matchers to the list of `$not` matchers as future emissions
-        // will have to negate everything we just matched as well.
-        cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
-    };
-
-    // Internal macro to Apply a cfg attribute to a list of items
-    (@__apply $m:meta, $($it:item)*) => {
-        $(#[$m] $it)*
-    };
-}
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 782a7ba4559..d145f2212f9 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -36,6 +36,8 @@
             issue = "0")]
 #![allow(missing_docs)]
 
+use crate::mem;
+
 #[stable(feature = "drop_in_place", since = "1.8.0")]
 #[rustc_deprecated(reason = "no longer an intrinsic - use `ptr::drop_in_place` directly",
                    since = "1.18.0")]
@@ -700,6 +702,13 @@ extern "rust-intrinsic" {
     /// which is unsafe unless `T` is `Copy`. Also, even if T is
     /// `Copy`, an all-zero value may not correspond to any legitimate
     /// state for the type in question.
+    #[unstable(feature = "core_intrinsics",
+               reason = "intrinsics are unlikely to ever be stabilized, instead \
+                         they should be used through stabilized interfaces \
+                         in the rest of the standard library",
+               issue = "0")]
+    #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned",
+                       since = "1.38.0")]
     pub fn init<T>() -> T;
 
     /// Creates an uninitialized value.
@@ -709,6 +718,13 @@ extern "rust-intrinsic" {
     /// state, which means it may claim either dropped or
     /// undropped. In the general case one must use `ptr::write` to
     /// initialize memory previous set to the result of `uninit`.
+    #[unstable(feature = "core_intrinsics",
+               reason = "intrinsics are unlikely to ever be stabilized, instead \
+                         they should be used through stabilized interfaces \
+                         in the rest of the standard library",
+               issue = "0")]
+    #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned",
+                       since = "1.38.0")]
     pub fn uninit<T>() -> T;
 
     /// Moves a value out of scope without running drop glue.
@@ -1051,6 +1067,15 @@ extern "rust-intrinsic" {
     /// Returns the absolute value of an `f64`.
     pub fn fabsf64(x: f64) -> f64;
 
+    /// Returns the minimum of two `f32` values.
+    pub fn minnumf32(x: f32, y: f32) -> f32;
+    /// Returns the minimum of two `f64` values.
+    pub fn minnumf64(x: f64, y: f64) -> f64;
+    /// Returns the maximum of two `f32` values.
+    pub fn maxnumf32(x: f32, y: f32) -> f32;
+    /// Returns the maximum of two `f64` values.
+    pub fn maxnumf64(x: f64, y: f64) -> f64;
+
     /// Copies the sign from `y` to `x` for `f32` values.
     pub fn copysignf32(x: f32, y: f32) -> f32;
     /// Copies the sign from `y` to `x` for `f64` values.
@@ -1240,6 +1265,18 @@ extern "rust-intrinsic" {
     /// y < 0 or y >= N, where N is the width of T in bits.
     pub fn unchecked_shr<T>(x: T, y: T) -> T;
 
+    /// Returns the result of an unchecked addition, resulting in
+    /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`.
+    pub fn unchecked_add<T>(x: T, y: T) -> T;
+
+    /// Returns the result of an unchecked substraction, resulting in
+    /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`.
+    pub fn unchecked_sub<T>(x: T, y: T) -> T;
+
+    /// Returns the result of an unchecked multiplication, resulting in
+    /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`.
+    pub fn unchecked_mul<T>(x: T, y: T) -> T;
+
     /// Performs rotate left.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `rotate_left` method. For example,
@@ -1256,18 +1293,40 @@ extern "rust-intrinsic" {
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_add` method. For example,
     /// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
+    #[cfg(boostrap_stdarch_ignore_this)]
     pub fn overflowing_add<T>(a: T, b: T) -> T;
     /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_sub` method. For example,
     /// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
+    #[cfg(boostrap_stdarch_ignore_this)]
     pub fn overflowing_sub<T>(a: T, b: T) -> T;
     /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_mul` method. For example,
     /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
+    #[cfg(boostrap_stdarch_ignore_this)]
     pub fn overflowing_mul<T>(a: T, b: T) -> T;
 
+    /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
+    /// The stabilized versions of this intrinsic are available on the integer
+    /// primitives via the `wrapping_add` method. For example,
+    /// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
+    #[cfg(not(boostrap_stdarch_ignore_this))]
+    pub fn wrapping_add<T>(a: T, b: T) -> T;
+    /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
+    /// The stabilized versions of this intrinsic are available on the integer
+    /// primitives via the `wrapping_sub` method. For example,
+    /// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
+    #[cfg(not(boostrap_stdarch_ignore_this))]
+    pub fn wrapping_sub<T>(a: T, b: T) -> T;
+    /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
+    /// The stabilized versions of this intrinsic are available on the integer
+    /// primitives via the `wrapping_mul` method. For example,
+    /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
+    #[cfg(not(boostrap_stdarch_ignore_this))]
+    pub fn wrapping_mul<T>(a: T, b: T) -> T;
+
     /// Computes `a + b`, while saturating at numeric bounds.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `saturating_add` method. For example,
@@ -1298,29 +1357,29 @@ extern "rust-intrinsic" {
     pub fn nontemporal_store<T>(ptr: *mut T, val: T);
 }
 
-mod real_intrinsics {
-  extern "rust-intrinsic" {
-    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
-    /// and destination must *not* overlap.
-    /// For the full docs, see the stabilized wrapper [`copy_nonoverlapping`].
-    ///
-    /// [`copy_nonoverlapping`]: ../../std/ptr/fn.copy_nonoverlapping.html
-    pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+// Some functions are defined here because they accidentally got made
+// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
+// (`transmute` also falls into this category, but it cannot be wrapped due to the
+// check that `T` and `U` have the same size.)
 
-    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
-    /// and destination may overlap.
-    /// For the full docs, see the stabilized wrapper [`copy`].
-    ///
-    /// [`copy`]: ../../std/ptr/fn.copy.html
-    pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
+/// Checks whether `ptr` is properly aligned with respect to
+/// `align_of::<T>()`.
+pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
+    !ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
+}
 
-    /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
-    /// `val`.
-    /// For the full docs, see the stabilized wrapper [`write_bytes`].
-    ///
-    /// [`write_bytes`]: ../../std/ptr/fn.write_bytes.html
-    pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
-  }
+/// Checks whether the regions of memory starting at `src` and `dst` of size
+/// `count * size_of::<T>()` overlap.
+fn overlaps<T>(src: *const T, dst: *const T, count: usize) -> bool {
+    let src_usize = src as usize;
+    let dst_usize = dst as usize;
+    let size = mem::size_of::<T>().checked_mul(count).unwrap();
+    let diff = if src_usize > dst_usize {
+        src_usize - dst_usize
+    } else {
+        dst_usize - src_usize
+    };
+    size > diff
 }
 
 /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
@@ -1409,7 +1468,14 @@ mod real_intrinsics {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[inline]
 pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
-    real_intrinsics::copy_nonoverlapping(src, dst, count);
+    extern "rust-intrinsic" {
+        fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+    }
+
+    debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer");
+    debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer");
+    debug_assert!(!overlaps(src, dst, count), "attempt to copy to overlapping memory");
+    copy_nonoverlapping(src, dst, count)
 }
 
 /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
@@ -1466,7 +1532,13 @@ pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[inline]
 pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
-    real_intrinsics::copy(src, dst, count)
+    extern "rust-intrinsic" {
+        fn copy<T>(src: *const T, dst: *mut T, count: usize);
+    }
+
+    debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer");
+    debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer");
+    copy(src, dst, count)
 }
 
 /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
@@ -1544,5 +1616,10 @@ pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[inline]
 pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
-    real_intrinsics::write_bytes(dst, val, count)
+    extern "rust-intrinsic" {
+        fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
+    }
+
+    debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
+    write_bytes(dst, val, count)
 }
diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs
index 76239ebc0ab..0b9f7f6b609 100644
--- a/src/libcore/iter/adapters/chain.rs
+++ b/src/libcore/iter/adapters/chain.rs
@@ -207,6 +207,29 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
         }
     }
 
+    #[inline]
+    fn nth_back(&mut self, mut n: usize) -> Option<A::Item> {
+        match self.state {
+            ChainState::Both | ChainState::Back => {
+                for x in self.b.by_ref().rev() {
+                    if n == 0 {
+                        return Some(x)
+                    }
+                    n -= 1;
+                }
+                if let ChainState::Both = self.state {
+                    self.state = ChainState::Front;
+                }
+            }
+            ChainState::Front => {}
+        }
+        if let ChainState::Front = self.state {
+            self.a.nth_back(n)
+        } else {
+            None
+        }
+    }
+
     fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
         Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
diff --git a/src/libcore/iter/adapters/flatten.rs b/src/libcore/iter/adapters/flatten.rs
index 8c2aae477bf..a45173f614d 100644
--- a/src/libcore/iter/adapters/flatten.rs
+++ b/src/libcore/iter/adapters/flatten.rs
@@ -24,15 +24,17 @@ impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Clone, U: Clone + IntoIterator, F: Clone> Clone for FlatMap<I, U, F>
-    where <U as IntoIterator>::IntoIter: Clone
+impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
+where
+    U: Clone + IntoIterator<IntoIter: Clone>,
 {
     fn clone(&self) -> Self { FlatMap { inner: self.inner.clone() } }
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, U: IntoIterator, F> fmt::Debug for FlatMap<I, U, F>
-    where U::IntoIter: fmt::Debug
+impl<I: fmt::Debug, U, F> fmt::Debug for FlatMap<I, U, F>
+where
+    U: IntoIterator<IntoIter: fmt::Debug>,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("FlatMap").field("inner", &self.inner).finish()
@@ -68,9 +70,9 @@ impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
-    where F: FnMut(I::Item) -> U,
-          U: IntoIterator,
-          U::IntoIter: DoubleEndedIterator
+where
+    F: FnMut(I::Item) -> U,
+    U: IntoIterator<IntoIter: DoubleEndedIterator>,
 {
     #[inline]
     fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
@@ -104,12 +106,11 @@ impl<I, U, F> FusedIterator for FlatMap<I, U, F>
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
-pub struct Flatten<I: Iterator>
-where I::Item: IntoIterator {
+pub struct Flatten<I: Iterator<Item: IntoIterator>> {
     inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
 }
-impl<I: Iterator> Flatten<I>
-where I::Item: IntoIterator {
+
+impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
     pub(in super::super) fn new(iter: I) -> Flatten<I> {
         Flatten { inner: FlattenCompat::new(iter) }
     }
@@ -117,8 +118,9 @@ where I::Item: IntoIterator {
 
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
 impl<I, U> fmt::Debug for Flatten<I>
-    where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
+where
+    I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+    U: fmt::Debug + Iterator,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Flatten").field("inner", &self.inner).finish()
@@ -127,16 +129,18 @@ impl<I, U> fmt::Debug for Flatten<I>
 
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
 impl<I, U> Clone for Flatten<I>
-    where I: Iterator + Clone, U: Iterator + Clone,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
+where
+    I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+    U: Clone + Iterator,
 {
     fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } }
 }
 
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
 impl<I, U> Iterator for Flatten<I>
-    where I: Iterator, U: Iterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+where
+    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+    U: Iterator,
 {
     type Item = U::Item;
 
@@ -163,8 +167,9 @@ impl<I, U> Iterator for Flatten<I>
 
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
 impl<I, U> DoubleEndedIterator for Flatten<I>
-    where I: DoubleEndedIterator, U: DoubleEndedIterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+where
+    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+    U: DoubleEndedIterator,
 {
     #[inline]
     fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
@@ -186,8 +191,10 @@ impl<I, U> DoubleEndedIterator for Flatten<I>
 
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
 impl<I, U> FusedIterator for Flatten<I>
-    where I: FusedIterator, U: Iterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item> {}
+where
+    I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+    U: Iterator,
+{}
 
 /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
 /// this type.
@@ -205,8 +212,9 @@ impl<I, U> FlattenCompat<I, U> {
 }
 
 impl<I, U> Iterator for FlattenCompat<I, U>
-    where I: Iterator, U: Iterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+where
+    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+    U: Iterator,
 {
     type Item = U::Item;
 
@@ -217,7 +225,7 @@ impl<I, U> Iterator for FlattenCompat<I, U>
                 if let elt@Some(_) = inner.next() { return elt }
             }
             match self.iter.next() {
-                None => return self.backiter.as_mut().and_then(|it| it.next()),
+                None => return self.backiter.as_mut()?.next(),
                 Some(inner) => self.frontiter = Some(inner.into_iter()),
             }
         }
@@ -225,8 +233,8 @@ impl<I, U> Iterator for FlattenCompat<I, U>
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
-        let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
+        let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
+        let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
         let lo = flo.saturating_add(blo);
         match (self.iter.size_hint(), fhi, bhi) {
             ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
@@ -238,20 +246,25 @@ impl<I, U> Iterator for FlattenCompat<I, U>
     fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
+        #[inline]
+        fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
+            frontiter: &'a mut Option<T::IntoIter>,
+            fold: &'a mut impl FnMut(Acc, T::Item) -> R,
+        ) -> impl FnMut(Acc, T) -> R + 'a {
+            move |acc, x| {
+                let mut mid = x.into_iter();
+                let r = mid.try_fold(acc, &mut *fold);
+                *frontiter = Some(mid);
+                r
+            }
+        }
+
         if let Some(ref mut front) = self.frontiter {
             init = front.try_fold(init, &mut fold)?;
         }
         self.frontiter = None;
 
-        {
-            let frontiter = &mut self.frontiter;
-            init = self.iter.try_fold(init, |acc, x| {
-                let mut mid = x.into_iter();
-                let r = mid.try_fold(acc, &mut fold);
-                *frontiter = Some(mid);
-                r
-            })?;
-        }
+        init = self.iter.try_fold(init, flatten(&mut self.frontiter, &mut fold))?;
         self.frontiter = None;
 
         if let Some(ref mut back) = self.backiter {
@@ -263,19 +276,27 @@ impl<I, U> Iterator for FlattenCompat<I, U>
     }
 
     #[inline]
-    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn fold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
+        #[inline]
+        fn flatten<U: Iterator, Acc>(
+            fold: &mut impl FnMut(Acc, U::Item) -> Acc,
+        ) -> impl FnMut(Acc, U) -> Acc + '_ {
+            move |acc, iter| iter.fold(acc, &mut *fold)
+        }
+
         self.frontiter.into_iter()
             .chain(self.iter.map(IntoIterator::into_iter))
             .chain(self.backiter)
-            .fold(init, |acc, iter| iter.fold(acc, &mut fold))
+            .fold(init, flatten(fold))
     }
 }
 
 impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
-    where I: DoubleEndedIterator, U: DoubleEndedIterator,
-          I::Item: IntoIterator<IntoIter = U, Item = U::Item>
+where
+    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
+    U: DoubleEndedIterator,
 {
     #[inline]
     fn next_back(&mut self) -> Option<U::Item> {
@@ -284,7 +305,7 @@ impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
                 if let elt@Some(_) = inner.next_back() { return elt }
             }
             match self.iter.next_back() {
-                None => return self.frontiter.as_mut().and_then(|it| it.next_back()),
+                None => return self.frontiter.as_mut()?.next_back(),
                 next => self.backiter = next.map(IntoIterator::into_iter),
             }
         }
@@ -294,22 +315,29 @@ impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
     fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        if let Some(ref mut back) = self.backiter {
-            init = back.try_rfold(init, &mut fold)?;
-        }
-        self.backiter = None;
-
+        #[inline]
+        fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
+            backiter: &'a mut Option<T::IntoIter>,
+            fold: &'a mut impl FnMut(Acc, T::Item) -> R,
+        ) -> impl FnMut(Acc, T) -> R + 'a where
+            T::IntoIter: DoubleEndedIterator,
         {
-            let backiter = &mut self.backiter;
-            init = self.iter.try_rfold(init, |acc, x| {
+            move |acc, x| {
                 let mut mid = x.into_iter();
-                let r = mid.try_rfold(acc, &mut fold);
+                let r = mid.try_rfold(acc, &mut *fold);
                 *backiter = Some(mid);
                 r
-            })?;
+            }
+        }
+
+        if let Some(ref mut back) = self.backiter {
+            init = back.try_rfold(init, &mut fold)?;
         }
         self.backiter = None;
 
+        init = self.iter.try_rfold(init, flatten(&mut self.backiter, &mut fold))?;
+        self.backiter = None;
+
         if let Some(ref mut front) = self.frontiter {
             init = front.try_rfold(init, &mut fold)?;
         }
@@ -319,12 +347,19 @@ impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
     }
 
     #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn rfold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
+        #[inline]
+        fn flatten<U: DoubleEndedIterator, Acc>(
+            fold: &mut impl FnMut(Acc, U::Item) -> Acc,
+        ) -> impl FnMut(Acc, U) -> Acc + '_ {
+            move |acc, iter| iter.rfold(acc, &mut *fold)
+        }
+
         self.frontiter.into_iter()
             .chain(self.iter.map(IntoIterator::into_iter))
             .chain(self.backiter)
-            .rfold(init, |acc, iter| iter.rfold(acc, &mut fold))
+            .rfold(init, flatten(fold))
     }
 }
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index 64e588f65b4..a63434abd6c 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -1,6 +1,6 @@
 use crate::cmp;
 use crate::fmt;
-use crate::ops::Try;
+use crate::ops::{Add, AddAssign, Try};
 use crate::usize;
 use crate::intrinsics;
 
@@ -73,11 +73,6 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
     {
         self.iter.position(predicate)
     }
-
-    #[inline]
-    fn last(mut self) -> Option<Self::Item> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -148,6 +143,18 @@ impl<I> Copied<I> {
     }
 }
 
+fn copy_fold<T: Copy, Acc>(
+    mut f: impl FnMut(Acc, T) -> Acc,
+) -> impl FnMut(Acc, &T) -> Acc {
+    move |acc, &elt| f(acc, elt)
+}
+
+fn copy_try_fold<T: Copy, Acc, R>(
+    mut f: impl FnMut(Acc, T) -> R,
+) -> impl FnMut(Acc, &T) -> R {
+    move |acc, &elt| f(acc, elt)
+}
+
 #[stable(feature = "iter_copied", since = "1.36.0")]
 impl<'a, I, T: 'a> Iterator for Copied<I>
     where I: Iterator<Item=&'a T>, T: Copy
@@ -162,16 +169,16 @@ impl<'a, I, T: 'a> Iterator for Copied<I>
         self.it.size_hint()
     }
 
-    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
         Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
     {
-        self.it.try_fold(init, move |acc, &elt| f(acc, elt))
+        self.it.try_fold(init, copy_try_fold(f))
     }
 
-    fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
+    fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
-        self.it.fold(init, move |acc, &elt| f(acc, elt))
+        self.it.fold(init, copy_fold(f))
     }
 }
 
@@ -183,16 +190,16 @@ impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I>
         self.it.next_back().copied()
     }
 
-    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+    fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
         Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
     {
-        self.it.try_rfold(init, move |acc, &elt| f(acc, elt))
+        self.it.try_rfold(init, copy_try_fold(f))
     }
 
-    fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
+    fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
-        self.it.rfold(init, move |acc, &elt| f(acc, elt))
+        self.it.rfold(init, copy_fold(f))
     }
 }
 
@@ -253,6 +260,12 @@ impl<I> Cloned<I> {
     }
 }
 
+fn clone_try_fold<T: Clone, Acc, R>(
+    mut f: impl FnMut(Acc, T) -> R,
+) -> impl FnMut(Acc, &T) -> R {
+    move |acc, elt| f(acc, elt.clone())
+}
+
 #[stable(feature = "iter_cloned", since = "1.1.0")]
 impl<'a, I, T: 'a> Iterator for Cloned<I>
     where I: Iterator<Item=&'a T>, T: Clone
@@ -267,16 +280,16 @@ impl<'a, I, T: 'a> Iterator for Cloned<I>
         self.it.size_hint()
     }
 
-    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
         Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
     {
-        self.it.try_fold(init, move |acc, elt| f(acc, elt.clone()))
+        self.it.try_fold(init, clone_try_fold(f))
     }
 
-    fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
+    fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
-        self.it.fold(init, move |acc, elt| f(acc, elt.clone()))
+        self.it.map(T::clone).fold(init, f)
     }
 }
 
@@ -288,16 +301,16 @@ impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
         self.it.next_back().cloned()
     }
 
-    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+    fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
         Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
     {
-        self.it.try_rfold(init, move |acc, elt| f(acc, elt.clone()))
+        self.it.try_rfold(init, clone_try_fold(f))
     }
 
-    fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
+    fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
-        self.it.rfold(init, move |acc, elt| f(acc, elt.clone()))
+        self.it.map(T::clone).rfold(init, f)
     }
 }
 
@@ -392,6 +405,36 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
             _ => (usize::MAX, None)
         }
     }
+
+    #[inline]
+    fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
+    where
+        F: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>,
+    {
+        // fully iterate the current iterator. this is necessary because
+        // `self.iter` may be empty even when `self.orig` isn't
+        acc = self.iter.try_fold(acc, &mut f)?;
+        self.iter = self.orig.clone();
+
+        // complete a full cycle, keeping track of whether the cycled
+        // iterator is empty or not. we need to return early in case
+        // of an empty iterator to prevent an infinite loop
+        let mut is_empty = true;
+        acc = self.iter.try_fold(acc, |acc, x| {
+            is_empty = false;
+            f(acc, x)
+        })?;
+
+        if is_empty {
+            return Try::from_ok(acc);
+        }
+
+        loop {
+            self.iter = self.orig.clone();
+            acc = self.iter.try_fold(acc, &mut f)?;
+        }
+    }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
@@ -435,14 +478,24 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let inner_hint = self.iter.size_hint();
+        #[inline]
+        fn first_size(step: usize) -> impl Fn(usize) -> usize {
+            move |n| if n == 0 { 0 } else { 1 + (n - 1) / (step + 1) }
+        }
+
+        #[inline]
+        fn other_size(step: usize) -> impl Fn(usize) -> usize {
+            move |n| n / (step + 1)
+        }
+
+        let (low, high) = self.iter.size_hint();
 
         if self.first_take {
-            let f = |n| if n == 0 { 0 } else { 1 + (n-1)/(self.step+1) };
-            (f(inner_hint.0), inner_hint.1.map(f))
+            let f = first_size(self.step);
+            (f(low), high.map(f))
         } else {
-            let f = |n| n / (self.step+1);
-            (f(inner_hint.0), inner_hint.1.map(f))
+            let f = other_size(self.step);
+            (f(low), high.map(f))
         }
     }
 
@@ -490,6 +543,39 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
     }
 }
 
+impl<I> StepBy<I> where I: ExactSizeIterator {
+    // The zero-based index starting from the end of the iterator of the
+    // last element. Used in the `DoubleEndedIterator` implementation.
+    fn next_back_index(&self) -> usize {
+        let rem = self.iter.len() % (self.step + 1);
+        if self.first_take {
+            if rem == 0 { self.step } else { rem - 1 }
+        } else {
+            rem
+        }
+    }
+}
+
+#[stable(feature = "double_ended_step_by_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for StepBy<I> where I: DoubleEndedIterator + ExactSizeIterator {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.nth_back(self.next_back_index())
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        // `self.iter.nth_back(usize::MAX)` does the right thing here when `n`
+        // is out of bounds because the length of `self.iter` does not exceed
+        // `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is
+        // zero-indexed
+        let n = n
+            .saturating_mul(self.step + 1)
+            .saturating_add(self.next_back_index());
+        self.iter.nth_back(n)
+    }
+}
+
 // StepBy can only make the iterator shorter, so the len will still fit.
 #[stable(feature = "iterator_step_by", since = "1.28.0")]
 impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
@@ -566,6 +652,20 @@ impl<I: fmt::Debug, F> fmt::Debug for Map<I, F> {
     }
 }
 
+fn map_fold<T, B, Acc>(
+    mut f: impl FnMut(T) -> B,
+    mut g: impl FnMut(Acc, B) -> Acc,
+) -> impl FnMut(Acc, T) -> Acc {
+    move |acc, elt| g(acc, f(elt))
+}
+
+fn map_try_fold<'a, T, B, Acc, R>(
+    f: &'a mut impl FnMut(T) -> B,
+    mut g: impl FnMut(Acc, B) -> R + 'a,
+) -> impl FnMut(Acc, T) -> R + 'a {
+    move |acc, elt| g(acc, f(elt))
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
     type Item = B;
@@ -580,18 +680,16 @@ impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
         self.iter.size_hint()
     }
 
-    fn try_fold<Acc, G, R>(&mut self, init: Acc, mut g: G) -> R where
+    fn try_fold<Acc, G, R>(&mut self, init: Acc, g: G) -> R where
         Self: Sized, G: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let f = &mut self.f;
-        self.iter.try_fold(init, move |acc, elt| g(acc, f(elt)))
+        self.iter.try_fold(init, map_try_fold(&mut self.f, g))
     }
 
-    fn fold<Acc, G>(self, init: Acc, mut g: G) -> Acc
+    fn fold<Acc, G>(self, init: Acc, g: G) -> Acc
         where G: FnMut(Acc, Self::Item) -> Acc,
     {
-        let mut f = self.f;
-        self.iter.fold(init, move |acc, elt| g(acc, f(elt)))
+        self.iter.fold(init, map_fold(self.f, g))
     }
 }
 
@@ -604,18 +702,16 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where
         self.iter.next_back().map(&mut self.f)
     }
 
-    fn try_rfold<Acc, G, R>(&mut self, init: Acc, mut g: G) -> R where
+    fn try_rfold<Acc, G, R>(&mut self, init: Acc, g: G) -> R where
         Self: Sized, G: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let f = &mut self.f;
-        self.iter.try_rfold(init, move |acc, elt| g(acc, f(elt)))
+        self.iter.try_rfold(init, map_try_fold(&mut self.f, g))
     }
 
-    fn rfold<Acc, G>(self, init: Acc, mut g: G) -> Acc
+    fn rfold<Acc, G>(self, init: Acc, g: G) -> Acc
         where G: FnMut(Acc, Self::Item) -> Acc,
     {
-        let mut f = self.f;
-        self.iter.rfold(init, move |acc, elt| g(acc, f(elt)))
+        self.iter.rfold(init, map_fold(self.f, g))
     }
 }
 
@@ -682,13 +778,27 @@ impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
     }
 }
 
+fn filter_fold<T, Acc>(
+    mut predicate: impl FnMut(&T) -> bool,
+    mut fold: impl FnMut(Acc, T) -> Acc,
+) -> impl FnMut(Acc, T) -> Acc {
+    move |acc, item| if predicate(&item) { fold(acc, item) } else { acc }
+}
+
+fn filter_try_fold<'a, T, Acc, R: Try<Ok = Acc>>(
+    predicate: &'a mut impl FnMut(&T) -> bool,
+    mut fold: impl FnMut(Acc, T) -> R + 'a,
+) -> impl FnMut(Acc, T) -> R + 'a {
+    move |acc, item| if predicate(&item) { fold(acc, item) } else { R::from_ok(acc) }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {
     type Item = I::Item;
 
     #[inline]
     fn next(&mut self) -> Option<I::Item> {
-        self.try_for_each(Err).err()
+        self.iter.find(&mut self.predicate)
     }
 
     #[inline]
@@ -710,32 +820,26 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
     // leaving more budget for LLVM optimizations.
     #[inline]
     fn count(self) -> usize {
-        let mut predicate = self.predicate;
-        self.iter.map(|x| predicate(&x) as usize).sum()
+        #[inline]
+        fn to_usize<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut(T) -> usize {
+            move |x| predicate(&x) as usize
+        }
+
+        self.iter.map(to_usize(self.predicate)).sum()
     }
 
     #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let predicate = &mut self.predicate;
-        self.iter.try_fold(init, move |acc, item| if predicate(&item) {
-            fold(acc, item)
-        } else {
-            Try::from_ok(acc)
-        })
+        self.iter.try_fold(init, filter_try_fold(&mut self.predicate, fold))
     }
 
     #[inline]
-    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        let mut predicate = self.predicate;
-        self.iter.fold(init, move |acc, item| if predicate(&item) {
-            fold(acc, item)
-        } else {
-            acc
-        })
+        self.iter.fold(init, filter_fold(self.predicate, fold))
     }
 }
 
@@ -745,31 +849,21 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
 {
     #[inline]
     fn next_back(&mut self) -> Option<I::Item> {
-        self.try_rfold((), |_, x| Err(x)).err()
+        self.iter.rfind(&mut self.predicate)
     }
 
     #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let predicate = &mut self.predicate;
-        self.iter.try_rfold(init, move |acc, item| if predicate(&item) {
-            fold(acc, item)
-        } else {
-            Try::from_ok(acc)
-        })
+        self.iter.try_rfold(init, filter_try_fold(&mut self.predicate, fold))
     }
 
     #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        let mut predicate = self.predicate;
-        self.iter.rfold(init, move |acc, item| if predicate(&item) {
-            fold(acc, item)
-        } else {
-            acc
-        })
+        self.iter.rfold(init, filter_fold(self.predicate, fold))
     }
 }
 
@@ -806,6 +900,26 @@ impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
     }
 }
 
+fn filter_map_fold<T, B, Acc>(
+    mut f: impl FnMut(T) -> Option<B>,
+    mut fold: impl FnMut(Acc, B) -> Acc,
+) -> impl FnMut(Acc, T) -> Acc {
+    move |acc, item| match f(item) {
+        Some(x) => fold(acc, x),
+        None => acc,
+    }
+}
+
+fn filter_map_try_fold<'a, T, B, Acc, R: Try<Ok = Acc>>(
+    f: &'a mut impl FnMut(T) -> Option<B>,
+    mut fold: impl FnMut(Acc, B) -> R + 'a,
+) -> impl FnMut(Acc, T) -> R + 'a {
+    move |acc, item| match f(item) {
+        Some(x) => fold(acc, x),
+        None => R::from_ok(acc),
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
     where F: FnMut(I::Item) -> Option<B>,
@@ -814,7 +928,7 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
 
     #[inline]
     fn next(&mut self) -> Option<B> {
-        self.try_for_each(Err).err()
+        self.iter.find_map(&mut self.f)
     }
 
     #[inline]
@@ -824,25 +938,17 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
     }
 
     #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let f = &mut self.f;
-        self.iter.try_fold(init, move |acc, item| match f(item) {
-            Some(x) => fold(acc, x),
-            None => Try::from_ok(acc),
-        })
+        self.iter.try_fold(init, filter_map_try_fold(&mut self.f, fold))
     }
 
     #[inline]
-    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        let mut f = self.f;
-        self.iter.fold(init, move |acc, item| match f(item) {
-            Some(x) => fold(acc, x),
-            None => acc,
-        })
+        self.iter.fold(init, filter_map_fold(self.f, fold))
     }
 }
 
@@ -852,29 +958,31 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
 {
     #[inline]
     fn next_back(&mut self) -> Option<B> {
-        self.try_rfold((), |_, x| Err(x)).err()
+        #[inline]
+        fn find<T, B>(
+            f: &mut impl FnMut(T) -> Option<B>
+        ) -> impl FnMut((), T) -> LoopState<(), B> + '_ {
+            move |(), x| match f(x) {
+                Some(x) => LoopState::Break(x),
+                None => LoopState::Continue(()),
+            }
+        }
+
+        self.iter.try_rfold((), find(&mut self.f)).break_value()
     }
 
     #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let f = &mut self.f;
-        self.iter.try_rfold(init, move |acc, item| match f(item) {
-            Some(x) => fold(acc, x),
-            None => Try::from_ok(acc),
-        })
+        self.iter.try_rfold(init, filter_map_try_fold(&mut self.f, fold))
     }
 
     #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        let mut f = self.f;
-        self.iter.rfold(init, move |acc, item| match f(item) {
-            Some(x) => fold(acc, x),
-            None => acc,
-        })
+        self.iter.rfold(init, filter_map_fold(self.f, fold))
     }
 }
 
@@ -916,14 +1024,12 @@ impl<I> Iterator for Enumerate<I> where I: Iterator {
     ///
     /// Might panic if the index of the element overflows a `usize`.
     #[inline]
-    #[rustc_inherit_overflow_checks]
     fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
-        self.iter.next().map(|a| {
-            let ret = (self.count, a);
-            // Possible undefined overflow.
-            self.count += 1;
-            ret
-        })
+        let a = self.iter.next()?;
+        let i = self.count;
+        // Possible undefined overflow.
+        AddAssign::add_assign(&mut self.count, 1);
+        Some((i, a))
     }
 
     #[inline]
@@ -932,13 +1038,12 @@ impl<I> Iterator for Enumerate<I> where I: Iterator {
     }
 
     #[inline]
-    #[rustc_inherit_overflow_checks]
     fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> {
-        self.iter.nth(n).map(|a| {
-            let i = self.count + n;
-            self.count = i + 1;
-            (i, a)
-        })
+        let a = self.iter.nth(n)?;
+        // Possible undefined overflow.
+        let i = Add::add(self.count, n);
+        self.count = Add::add(i, 1);
+        Some((i, a))
     }
 
     #[inline]
@@ -947,29 +1052,43 @@ impl<I> Iterator for Enumerate<I> where I: Iterator {
     }
 
     #[inline]
-    #[rustc_inherit_overflow_checks]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let count = &mut self.count;
-        self.iter.try_fold(init, move |acc, item| {
-            let acc = fold(acc, (*count, item));
-            *count += 1;
-            acc
-        })
+        #[inline]
+        fn enumerate<'a, T, Acc, R>(
+            count: &'a mut usize,
+            mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
+        ) -> impl FnMut(Acc, T) -> R + 'a {
+            move |acc, item| {
+                let acc = fold(acc, (*count, item));
+                // Possible undefined overflow.
+                AddAssign::add_assign(count, 1);
+                acc
+            }
+        }
+
+        self.iter.try_fold(init, enumerate(&mut self.count, fold))
     }
 
     #[inline]
-    #[rustc_inherit_overflow_checks]
-    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        let mut count = self.count;
-        self.iter.fold(init, move |acc, item| {
-            let acc = fold(acc, (count, item));
-            count += 1;
-            acc
-        })
+        #[inline]
+        fn enumerate<T, Acc>(
+            mut count: usize,
+            mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
+        ) -> impl FnMut(Acc, T) -> Acc {
+            move |acc, item| {
+                let acc = fold(acc, (count, item));
+                // Possible undefined overflow.
+                AddAssign::add_assign(&mut count, 1);
+                acc
+            }
+        }
+
+        self.iter.fold(init, enumerate(self.count, fold))
     }
 }
 
@@ -979,48 +1098,60 @@ impl<I> DoubleEndedIterator for Enumerate<I> where
 {
     #[inline]
     fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
-        self.iter.next_back().map(|a| {
-            let len = self.iter.len();
-            // Can safely add, `ExactSizeIterator` promises that the number of
-            // elements fits into a `usize`.
-            (self.count + len, a)
-        })
+        let a = self.iter.next_back()?;
+        let len = self.iter.len();
+        // Can safely add, `ExactSizeIterator` promises that the number of
+        // elements fits into a `usize`.
+        Some((self.count + len, a))
     }
 
     #[inline]
     fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
-        self.iter.nth_back(n).map(|a| {
-            let len = self.iter.len();
-            // Can safely add, `ExactSizeIterator` promises that the number of
-            // elements fits into a `usize`.
-            (self.count + len, a)
-        })
+        let a = self.iter.nth_back(n)?;
+        let len = self.iter.len();
+        // Can safely add, `ExactSizeIterator` promises that the number of
+        // elements fits into a `usize`.
+        Some((self.count + len, a))
     }
 
     #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
         // Can safely add and subtract the count, as `ExactSizeIterator` promises
         // that the number of elements fits into a `usize`.
-        let mut count = self.count + self.iter.len();
-        self.iter.try_rfold(init, move |acc, item| {
-            count -= 1;
-            fold(acc, (count, item))
-        })
+        fn enumerate<T, Acc, R>(
+            mut count: usize,
+            mut fold: impl FnMut(Acc, (usize, T)) -> R,
+        ) -> impl FnMut(Acc, T) -> R {
+            move |acc, item| {
+                count -= 1;
+                fold(acc, (count, item))
+            }
+        }
+
+        let count = self.count + self.iter.len();
+        self.iter.try_rfold(init, enumerate(count, fold))
     }
 
     #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
         // Can safely add and subtract the count, as `ExactSizeIterator` promises
         // that the number of elements fits into a `usize`.
-        let mut count = self.count + self.iter.len();
-        self.iter.rfold(init, move |acc, item| {
-            count -= 1;
-            fold(acc, (count, item))
-        })
+        fn enumerate<T, Acc>(
+            mut count: usize,
+            mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
+        ) -> impl FnMut(Acc, T) -> Acc {
+            move |acc, item| {
+                count -= 1;
+                fold(acc, (count, item))
+            }
+        }
+
+        let count = self.count + self.iter.len();
+        self.iter.rfold(init, enumerate(count, fold))
     }
 }
 
@@ -1134,7 +1265,10 @@ impl<I: Iterator> Iterator for Peekable<I> {
         };
         let (lo, hi) = self.iter.size_hint();
         let lo = lo.saturating_add(peek_len);
-        let hi = hi.and_then(|x| x.checked_add(peek_len));
+        let hi = match hi {
+            Some(x) => x.checked_add(peek_len),
+            None => None,
+        };
         (lo, hi)
     }
 
@@ -1163,6 +1297,45 @@ impl<I: Iterator> Iterator for Peekable<I> {
     }
 }
 
+#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.next_back().or_else(|| self.peeked.take().and_then(|x| x))
+    }
+
+    #[inline]
+    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        match self.peeked.take() {
+            Some(None) => return Try::from_ok(init),
+            Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
+                Ok(acc) => f(acc, v),
+                Err(e) => {
+                    self.peeked = Some(Some(v));
+                    Try::from_error(e)
+                }
+            },
+            None => self.iter.try_rfold(init, f),
+        }
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        match self.peeked {
+            Some(None) => return init,
+            Some(Some(v)) => {
+                let acc = self.iter.rfold(init, &mut fold);
+                fold(acc, v)
+            }
+            None => self.iter.rfold(init, fold),
+        }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
 
@@ -1254,16 +1427,23 @@ impl<I: Iterator, P> Iterator for SkipWhile<I, P>
 
     #[inline]
     fn next(&mut self) -> Option<I::Item> {
+        fn check<'a, T>(
+            flag: &'a mut bool,
+            pred: &'a mut impl FnMut(&T) -> bool,
+        ) -> impl FnMut(&T) -> bool + 'a {
+            move |x| {
+                if *flag || !pred(x) {
+                    *flag = true;
+                    true
+                } else {
+                    false
+                }
+            }
+        }
+
         let flag = &mut self.flag;
         let pred = &mut self.predicate;
-        self.iter.find(move |x| {
-            if *flag || !pred(x) {
-                *flag = true;
-                true
-            } else {
-                false
-            }
-        })
+        self.iter.find(check(flag, pred))
     }
 
     #[inline]
@@ -1345,14 +1525,13 @@ impl<I: Iterator, P> Iterator for TakeWhile<I, P>
         if self.flag {
             None
         } else {
-            self.iter.next().and_then(|x| {
-                if (self.predicate)(&x) {
-                    Some(x)
-                } else {
-                    self.flag = true;
-                    None
-                }
-            })
+            let x = self.iter.next()?;
+            if (self.predicate)(&x) {
+                Some(x)
+            } else {
+                self.flag = true;
+                None
+            }
         }
     }
 
@@ -1367,22 +1546,30 @@ impl<I: Iterator, P> Iterator for TakeWhile<I, P>
     }
 
     #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        if self.flag {
-            Try::from_ok(init)
-        } else {
-            let flag = &mut self.flag;
-            let p = &mut self.predicate;
-            self.iter.try_fold(init, move |acc, x|{
+        fn check<'a, T, Acc, R: Try<Ok = Acc>>(
+            flag: &'a mut bool,
+            p: &'a mut impl FnMut(&T) -> bool,
+            mut fold: impl FnMut(Acc, T) -> R + 'a,
+        ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
+            move |acc, x| {
                 if p(&x) {
                     LoopState::from_try(fold(acc, x))
                 } else {
                     *flag = true;
                     LoopState::Break(Try::from_ok(acc))
                 }
-            }).into_try()
+            }
+        }
+
+        if self.flag {
+            Try::from_ok(init)
+        } else {
+            let flag = &mut self.flag;
+            let p = &mut self.predicate;
+            self.iter.try_fold(init, check(flag, p, fold)).into_try()
         }
     }
 }
@@ -1467,7 +1654,10 @@ impl<I> Iterator for Skip<I> where I: Iterator {
         let (lower, upper) = self.iter.size_hint();
 
         let lower = lower.saturating_sub(self.n);
-        let upper = upper.map(|x| x.saturating_sub(self.n));
+        let upper = match upper {
+            Some(x) => Some(x.saturating_sub(self.n)),
+            None => None,
+        };
 
         (lower, upper)
     }
@@ -1514,19 +1704,40 @@ impl<I> DoubleEndedIterator for Skip<I> where I: DoubleEndedIterator + ExactSize
         }
     }
 
-    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<I::Item> {
+        let len = self.len();
+        if n < len {
+            self.iter.nth_back(n)
+        } else {
+            if len > 0 {
+                // consume the original iterator
+                self.iter.nth_back(len-1);
+            }
+            None
+        }
+    }
+
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let mut n = self.len();
-        if n == 0 {
-            Try::from_ok(init)
-        } else {
-            self.iter.try_rfold(init, move |acc, x| {
+        fn check<T, Acc, R: Try<Ok = Acc>>(
+            mut n: usize,
+            mut fold: impl FnMut(Acc, T) -> R,
+        ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> {
+            move |acc, x| {
                 n -= 1;
                 let r = fold(acc, x);
                 if n == 0 { LoopState::Break(r) }
                 else { LoopState::from_try(r) }
-            }).into_try()
+            }
+        }
+
+        let n = self.len();
+        if n == 0 {
+            Try::from_ok(init)
+        } else {
+            self.iter.try_rfold(init, check(n, fold)).into_try()
         }
     }
 }
@@ -1601,19 +1812,71 @@ impl<I> Iterator for Take<I> where I: Iterator{
     }
 
     #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        if self.n == 0 {
-            Try::from_ok(init)
-        } else {
-            let n = &mut self.n;
-            self.iter.try_fold(init, move |acc, x| {
+        fn check<'a, T, Acc, R: Try<Ok = Acc>>(
+            n: &'a mut usize,
+            mut fold: impl FnMut(Acc, T) -> R + 'a,
+        ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
+            move |acc, x| {
                 *n -= 1;
                 let r = fold(acc, x);
                 if *n == 0 { LoopState::Break(r) }
                 else { LoopState::from_try(r) }
-            }).into_try()
+            }
+        }
+
+        if self.n == 0 {
+            Try::from_ok(init)
+        } else {
+            let n = &mut self.n;
+            self.iter.try_fold(init, check(n, fold)).into_try()
+        }
+    }
+}
+
+#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for Take<I> where I: DoubleEndedIterator + ExactSizeIterator {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        if self.n == 0 {
+            None
+        } else {
+            let n = self.n;
+            self.n -= 1;
+            self.iter.nth_back(self.iter.len().saturating_sub(n))
+        }
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.iter.len();
+        if self.n > n {
+            let m = len.saturating_sub(self.n) + n;
+            self.n -= n + 1;
+            self.iter.nth_back(m)
+        } else {
+            if len > 0 {
+                self.iter.nth_back(len - 1);
+            }
+            None
+        }
+    }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok = Acc>
+    {
+        if self.n == 0 {
+            Try::from_ok(init)
+        } else {
+            let len = self.iter.len();
+            if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
+                Try::from_ok(init)
+            } else {
+                self.iter.try_rfold(init, fold)
+            }
         }
     }
 }
@@ -1667,7 +1930,8 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where
 
     #[inline]
     fn next(&mut self) -> Option<B> {
-        self.iter.next().and_then(|a| (self.f)(&mut self.state, a))
+        let a = self.iter.next()?;
+        (self.f)(&mut self.state, a)
     }
 
     #[inline]
@@ -1677,17 +1941,25 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where
     }
 
     #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
+        fn scan<'a, T, St, B, Acc, R: Try<Ok = Acc>>(
+            state: &'a mut St,
+            f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
+            mut fold: impl FnMut(Acc, B) -> R + 'a,
+        ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a {
+            move |acc, x| {
+                match f(state, x) {
+                    None => LoopState::Break(Try::from_ok(acc)),
+                    Some(x) => LoopState::from_try(fold(acc, x)),
+                }
+            }
+        }
+
         let state = &mut self.state;
         let f = &mut self.f;
-        self.iter.try_fold(init, move |acc, x| {
-            match f(state, x) {
-                None => LoopState::Break(Try::from_ok(acc)),
-                Some(x) => LoopState::from_try(fold(acc, x)),
-            }
-        }).into_try()
+        self.iter.try_fold(init, scan(state, f, fold)).into_try()
     }
 }
 
@@ -1978,6 +2250,20 @@ impl<I: Iterator, F> Inspect<I, F> where F: FnMut(&I::Item) {
     }
 }
 
+fn inspect_fold<T, Acc>(
+    mut f: impl FnMut(&T),
+    mut fold: impl FnMut(Acc, T) -> Acc,
+) -> impl FnMut(Acc, T) -> Acc {
+    move |acc, item| { f(&item); fold(acc, item) }
+}
+
+fn inspect_try_fold<'a, T, Acc, R>(
+    f: &'a mut impl FnMut(&T),
+    mut fold: impl FnMut(Acc, T) -> R + 'a,
+) -> impl FnMut(Acc, T) -> R + 'a {
+    move |acc, item| { f(&item); fold(acc, item) }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: Iterator, F> Iterator for Inspect<I, F> where F: FnMut(&I::Item) {
     type Item = I::Item;
@@ -1994,19 +2280,17 @@ impl<I: Iterator, F> Iterator for Inspect<I, F> where F: FnMut(&I::Item) {
     }
 
     #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let f = &mut self.f;
-        self.iter.try_fold(init, move |acc, item| { f(&item); fold(acc, item) })
+        self.iter.try_fold(init, inspect_try_fold(&mut self.f, fold))
     }
 
     #[inline]
-    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        let mut f = self.f;
-        self.iter.fold(init, move |acc, item| { f(&item); fold(acc, item) })
+        self.iter.fold(init, inspect_fold(self.f, fold))
     }
 }
 
@@ -2021,19 +2305,17 @@ impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
     }
 
     #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
-        let f = &mut self.f;
-        self.iter.try_rfold(init, move |acc, item| { f(&item); fold(acc, item) })
+        self.iter.try_rfold(init, inspect_try_fold(&mut self.f, fold))
     }
 
     #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        let mut f = self.f;
-        self.iter.rfold(init, move |acc, item| { f(&item); fold(acc, item) })
+        self.iter.rfold(init, inspect_fold(self.f, fold))
     }
 }
 
@@ -2053,3 +2335,66 @@ impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F>
 #[stable(feature = "fused", since = "1.26.0")]
 impl<I: FusedIterator, F> FusedIterator for Inspect<I, F>
     where F: FnMut(&I::Item) {}
+
+/// An iterator adapter that produces output as long as the underlying
+/// iterator produces `Result::Ok` values.
+///
+/// If an error is encountered, the iterator stops and the error is
+/// stored.
+pub(crate) struct ResultShunt<'a, I, E> {
+    iter: I,
+    error: &'a mut Result<(), E>,
+}
+
+/// Process the given iterator as if it yielded a `T` instead of a
+/// `Result<T, _>`. Any errors will stop the inner iterator and
+/// the overall result will be an error.
+pub(crate) fn process_results<I, T, E, F, U>(iter: I, mut f: F) -> Result<U, E>
+where
+    I: Iterator<Item = Result<T, E>>,
+    for<'a> F: FnMut(ResultShunt<'a, I, E>) -> U,
+{
+    let mut error = Ok(());
+    let shunt = ResultShunt {
+        iter,
+        error: &mut error,
+    };
+    let value = f(shunt);
+    error.map(|()| value)
+}
+
+impl<I, T, E> Iterator for ResultShunt<'_, I, E>
+    where I: Iterator<Item = Result<T, E>>
+{
+    type Item = T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.find(|_| true)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        if self.error.is_err() {
+            (0, Some(0))
+        } else {
+            let (_, upper) = self.iter.size_hint();
+            (0, upper)
+        }
+    }
+
+    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
+    where
+        F: FnMut(B, Self::Item) -> R,
+        R: Try<Ok = B>,
+    {
+        let error = &mut *self.error;
+        self.iter
+            .try_fold(init, |acc, x| match x {
+                Ok(x) => LoopState::from_try(f(acc, x)),
+                Err(e) => {
+                    *error = Err(e);
+                    LoopState::Break(Try::from_ok(acc))
+                }
+            })
+            .into_try()
+    }
+}
diff --git a/src/libcore/iter/adapters/zip.rs b/src/libcore/iter/adapters/zip.rs
index 06f047d9287..430ceacdd9f 100644
--- a/src/libcore/iter/adapters/zip.rs
+++ b/src/libcore/iter/adapters/zip.rs
@@ -94,11 +94,9 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
 
     #[inline]
     default fn next(&mut self) -> Option<(A::Item, B::Item)> {
-        self.a.next().and_then(|x| {
-            self.b.next().and_then(|y| {
-                Some((x, y))
-            })
-        })
+        let x = self.a.next()?;
+        let y = self.b.next()?;
+        Some((x, y))
     }
 
     #[inline]
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 1601357d3b0..aba8e84d58b 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -140,6 +140,11 @@
 //! call `next()` on your iterator, until it reaches `None`. Let's go over that
 //! next.
 //!
+//! Also note that `Iterator` provides a default implementation of methods such as `nth` and `fold`
+//! which call `next` internally. However, it is also possible to write a custom implementation of
+//! methods like `nth` and `fold` if an iterator can compute them more efficiently without calling
+//! `next`.
+//!
 //! # for Loops and IntoIterator
 //!
 //! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic
@@ -355,7 +360,7 @@ pub use self::adapters::Flatten;
 #[stable(feature = "iter_copied", since = "1.36.0")]
 pub use self::adapters::Copied;
 
-pub(crate) use self::adapters::TrustedRandomAccess;
+pub(crate) use self::adapters::{TrustedRandomAccess, process_results};
 
 mod range;
 mod sources;
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index f8a975cc8d4..efda3b263cc 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -34,6 +34,13 @@ pub trait Step: Clone + PartialOrd + Sized {
 
     /// Adds a `usize`, returning `None` on overflow.
     fn add_usize(&self, n: usize) -> Option<Self>;
+
+    /// Subtracts a `usize`, returning `None` on underflow.
+    fn sub_usize(&self, n: usize) -> Option<Self> {
+        // this default implementation makes the addition of `sub_usize` a non-breaking change
+        let _ = n;
+        unimplemented!()
+    }
 }
 
 // These are still macro-generated because the integer literals resolve to different types.
@@ -85,6 +92,15 @@ macro_rules! step_impl_unsigned {
                 }
             }
 
+            #[inline]
+            #[allow(unreachable_patterns)]
+            fn sub_usize(&self, n: usize) -> Option<Self> {
+                match <$t>::try_from(n) {
+                    Ok(n_as_t) => self.checked_sub(n_as_t),
+                    Err(_) => None,
+                }
+            }
+
             step_identical_methods!();
         }
     )*)
@@ -125,6 +141,25 @@ macro_rules! step_impl_signed {
                 }
             }
 
+            #[inline]
+            #[allow(unreachable_patterns)]
+            fn sub_usize(&self, n: usize) -> Option<Self> {
+                match <$unsigned>::try_from(n) {
+                    Ok(n_as_unsigned) => {
+                        // Wrapping in unsigned space handles cases like
+                        // `80_i8.sub_usize(200) == Some(-120_i8)`,
+                        // even though 200_usize is out of range for i8.
+                        let wrapped = (*self as $unsigned).wrapping_sub(n_as_unsigned) as $t;
+                        if wrapped <= *self {
+                            Some(wrapped)
+                        } else {
+                            None  // Subtraction underflowed
+                        }
+                    }
+                    Err(_) => None,
+                }
+            }
+
             step_identical_methods!();
         }
     )*)
@@ -246,6 +281,19 @@ impl<A: Step> DoubleEndedIterator for ops::Range<A> {
             None
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<A> {
+        if let Some(minus_n) = self.end.sub_usize(n) {
+            if minus_n > self.start {
+                self.end = minus_n.sub_one();
+                return Some(self.end.clone())
+            }
+        }
+
+        self.end = self.start.clone();
+        None
+    }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
@@ -404,6 +452,34 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
     }
 
     #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<A> {
+        self.compute_is_empty();
+        if self.is_empty.unwrap_or_default() {
+            return None;
+        }
+
+        if let Some(minus_n) = self.end.sub_usize(n) {
+            use crate::cmp::Ordering::*;
+
+            match minus_n.partial_cmp(&self.start) {
+                Some(Greater) => {
+                    self.is_empty = Some(false);
+                    self.end = minus_n.sub_one();
+                    return Some(minus_n);
+                }
+                Some(Equal) => {
+                    self.is_empty = Some(true);
+                    return Some(minus_n);
+                }
+                _ => {}
+            }
+        }
+
+        self.is_empty = Some(true);
+        None
+    }
+
+    #[inline]
     fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
         Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
     {
diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs
index 70a3b70c180..183176005ed 100644
--- a/src/libcore/iter/sources.rs
+++ b/src/libcore/iter/sources.rs
@@ -394,7 +394,8 @@ impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        self.gen.take().map(|f| f())
+        let f = self.gen.take()?;
+        Some(f())
     }
 
     #[inline]
@@ -608,10 +609,9 @@ impl<T, F> Iterator for Successors<T, F>
 
     #[inline]
     fn next(&mut self) -> Option<Self::Item> {
-        self.next.take().map(|item| {
-            self.next = (self.succ)(&item);
-            item
-        })
+        let item = self.next.take()?;
+        self.next = (self.succ)(&item);
+        Some(item)
     }
 
     #[inline]
diff --git a/src/libcore/iter/traits/accum.rs b/src/libcore/iter/traits/accum.rs
index 7815fe9c59d..818f0330329 100644
--- a/src/libcore/iter/traits/accum.rs
+++ b/src/libcore/iter/traits/accum.rs
@@ -1,5 +1,6 @@
 use crate::ops::{Mul, Add};
 use crate::num::Wrapping;
+use crate::iter;
 
 /// Trait to represent types that can be created by summing up an iterator.
 ///
@@ -72,10 +73,10 @@ macro_rules! integer_sum_product {
     ($($a:ty)*) => (
         integer_sum_product!(@impls 0, 1,
                 #[stable(feature = "iter_arith_traits", since = "1.12.0")],
-                $($a)+);
+                $($a)*);
         integer_sum_product!(@impls Wrapping(0), Wrapping(1),
                 #[stable(feature = "wrapping_iter_arith", since = "1.14.0")],
-                $(Wrapping<$a>)+);
+                $(Wrapping<$a>)*);
     );
 }
 
@@ -84,28 +85,28 @@ macro_rules! float_sum_product {
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Sum for $a {
             fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
-                iter.fold(0.0, |a, b| a + b)
+                iter.fold(0.0, Add::add)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl Product for $a {
             fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
-                iter.fold(1.0, |a, b| a * b)
+                iter.fold(1.0, Mul::mul)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Sum<&'a $a> for $a {
             fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
-                iter.fold(0.0, |a, b| a + *b)
+                iter.fold(0.0, Add::add)
             }
         }
 
         #[stable(feature = "iter_arith_traits", since = "1.12.0")]
         impl<'a> Product<&'a $a> for $a {
             fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
-                iter.fold(1.0, |a, b| a * *b)
+                iter.fold(1.0, Mul::mul)
             }
         }
     )*)
@@ -114,74 +115,6 @@ macro_rules! float_sum_product {
 integer_sum_product! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
 float_sum_product! { f32 f64 }
 
-/// An iterator adapter that produces output as long as the underlying
-/// iterator produces `Result::Ok` values.
-///
-/// If an error is encountered, the iterator stops and the error is
-/// stored. The error may be recovered later via `reconstruct`.
-struct ResultShunt<I, E> {
-    iter: I,
-    error: Option<E>,
-}
-
-impl<I, T, E> ResultShunt<I, E>
-    where I: Iterator<Item = Result<T, E>>
-{
-    /// Process the given iterator as if it yielded a `T` instead of a
-    /// `Result<T, _>`. Any errors will stop the inner iterator and
-    /// the overall result will be an error.
-    pub fn process<F, U>(iter: I, mut f: F) -> Result<U, E>
-        where F: FnMut(&mut Self) -> U
-    {
-        let mut shunt = ResultShunt::new(iter);
-        let value = f(shunt.by_ref());
-        shunt.reconstruct(value)
-    }
-
-    fn new(iter: I) -> Self {
-        ResultShunt {
-            iter,
-            error: None,
-        }
-    }
-
-    /// Consume the adapter and rebuild a `Result` value. This should
-    /// *always* be called, otherwise any potential error would be
-    /// lost.
-    fn reconstruct<U>(self, val: U) -> Result<U, E> {
-        match self.error {
-            None => Ok(val),
-            Some(e) => Err(e),
-        }
-    }
-}
-
-impl<I, T, E> Iterator for ResultShunt<I, E>
-    where I: Iterator<Item = Result<T, E>>
-{
-    type Item = T;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        match self.iter.next() {
-            Some(Ok(v)) => Some(v),
-            Some(Err(e)) => {
-                self.error = Some(e);
-                None
-            }
-            None => None,
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        if self.error.is_some() {
-            (0, Some(0))
-        } else {
-            let (_, upper) = self.iter.size_hint();
-            (0, upper)
-        }
-    }
-}
-
 #[stable(feature = "iter_arith_traits_result", since="1.16.0")]
 impl<T, U, E> Sum<Result<U, E>> for Result<T, E>
     where T: Sum<U>,
@@ -206,7 +139,7 @@ impl<T, U, E> Sum<Result<U, E>> for Result<T, E>
     fn sum<I>(iter: I) -> Result<T, E>
         where I: Iterator<Item = Result<U, E>>,
     {
-        ResultShunt::process(iter, |i| i.sum())
+        iter::process_results(iter, |i| i.sum())
     }
 }
 
@@ -220,6 +153,49 @@ impl<T, U, E> Product<Result<U, E>> for Result<T, E>
     fn product<I>(iter: I) -> Result<T, E>
         where I: Iterator<Item = Result<U, E>>,
     {
-        ResultShunt::process(iter, |i| i.product())
+        iter::process_results(iter, |i| i.product())
+    }
+}
+
+#[stable(feature = "iter_arith_traits_option", since = "1.37.0")]
+impl<T, U> Sum<Option<U>> for Option<T>
+where
+    T: Sum<U>,
+{
+    /// Takes each element in the `Iterator`: if it is a `None`, no further
+    /// elements are taken, and the `None` is returned. Should no `None` occur,
+    /// the sum of all elements is returned.
+    ///
+    /// # Examples
+    ///
+    /// This sums up the position of the character 'a' in a vector of strings,
+    /// if a word did not have the character 'a' the operation returns `None`:
+    ///
+    /// ```
+    /// let words = vec!["have", "a", "great", "day"];
+    /// let total: Option<usize> = words.iter().map(|w| w.find('a')).sum();
+    /// assert_eq!(total, Some(5));
+    /// ```
+    fn sum<I>(iter: I) -> Option<T>
+    where
+        I: Iterator<Item = Option<U>>,
+    {
+        iter.map(|x| x.ok_or(())).sum::<Result<_, _>>().ok()
+    }
+}
+
+#[stable(feature = "iter_arith_traits_option", since = "1.37.0")]
+impl<T, U> Product<Option<U>> for Option<T>
+where
+    T: Product<U>,
+{
+    /// Takes each element in the `Iterator`: if it is a `None`, no further
+    /// elements are taken, and the `None` is returned. Should no `None` occur,
+    /// the product of all elements is returned.
+    fn product<I>(iter: I) -> Option<T>
+    where
+        I: Iterator<Item = Option<U>>,
+    {
+        iter.map(|x| x.ok_or(())).product::<Result<_, _>>().ok()
     }
 }
diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs
index cd61ab5c552..25439136b85 100644
--- a/src/libcore/iter/traits/collect.rs
+++ b/src/libcore/iter/traits/collect.rs
@@ -195,8 +195,9 @@ pub trait FromIterator<A>: Sized {
 ///
 /// ```rust
 /// fn collect_as_strings<T>(collection: T) -> Vec<String>
-///     where T: IntoIterator,
-///           T::Item : std::fmt::Debug,
+/// where
+///     T: IntoIterator,
+///     T::Item: std::fmt::Debug,
 /// {
 ///     collection
 ///         .into_iter()
diff --git a/src/libcore/iter/traits/double_ended.rs b/src/libcore/iter/traits/double_ended.rs
index 06de95c0827..006b243ca42 100644
--- a/src/libcore/iter/traits/double_ended.rs
+++ b/src/libcore/iter/traits/double_ended.rs
@@ -69,7 +69,7 @@ pub trait DoubleEndedIterator: Iterator {
     /// Returns the `n`th element from the end of the iterator.
     ///
     /// This is essentially the reversed version of [`nth`]. Although like most indexing
-    /// operations, the count starts from zero, so `nth_back(0)` returns the first value fro
+    /// operations, the count starts from zero, so `nth_back(0)` returns the first value from
     /// the end, `nth_back(1)` the second, and so on.
     ///
     /// Note that all elements between the end and the returned element will be
@@ -88,7 +88,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iter_nth_back)]
     /// let a = [1, 2, 3];
     /// assert_eq!(a.iter().nth_back(2), Some(&1));
     /// ```
@@ -96,7 +95,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// Calling `nth_back()` multiple times doesn't rewind the iterator:
     ///
     /// ```
-    /// #![feature(iter_nth_back)]
     /// let a = [1, 2, 3];
     ///
     /// let mut iter = a.iter();
@@ -108,12 +106,11 @@ pub trait DoubleEndedIterator: Iterator {
     /// Returning `None` if there are less than `n + 1` elements:
     ///
     /// ```
-    /// #![feature(iter_nth_back)]
     /// let a = [1, 2, 3];
     /// assert_eq!(a.iter().nth_back(10), None);
     /// ```
     #[inline]
-    #[unstable(feature = "iter_nth_back", issue = "56995")]
+    #[stable(feature = "iter_nth_back", since = "1.37.0")]
     fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
         for x in self.rev() {
             if n == 0 { return Some(x) }
@@ -222,12 +219,17 @@ pub trait DoubleEndedIterator: Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_rfold", since = "1.27.0")]
-    fn rfold<B, F>(mut self, accum: B, mut f: F) -> B
+    fn rfold<B, F>(mut self, accum: B, f: F) -> B
     where
         Self: Sized,
         F: FnMut(B, Self::Item) -> B,
     {
-        self.try_rfold(accum, move |acc, x| Ok::<B, !>(f(acc, x))).unwrap()
+        #[inline]
+        fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
+            move |acc, x| Ok(f(acc, x))
+        }
+
+        self.try_rfold(accum, ok(f)).unwrap()
     }
 
     /// Searches for an element of an iterator from the back that satisfies a predicate.
@@ -274,15 +276,21 @@ pub trait DoubleEndedIterator: Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_rfind", since = "1.27.0")]
-    fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
+    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         Self: Sized,
         P: FnMut(&Self::Item) -> bool
     {
-        self.try_rfold((), move |(), x| {
-            if predicate(&x) { LoopState::Break(x) }
-            else { LoopState::Continue(()) }
-        }).break_value()
+        #[inline]
+        fn check<T>(
+            mut predicate: impl FnMut(&T) -> bool,
+        ) -> impl FnMut((), T) -> LoopState<(), T> {
+            move |(), x| {
+                if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
+            }
+        }
+
+        self.try_rfold((), check(predicate)).break_value()
     }
 }
 
diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs
index 403f3358105..d644787d2c4 100644
--- a/src/libcore/iter/traits/iterator.rs
+++ b/src/libcore/iter/traits/iterator.rs
@@ -1,5 +1,5 @@
 use crate::cmp::Ordering;
-use crate::ops::Try;
+use crate::ops::{Add, Try};
 
 use super::super::LoopState;
 use super::super::{Chain, Cycle, Copied, Cloned, Enumerate, Filter, FilterMap, Fuse};
@@ -234,11 +234,15 @@ pub trait Iterator {
     /// assert_eq!(a.iter().count(), 5);
     /// ```
     #[inline]
-    #[rustc_inherit_overflow_checks]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn count(self) -> usize where Self: Sized {
-        // Might overflow.
-        self.fold(0, |cnt, _| cnt + 1)
+        #[inline]
+        fn add1<T>(count: usize, _: T) -> usize {
+            // Might overflow.
+            Add::add(count, 1)
+        }
+
+        self.fold(0, add1)
     }
 
     /// Consumes the iterator, returning the last element.
@@ -263,9 +267,12 @@ pub trait Iterator {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn last(self) -> Option<Self::Item> where Self: Sized {
-        let mut last = None;
-        for x in self { last = Some(x); }
-        last
+        #[inline]
+        fn some<T>(_: Option<T>, x: T) -> Option<T> {
+            Some(x)
+        }
+
+        self.fold(None, some)
     }
 
     /// Returns the `n`th element of the iterator.
@@ -356,7 +363,7 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [0, 1, 2, 3, 4, 5];
-    /// let mut iter = a.into_iter().step_by(2);
+    /// let mut iter = a.iter().step_by(2);
     ///
     /// assert_eq!(iter.next(), Some(&0));
     /// assert_eq!(iter.next(), Some(&2));
@@ -531,7 +538,7 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.into_iter().map(|x| 2 * x);
+    /// let mut iter = a.iter().map(|x| 2 * x);
     ///
     /// assert_eq!(iter.next(), Some(2));
     /// assert_eq!(iter.next(), Some(4));
@@ -598,10 +605,15 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_for_each", since = "1.21.0")]
-    fn for_each<F>(self, mut f: F) where
+    fn for_each<F>(self, f: F) where
         Self: Sized, F: FnMut(Self::Item),
     {
-        self.fold((), move |(), item| f(item));
+        #[inline]
+        fn call<T>(mut f: impl FnMut(T)) -> impl FnMut((), T) {
+            move |(), item| f(item)
+        }
+
+        self.fold((), call(f));
     }
 
     /// Creates an iterator which uses a closure to determine if an element
@@ -620,7 +632,7 @@ pub trait Iterator {
     /// ```
     /// let a = [0i32, 1, 2];
     ///
-    /// let mut iter = a.into_iter().filter(|x| x.is_positive());
+    /// let mut iter = a.iter().filter(|x| x.is_positive());
     ///
     /// assert_eq!(iter.next(), Some(&1));
     /// assert_eq!(iter.next(), Some(&2));
@@ -634,7 +646,7 @@ pub trait Iterator {
     /// ```
     /// let a = [0, 1, 2];
     ///
-    /// let mut iter = a.into_iter().filter(|x| **x > 1); // need two *s!
+    /// let mut iter = a.iter().filter(|x| **x > 1); // need two *s!
     ///
     /// assert_eq!(iter.next(), Some(&2));
     /// assert_eq!(iter.next(), None);
@@ -646,7 +658,7 @@ pub trait Iterator {
     /// ```
     /// let a = [0, 1, 2];
     ///
-    /// let mut iter = a.into_iter().filter(|&x| *x > 1); // both & and *
+    /// let mut iter = a.iter().filter(|&x| *x > 1); // both & and *
     ///
     /// assert_eq!(iter.next(), Some(&2));
     /// assert_eq!(iter.next(), None);
@@ -657,7 +669,7 @@ pub trait Iterator {
     /// ```
     /// let a = [0, 1, 2];
     ///
-    /// let mut iter = a.into_iter().filter(|&&x| x > 1); // two &s
+    /// let mut iter = a.iter().filter(|&&x| x > 1); // two &s
     ///
     /// assert_eq!(iter.next(), Some(&2));
     /// assert_eq!(iter.next(), None);
@@ -837,7 +849,7 @@ pub trait Iterator {
     /// ```
     /// let a = [-1i32, 0, 1];
     ///
-    /// let mut iter = a.into_iter().skip_while(|x| x.is_negative());
+    /// let mut iter = a.iter().skip_while(|x| x.is_negative());
     ///
     /// assert_eq!(iter.next(), Some(&0));
     /// assert_eq!(iter.next(), Some(&1));
@@ -851,7 +863,7 @@ pub trait Iterator {
     /// ```
     /// let a = [-1, 0, 1];
     ///
-    /// let mut iter = a.into_iter().skip_while(|x| **x < 0); // need two *s!
+    /// let mut iter = a.iter().skip_while(|x| **x < 0); // need two *s!
     ///
     /// assert_eq!(iter.next(), Some(&0));
     /// assert_eq!(iter.next(), Some(&1));
@@ -863,7 +875,7 @@ pub trait Iterator {
     /// ```
     /// let a = [-1, 0, 1, -2];
     ///
-    /// let mut iter = a.into_iter().skip_while(|x| **x < 0);
+    /// let mut iter = a.iter().skip_while(|x| **x < 0);
     ///
     /// assert_eq!(iter.next(), Some(&0));
     /// assert_eq!(iter.next(), Some(&1));
@@ -898,7 +910,7 @@ pub trait Iterator {
     /// ```
     /// let a = [-1i32, 0, 1];
     ///
-    /// let mut iter = a.into_iter().take_while(|x| x.is_negative());
+    /// let mut iter = a.iter().take_while(|x| x.is_negative());
     ///
     /// assert_eq!(iter.next(), Some(&-1));
     /// assert_eq!(iter.next(), None);
@@ -911,7 +923,7 @@ pub trait Iterator {
     /// ```
     /// let a = [-1, 0, 1];
     ///
-    /// let mut iter = a.into_iter().take_while(|x| **x < 0); // need two *s!
+    /// let mut iter = a.iter().take_while(|x| **x < 0); // need two *s!
     ///
     /// assert_eq!(iter.next(), Some(&-1));
     /// assert_eq!(iter.next(), None);
@@ -922,7 +934,7 @@ pub trait Iterator {
     /// ```
     /// let a = [-1, 0, 1, -2];
     ///
-    /// let mut iter = a.into_iter().take_while(|x| **x < 0);
+    /// let mut iter = a.iter().take_while(|x| **x < 0);
     ///
     /// assert_eq!(iter.next(), Some(&-1));
     ///
@@ -937,7 +949,7 @@ pub trait Iterator {
     ///
     /// ```
     /// let a = [1, 2, 3, 4];
-    /// let mut iter = a.into_iter();
+    /// let mut iter = a.iter();
     ///
     /// let result: Vec<i32> = iter.by_ref()
     ///                            .take_while(|n| **n != 3)
@@ -964,6 +976,7 @@ pub trait Iterator {
     /// Creates an iterator that skips the first `n` elements.
     ///
     /// After they have been consumed, the rest of the elements are yielded.
+    /// Rather than overriding this method directly, instead override the `nth` method.
     ///
     /// # Examples
     ///
@@ -1321,7 +1334,7 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// let iter = a.into_iter();
+    /// let iter = a.iter();
     ///
     /// let sum: i32 = iter.take(5).fold(0, |acc, i| acc + i );
     ///
@@ -1334,7 +1347,7 @@ pub trait Iterator {
     /// // let's try that again
     /// let a = [1, 2, 3];
     ///
-    /// let mut iter = a.into_iter();
+    /// let mut iter = a.iter();
     ///
     /// // instead, we add in a .by_ref()
     /// let sum: i32 = iter.by_ref().take(2).fold(0, |acc, i| acc + i );
@@ -1471,6 +1484,11 @@ pub trait Iterator {
     /// `partition()` returns a pair, all of the elements for which it returned
     /// `true`, and all of the elements for which it returned `false`.
     ///
+    /// See also [`is_partitioned()`] and [`partition_in_place()`].
+    ///
+    /// [`is_partitioned()`]: #method.is_partitioned
+    /// [`partition_in_place()`]: #method.partition_in_place
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -1479,30 +1497,134 @@ pub trait Iterator {
     /// let a = [1, 2, 3];
     ///
     /// let (even, odd): (Vec<i32>, Vec<i32>) = a
-    ///     .into_iter()
+    ///     .iter()
     ///     .partition(|&n| n % 2 == 0);
     ///
     /// assert_eq!(even, vec![2]);
     /// assert_eq!(odd, vec![1, 3]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn partition<B, F>(self, mut f: F) -> (B, B) where
+    fn partition<B, F>(self, f: F) -> (B, B) where
         Self: Sized,
         B: Default + Extend<Self::Item>,
         F: FnMut(&Self::Item) -> bool
     {
+        #[inline]
+        fn extend<'a, T, B: Extend<T>>(
+            mut f: impl FnMut(&T) -> bool + 'a,
+            left: &'a mut B,
+            right: &'a mut B,
+        ) -> impl FnMut(T) + 'a {
+            move |x| {
+                if f(&x) {
+                    left.extend(Some(x));
+                } else {
+                    right.extend(Some(x));
+                }
+            }
+        }
+
         let mut left: B = Default::default();
         let mut right: B = Default::default();
 
-        for x in self {
-            if f(&x) {
-                left.extend(Some(x))
+        self.for_each(extend(f, &mut left, &mut right));
+
+        (left, right)
+    }
+
+    /// Reorder the elements of this iterator *in-place* according to the given predicate,
+    /// such that all those that return `true` precede all those that return `false`.
+    /// Returns the number of `true` elements found.
+    ///
+    /// The relative order of partitioned items is not maintained.
+    ///
+    /// See also [`is_partitioned()`] and [`partition()`].
+    ///
+    /// [`is_partitioned()`]: #method.is_partitioned
+    /// [`partition()`]: #method.partition
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(iter_partition_in_place)]
+    ///
+    /// let mut a = [1, 2, 3, 4, 5, 6, 7];
+    ///
+    /// // Partition in-place between evens and odds
+    /// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0);
+    ///
+    /// assert_eq!(i, 3);
+    /// assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens
+    /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
+    /// ```
+    #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")]
+    fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize
+    where
+        Self: Sized + DoubleEndedIterator<Item = &'a mut T>,
+        P: FnMut(&T) -> bool,
+    {
+        // FIXME: should we worry about the count overflowing? The only way to have more than
+        // `usize::MAX` mutable references is with ZSTs, which aren't useful to partition...
+
+        // These closure "factory" functions exist to avoid genericity in `Self`.
+
+        #[inline]
+        fn is_false<'a, T>(
+            predicate: &'a mut impl FnMut(&T) -> bool,
+            true_count: &'a mut usize,
+        ) -> impl FnMut(&&mut T) -> bool + 'a {
+            move |x| {
+                let p = predicate(&**x);
+                *true_count += p as usize;
+                !p
+            }
+        }
+
+        #[inline]
+        fn is_true<T>(
+            predicate: &mut impl FnMut(&T) -> bool
+        ) -> impl FnMut(&&mut T) -> bool + '_ {
+            move |x| predicate(&**x)
+        }
+
+        // Repeatedly find the first `false` and swap it with the last `true`.
+        let mut true_count = 0;
+        while let Some(head) = self.find(is_false(predicate, &mut true_count)) {
+            if let Some(tail) = self.rfind(is_true(predicate)) {
+                crate::mem::swap(head, tail);
+                true_count += 1;
             } else {
-                right.extend(Some(x))
+                break;
             }
         }
+        true_count
+    }
 
-        (left, right)
+    /// Checks if the elements of this iterator are partitioned according to the given predicate,
+    /// such that all those that return `true` precede all those that return `false`.
+    ///
+    /// See also [`partition()`] and [`partition_in_place()`].
+    ///
+    /// [`partition()`]: #method.partition
+    /// [`partition_in_place()`]: #method.partition_in_place
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(iter_is_partitioned)]
+    ///
+    /// assert!("Iterator".chars().is_partitioned(char::is_uppercase));
+    /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase));
+    /// ```
+    #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "62544")]
+    fn is_partitioned<P>(mut self, mut predicate: P) -> bool
+    where
+        Self: Sized,
+        P: FnMut(Self::Item) -> bool,
+    {
+        // Either all items test `true`, or the first clause stops at `false`
+        // and we check that there are no more `true` items after that.
+        self.all(&mut predicate) || !self.any(predicate)
     }
 
     /// An iterator method that applies a function as long as it returns
@@ -1603,10 +1725,15 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_try_fold", since = "1.27.0")]
-    fn try_for_each<F, R>(&mut self, mut f: F) -> R where
+    fn try_for_each<F, R>(&mut self, f: F) -> R where
         Self: Sized, F: FnMut(Self::Item) -> R, R: Try<Ok=()>
     {
-        self.try_fold((), move |(), x| f(x))
+        #[inline]
+        fn call<T, R>(mut f: impl FnMut(T) -> R) -> impl FnMut((), T) -> R {
+            move |(), x| f(x)
+        }
+
+        self.try_fold((), call(f))
     }
 
     /// An iterator method that applies a function, producing a single, final value.
@@ -1678,10 +1805,15 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn fold<B, F>(mut self, init: B, mut f: F) -> B where
+    fn fold<B, F>(mut self, init: B, f: F) -> B where
         Self: Sized, F: FnMut(B, Self::Item) -> B,
     {
-        self.try_fold(init, move |acc, x| Ok::<B, !>(f(acc, x))).unwrap()
+        #[inline]
+        fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
+            move |acc, x| Ok(f(acc, x))
+        }
+
+        self.try_fold(init, ok(f)).unwrap()
     }
 
     /// Tests if every element of the iterator matches a predicate.
@@ -1723,13 +1855,18 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn all<F>(&mut self, mut f: F) -> bool where
+    fn all<F>(&mut self, f: F) -> bool where
         Self: Sized, F: FnMut(Self::Item) -> bool
     {
-        self.try_for_each(move |x| {
-            if f(x) { LoopState::Continue(()) }
-            else { LoopState::Break(()) }
-        }) == LoopState::Continue(())
+        #[inline]
+        fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut(T) -> LoopState<(), ()> {
+            move |x| {
+                if f(x) { LoopState::Continue(()) }
+                else { LoopState::Break(()) }
+            }
+        }
+
+        self.try_for_each(check(f)) == LoopState::Continue(())
     }
 
     /// Tests if any element of the iterator matches a predicate.
@@ -1771,14 +1908,19 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn any<F>(&mut self, mut f: F) -> bool where
+    fn any<F>(&mut self, f: F) -> bool where
         Self: Sized,
         F: FnMut(Self::Item) -> bool
     {
-        self.try_for_each(move |x| {
-            if f(x) { LoopState::Break(()) }
-            else { LoopState::Continue(()) }
-        }) == LoopState::Break(())
+        #[inline]
+        fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut(T) -> LoopState<(), ()> {
+            move |x| {
+                if f(x) { LoopState::Break(()) }
+                else { LoopState::Continue(()) }
+            }
+        }
+
+        self.try_for_each(check(f)) == LoopState::Break(())
     }
 
     /// Searches for an element of an iterator that satisfies a predicate.
@@ -1825,14 +1967,19 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
+    fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
         Self: Sized,
         P: FnMut(&Self::Item) -> bool,
     {
-        self.try_for_each(move |x| {
-            if predicate(&x) { LoopState::Break(x) }
-            else { LoopState::Continue(()) }
-        }).break_value()
+        #[inline]
+        fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut(T) -> LoopState<(), T> {
+            move |x| {
+                if predicate(&x) { LoopState::Break(x) }
+                else { LoopState::Continue(()) }
+            }
+        }
+
+        self.try_for_each(check(predicate)).break_value()
     }
 
     /// Applies function to the elements of iterator and returns
@@ -1852,16 +1999,19 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iterator_find_map", since = "1.30.0")]
-    fn find_map<B, F>(&mut self, mut f: F) -> Option<B> where
+    fn find_map<B, F>(&mut self, f: F) -> Option<B> where
         Self: Sized,
         F: FnMut(Self::Item) -> Option<B>,
     {
-        self.try_for_each(move |x| {
-            match f(x) {
+        #[inline]
+        fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut(T) -> LoopState<(), B> {
+            move |x| match f(x) {
                 Some(x) => LoopState::Break(x),
                 None => LoopState::Continue(()),
             }
-        }).break_value()
+        }
+
+        self.try_for_each(check(f)).break_value()
     }
 
     /// Searches for an element in an iterator, returning its index.
@@ -1919,17 +2069,23 @@ pub trait Iterator {
     ///
     /// ```
     #[inline]
-    #[rustc_inherit_overflow_checks]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn position<P>(&mut self, mut predicate: P) -> Option<usize> where
+    fn position<P>(&mut self, predicate: P) -> Option<usize> where
         Self: Sized,
         P: FnMut(Self::Item) -> bool,
     {
-        // The addition might panic on overflow
-        self.try_fold(0, move |i, x| {
-            if predicate(x) { LoopState::Break(i) }
-            else { LoopState::Continue(i + 1) }
-        }).break_value()
+        #[inline]
+        fn check<T>(
+            mut predicate: impl FnMut(T) -> bool,
+        ) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
+            // The addition might panic on overflow
+            move |i, x| {
+                if predicate(x) { LoopState::Break(i) }
+                else { LoopState::Continue(Add::add(i, 1)) }
+            }
+        }
+
+        self.try_fold(0, check(predicate)).break_value()
     }
 
     /// Searches for an element in an iterator from the right, returning its
@@ -1972,18 +2128,25 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn rposition<P>(&mut self, mut predicate: P) -> Option<usize> where
+    fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
         P: FnMut(Self::Item) -> bool,
         Self: Sized + ExactSizeIterator + DoubleEndedIterator
     {
         // No need for an overflow check here, because `ExactSizeIterator`
         // implies that the number of elements fits into a `usize`.
+        #[inline]
+        fn check<T>(
+            mut predicate: impl FnMut(T) -> bool,
+        ) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
+            move |i, x| {
+                let i = i - 1;
+                if predicate(x) { LoopState::Break(i) }
+                else { LoopState::Continue(i) }
+            }
+        }
+
         let n = self.len();
-        self.try_rfold(n, move |i, x| {
-            let i = i - 1;
-            if predicate(x) { LoopState::Break(i) }
-            else { LoopState::Continue(i) }
-        }).break_value()
+        self.try_rfold(n, check(predicate)).break_value()
     }
 
     /// Returns the maximum element of an iterator.
@@ -2052,11 +2215,22 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
-    fn max_by_key<B: Ord, F>(self, mut f: F) -> Option<Self::Item>
+    fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
         where Self: Sized, F: FnMut(&Self::Item) -> B,
     {
+        #[inline]
+        fn key<T, B>(mut f: impl FnMut(&T) -> B) -> impl FnMut(T) -> (B, T) {
+            move |x| (f(&x), x)
+        }
+
         // switch to y even if it is only equal, to preserve stability.
-        select_fold1(self.map(|x| (f(&x), x)), |(x_p, _), (y_p, _)| x_p <= y_p).map(|(_, x)| x)
+        #[inline]
+        fn select<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool {
+            x_p <= y_p
+        }
+
+        let (_, x) = select_fold1(self.map(key(f)), select)?;
+        Some(x)
     }
 
     /// Returns the element that gives the maximum value with respect to the
@@ -2075,11 +2249,16 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_max_by", since = "1.15.0")]
-    fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
+    fn max_by<F>(self, compare: F) -> Option<Self::Item>
         where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
     {
         // switch to y even if it is only equal, to preserve stability.
-        select_fold1(self, |x, y| compare(x, y) != Ordering::Greater)
+        #[inline]
+        fn select<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool {
+            move |x, y| compare(x, y) != Ordering::Greater
+        }
+
+        select_fold1(self, select(compare))
     }
 
     /// Returns the element that gives the minimum value from the
@@ -2096,12 +2275,24 @@ pub trait Iterator {
     /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0);
     /// ```
+    #[inline]
     #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
-    fn min_by_key<B: Ord, F>(self, mut f: F) -> Option<Self::Item>
+    fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
         where Self: Sized, F: FnMut(&Self::Item) -> B,
     {
+        #[inline]
+        fn key<T, B>(mut f: impl FnMut(&T) -> B) -> impl FnMut(T) -> (B, T) {
+            move |x| (f(&x), x)
+        }
+
         // only switch to y if it is strictly smaller, to preserve stability.
-        select_fold1(self.map(|x| (f(&x), x)), |(x_p, _), (y_p, _)| x_p > y_p).map(|(_, x)| x)
+        #[inline]
+        fn select<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool {
+            x_p > y_p
+        }
+
+        let (_, x) = select_fold1(self.map(key(f)), select)?;
+        Some(x)
     }
 
     /// Returns the element that gives the minimum value with respect to the
@@ -2120,11 +2311,16 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "iter_min_by", since = "1.15.0")]
-    fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
+    fn min_by<F>(self, compare: F) -> Option<Self::Item>
         where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
     {
         // only switch to y if it is strictly smaller, to preserve stability.
-        select_fold1(self, |x, y| compare(x, y) == Ordering::Greater)
+        #[inline]
+        fn select<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool {
+            move |x, y| compare(x, y) == Ordering::Greater
+        }
+
+        select_fold1(self, select(compare))
     }
 
 
@@ -2185,13 +2381,20 @@ pub trait Iterator {
         FromB: Default + Extend<B>,
         Self: Sized + Iterator<Item=(A, B)>,
     {
+        fn extend<'a, A, B>(
+            ts: &'a mut impl Extend<A>,
+            us: &'a mut impl Extend<B>,
+        ) -> impl FnMut((A, B)) + 'a {
+            move |(t, u)| {
+                ts.extend(Some(t));
+                us.extend(Some(u));
+            }
+        }
+
         let mut ts: FromA = Default::default();
         let mut us: FromB = Default::default();
 
-        self.for_each(|(t, u)| {
-            ts.extend(Some(t));
-            us.extend(Some(u));
-        });
+        self.for_each(extend(&mut ts, &mut us));
 
         (ts, us)
     }
@@ -2518,7 +2721,7 @@ pub trait Iterator {
         Self: Sized,
         Self::Item: PartialOrd,
     {
-        self.is_sorted_by(|a, b| a.partial_cmp(b))
+        self.is_sorted_by(PartialOrd::partial_cmp)
     }
 
     /// Checks if the elements of this iterator are sorted using the given comparator function.
@@ -2540,10 +2743,7 @@ pub trait Iterator {
         };
 
         while let Some(curr) = self.next() {
-            if compare(&last, &curr)
-                .map(|o| o == Ordering::Greater)
-                .unwrap_or(true)
-            {
+            if let Some(Ordering::Greater) | None = compare(&last, &curr) {
                 return false;
             }
             last = curr;
@@ -2571,13 +2771,13 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
-    fn is_sorted_by_key<F, K>(self, mut f: F) -> bool
+    fn is_sorted_by_key<F, K>(self, f: F) -> bool
     where
         Self: Sized,
-        F: FnMut(&Self::Item) -> K,
+        F: FnMut(Self::Item) -> K,
         K: PartialOrd
     {
-        self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b)))
+        self.map(f).is_sorted()
     }
 }
 
@@ -2588,17 +2788,21 @@ pub trait Iterator {
 /// commonalities of {max,min}{,_by}. In particular, this avoids
 /// having to implement optimizations several times.
 #[inline]
-fn select_fold1<I, F>(mut it: I, mut f: F) -> Option<I::Item>
+fn select_fold1<I, F>(mut it: I, f: F) -> Option<I::Item>
     where
         I: Iterator,
         F: FnMut(&I::Item, &I::Item) -> bool,
 {
+    #[inline]
+    fn select<T>(mut f: impl FnMut(&T, &T) -> bool) -> impl FnMut(T, T) -> T {
+        move |sel, x| if f(&sel, &x) { x } else { sel }
+    }
+
     // start with the first element as our selection. This avoids
     // having to use `Option`s inside the loop, translating to a
     // sizeable performance gain (6x in one case).
-    it.next().map(|first| {
-        it.fold(first, |sel, x| if f(&sel, &x) { x } else { sel })
-    })
+    let first = it.next()?;
+    Some(it.fold(first, select(f)))
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 28db55578c3..c168d5c8a2e 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -62,19 +62,20 @@
 #![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)]
 
 #![feature(allow_internal_unstable)]
 #![feature(arbitrary_self_types)]
 #![feature(asm)]
-#![feature(associated_type_defaults)]
+#![feature(bound_cloned)]
 #![feature(cfg_target_has_atomic)]
 #![feature(concat_idents)]
 #![feature(const_fn)]
 #![feature(const_fn_union)]
-#![feature(custom_attribute)]
+#![feature(const_generics)]
+#![feature(custom_inner_attributes)]
+#![feature(decl_macro)]
 #![feature(doc_cfg)]
 #![feature(doc_spotlight)]
 #![feature(extern_types)]
@@ -100,6 +101,7 @@
 #![feature(staged_api)]
 #![feature(std_internals)]
 #![feature(stmt_expr_attributes)]
+#![feature(transparent_unions)]
 #![feature(unboxed_closures)]
 #![feature(unsized_locals)]
 #![feature(untagged_unions)]
@@ -115,18 +117,22 @@
 #![feature(wasm_target_feature)]
 #![feature(avx512_target_feature)]
 #![feature(cmpxchg16b_target_feature)]
+#![feature(rtm_target_feature)]
+#![feature(f16c_target_feature)]
+#![feature(hexagon_target_feature)]
 #![feature(const_slice_len)]
 #![feature(const_str_as_bytes)]
 #![feature(const_str_len)]
 #![feature(const_int_conversion)]
 #![feature(const_transmute)]
-#![feature(reverse_bits)]
 #![feature(non_exhaustive)]
 #![feature(structural_match)]
 #![feature(abi_unadjusted)]
 #![feature(adx_target_feature)]
-#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)]
+#![feature(maybe_uninit_slice)]
 #![feature(external_doc)]
+#![feature(mem_take)]
+#![feature(associated_type_bounds)]
 
 #[prelude_import]
 #[allow(unused)]
@@ -225,12 +231,12 @@ mod tuple;
 mod unit;
 
 // Pull in the `core_arch` crate directly into libcore. The contents of
-// `core_arch` are in a different repository: rust-lang-nursery/stdsimd.
+// `core_arch` are in a different repository: rust-lang/stdarch.
 //
 // `core_arch` depends on libcore, but the contents of this module are
 // set up in such a way that directly pulling it here works such that the
 // crate uses the this crate as its libcore.
-#[path = "../stdsimd/crates/core_arch/src/mod.rs"]
+#[path = "../stdarch/crates/core_arch/src/mod.rs"]
 #[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
 #[unstable(feature = "stdsimd", issue = "48556")]
 mod core_arch;
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index d2ee9b11b36..6c88a766a2f 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -2,21 +2,21 @@
 ///
 /// For details, see `std::macros`.
 #[macro_export]
-#[allow_internal_unstable(core_panic, __rust_unstable_column)]
+#[allow_internal_unstable(core_panic)]
 #[stable(feature = "core", since = "1.6.0")]
 macro_rules! panic {
     () => (
-        panic!("explicit panic")
+        $crate::panic!("explicit panic")
     );
     ($msg:expr) => ({
-        $crate::panicking::panic(&($msg, file!(), line!(), __rust_unstable_column!()))
+        $crate::panicking::panic(&($msg, $crate::file!(), $crate::line!(), $crate::column!()))
     });
     ($msg:expr,) => (
-        panic!($msg)
+        $crate::panic!($msg)
     );
     ($fmt:expr, $($arg:tt)+) => ({
-        $crate::panicking::panic_fmt(format_args!($fmt, $($arg)*),
-                                     &(file!(), line!(), __rust_unstable_column!()))
+        $crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+),
+                                     &($crate::file!(), $crate::line!(), $crate::column!()))
     });
 }
 
@@ -58,7 +58,7 @@ macro_rules! assert_eq {
         }
     });
     ($left:expr, $right:expr,) => ({
-        assert_eq!($left, $right)
+        $crate::assert_eq!($left, $right)
     });
     ($left:expr, $right:expr, $($arg:tt)+) => ({
         match (&($left), &($right)) {
@@ -70,7 +70,7 @@ macro_rules! assert_eq {
                     panic!(r#"assertion failed: `(left == right)`
   left: `{:?}`,
  right: `{:?}`: {}"#, &*left_val, &*right_val,
-                           format_args!($($arg)+))
+                           $crate::format_args!($($arg)+))
                 }
             }
         }
@@ -115,7 +115,7 @@ macro_rules! assert_ne {
         }
     });
     ($left:expr, $right:expr,) => {
-        assert_ne!($left, $right)
+        $crate::assert_ne!($left, $right)
     };
     ($left:expr, $right:expr, $($arg:tt)+) => ({
         match (&($left), &($right)) {
@@ -127,7 +127,7 @@ macro_rules! assert_ne {
                     panic!(r#"assertion failed: `(left != right)`
   left: `{:?}`,
  right: `{:?}`: {}"#, &*left_val, &*right_val,
-                           format_args!($($arg)+))
+                           $crate::format_args!($($arg)+))
                 }
             }
         }
@@ -145,11 +145,11 @@ macro_rules! assert_ne {
 /// # Uses
 ///
 /// Unlike [`assert!`], `debug_assert!` statements are only enabled in non
-/// optimized builds by default. An optimized build will omit all
+/// optimized builds by default. An optimized build will not execute
 /// `debug_assert!` statements unless `-C debug-assertions` is passed to the
 /// compiler. This makes `debug_assert!` useful for checks that are too
 /// expensive to be present in a release build but may be helpful during
-/// development.
+/// development. The result of expanding `debug_assert!` is always type checked.
 ///
 /// An unchecked assertion allows a program in an inconsistent state to keep
 /// running, which might have unexpected consequences but does not introduce
@@ -181,7 +181,7 @@ macro_rules! assert_ne {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! debug_assert {
-    ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert!($($arg)*); })
 }
 
 /// Asserts that two expressions are equal to each other.
@@ -190,11 +190,11 @@ macro_rules! debug_assert {
 /// debug representations.
 ///
 /// Unlike [`assert_eq!`], `debug_assert_eq!` statements are only enabled in non
-/// optimized builds by default. An optimized build will omit all
+/// optimized builds by default. An optimized build will not execute
 /// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
 /// compiler. This makes `debug_assert_eq!` useful for checks that are too
 /// expensive to be present in a release build but may be helpful during
-/// development.
+/// development. The result of expanding `debug_assert_eq!` is always type checked.
 ///
 /// [`assert_eq!`]: ../std/macro.assert_eq.html
 ///
@@ -208,7 +208,7 @@ macro_rules! debug_assert {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! debug_assert_eq {
-    ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_eq!($($arg)*); })
 }
 
 /// Asserts that two expressions are not equal to each other.
@@ -217,11 +217,11 @@ macro_rules! debug_assert_eq {
 /// debug representations.
 ///
 /// Unlike [`assert_ne!`], `debug_assert_ne!` statements are only enabled in non
-/// optimized builds by default. An optimized build will omit all
+/// optimized builds by default. An optimized build will not execute
 /// `debug_assert_ne!` statements unless `-C debug-assertions` is passed to the
 /// compiler. This makes `debug_assert_ne!` useful for checks that are too
 /// expensive to be present in a release build but may be helpful during
-/// development.
+/// development. The result of expanding `debug_assert_ne!` is always type checked.
 ///
 /// [`assert_ne!`]: ../std/macro.assert_ne.html
 ///
@@ -235,7 +235,7 @@ macro_rules! debug_assert_eq {
 #[macro_export]
 #[stable(feature = "assert_ne", since = "1.13.0")]
 macro_rules! debug_assert_ne {
-    ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_ne!($($arg)*); })
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
 }
 
 /// Unwraps a result or propagates its error.
@@ -302,6 +302,7 @@ macro_rules! debug_assert_ne {
 /// ```
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_deprecated(since = "1.39.0", reason = "use the `?` operator instead")]
 #[doc(alias = "?")]
 macro_rules! r#try {
     ($expr:expr) => (match $expr {
@@ -310,7 +311,7 @@ macro_rules! r#try {
             return $crate::result::Result::Err($crate::convert::From::from(err))
         }
     });
-    ($expr:expr,) => (r#try!($expr));
+    ($expr:expr,) => ($crate::r#try!($expr));
 }
 
 /// Writes formatted data into a buffer.
@@ -335,11 +336,14 @@ macro_rules! r#try {
 /// ```
 /// use std::io::Write;
 ///
-/// let mut w = Vec::new();
-/// write!(&mut w, "test").unwrap();
-/// write!(&mut w, "formatted {}", "arguments").unwrap();
+/// fn main() -> std::io::Result<()> {
+///     let mut w = Vec::new();
+///     write!(&mut w, "test")?;
+///     write!(&mut w, "formatted {}", "arguments")?;
 ///
-/// assert_eq!(w, b"testformatted arguments");
+///     assert_eq!(w, b"testformatted arguments");
+///     Ok(())
+/// }
 /// ```
 ///
 /// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
@@ -350,11 +354,15 @@ macro_rules! r#try {
 /// use std::fmt::Write as FmtWrite;
 /// use std::io::Write as IoWrite;
 ///
-/// let mut s = String::new();
-/// let mut v = Vec::new();
-/// write!(&mut s, "{} {}", "abc", 123).unwrap(); // uses fmt::Write::write_fmt
-/// write!(&mut v, "s = {:?}", s).unwrap(); // uses io::Write::write_fmt
-/// assert_eq!(v, b"s = \"abc 123\"");
+/// fn main() -> Result<(), Box<dyn std::error::Error>> {
+///     let mut s = String::new();
+///     let mut v = Vec::new();
+///
+///     write!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt
+///     write!(&mut v, "s = {:?}", s)?; // uses io::Write::write_fmt
+///     assert_eq!(v, b"s = \"abc 123\"");
+///     Ok(())
+/// }
 /// ```
 ///
 /// Note: This macro can be used in `no_std` setups as well.
@@ -378,7 +386,7 @@ macro_rules! r#try {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! write {
-    ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*)))
+    ($dst:expr, $($arg:tt)*) => ($dst.write_fmt($crate::format_args!($($arg)*)))
 }
 
 /// Write formatted data into a buffer, with a newline appended.
@@ -396,14 +404,17 @@ macro_rules! write {
 /// # Examples
 ///
 /// ```
-/// use std::io::Write;
+/// use std::io::{Write, Result};
 ///
-/// let mut w = Vec::new();
-/// writeln!(&mut w).unwrap();
-/// writeln!(&mut w, "test").unwrap();
-/// writeln!(&mut w, "formatted {}", "arguments").unwrap();
+/// fn main() -> Result<()> {
+///     let mut w = Vec::new();
+///     writeln!(&mut w)?;
+///     writeln!(&mut w, "test")?;
+///     writeln!(&mut w, "formatted {}", "arguments")?;
 ///
-/// assert_eq!(&w[..], "\ntest\nformatted arguments\n".as_bytes());
+///     assert_eq!(&w[..], "\ntest\nformatted arguments\n".as_bytes());
+///     Ok(())
+/// }
 /// ```
 ///
 /// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
@@ -414,24 +425,28 @@ macro_rules! write {
 /// use std::fmt::Write as FmtWrite;
 /// use std::io::Write as IoWrite;
 ///
-/// let mut s = String::new();
-/// let mut v = Vec::new();
-/// writeln!(&mut s, "{} {}", "abc", 123).unwrap(); // uses fmt::Write::write_fmt
-/// writeln!(&mut v, "s = {:?}", s).unwrap(); // uses io::Write::write_fmt
-/// assert_eq!(v, b"s = \"abc 123\\n\"\n");
+/// fn main() -> Result<(), Box<dyn std::error::Error>> {
+///     let mut s = String::new();
+///     let mut v = Vec::new();
+///
+///     writeln!(&mut s, "{} {}", "abc", 123)?; // uses fmt::Write::write_fmt
+///     writeln!(&mut v, "s = {:?}", s)?; // uses io::Write::write_fmt
+///     assert_eq!(v, b"s = \"abc 123\\n\"\n");
+///     Ok(())
+/// }
 /// ```
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable(format_args_nl)]
 macro_rules! writeln {
     ($dst:expr) => (
-        write!($dst, "\n")
+        $crate::write!($dst, "\n")
     );
     ($dst:expr,) => (
-        writeln!($dst)
+        $crate::writeln!($dst)
     );
     ($dst:expr, $($arg:tt)*) => (
-        $dst.write_fmt(format_args_nl!($($arg)*))
+        $dst.write_fmt($crate::format_args_nl!($($arg)*))
     );
 }
 
@@ -445,9 +460,10 @@ macro_rules! writeln {
 /// * Iterators that dynamically terminate.
 ///
 /// If the determination that the code is unreachable proves incorrect, the
-/// program immediately terminates with a [`panic!`]. The function [`unreachable_unchecked`],
-/// which belongs to the [`std::hint`] module, informs the compiler to
-/// optimize the code out of the release version entirely.
+/// program immediately terminates with a [`panic!`].
+///
+/// The unsafe counterpart of this macro is the [`unreachable_unchecked`] function, which
+/// will cause undefined behavior if the code is reached.
 ///
 /// [`panic!`]:  ../std/macro.panic.html
 /// [`unreachable_unchecked`]: ../std/hint/fn.unreachable_unchecked.html
@@ -493,13 +509,13 @@ macro_rules! unreachable {
         panic!("internal error: entered unreachable code")
     });
     ($msg:expr) => ({
-        unreachable!("{}", $msg)
+        $crate::unreachable!("{}", $msg)
     });
     ($msg:expr,) => ({
-        unreachable!($msg)
+        $crate::unreachable!($msg)
     });
     ($fmt:expr, $($arg:tt)*) => ({
-        panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
+        panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
     });
 }
 
@@ -557,7 +573,7 @@ macro_rules! unreachable {
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! unimplemented {
     () => (panic!("not yet implemented"));
-    ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
 }
 
 /// Indicates unfinished code.
@@ -616,208 +632,646 @@ macro_rules! unimplemented {
 #[unstable(feature = "todo_macro", issue = "59277")]
 macro_rules! todo {
     () => (panic!("not yet implemented"));
-    ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
 }
 
-/// Creates an array of [`MaybeUninit`].
+/// Definitions of built-in macros.
 ///
-/// This macro constructs an uninitialized array of the type `[MaybeUninit<K>; N]`.
-///
-/// [`MaybeUninit`]: mem/union.MaybeUninit.html
-#[macro_export]
-#[unstable(feature = "maybe_uninit_array", issue = "53491")]
-macro_rules! uninitialized_array {
-    // This `assume_init` is safe because an array of `MaybeUninit` does not
-    // require initialization.
-    // FIXME(#49147): Could be replaced by an array initializer, once those can
-    // be any const expression.
-    ($t:ty; $size:expr) => (unsafe {
-        MaybeUninit::<[MaybeUninit<$t>; $size]>::uninit().assume_init()
-    });
-}
-
-/// Built-in macros to the compiler itself.
-///
-/// These macros do not have any corresponding definition with a `macro_rules!`
-/// macro, but are documented here. Their implementations can be found hardcoded
-/// into libsyntax itself.
-///
-/// For more information, see documentation for `std`'s macros.
-#[cfg(rustdoc)]
-mod builtin {
+/// Most of the macro properties (stability, visibility, etc.) are taken from the source code here,
+/// with exception of expansion functions transforming macro inputs into outputs,
+/// those functions are provided by the compiler.
+pub(crate) mod builtin {
 
     /// Causes compilation to fail with the given error message when encountered.
     ///
-    /// For more information, see the documentation for [`std::compile_error!`].
+    /// This macro should be used when a crate uses a conditional compilation strategy to provide
+    /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
+    /// but emits an error during *compilation* rather than at *runtime*.
+    ///
+    /// # Examples
+    ///
+    /// Two such examples are macros and `#[cfg]` environments.
+    ///
+    /// Emit better compiler error if a macro is passed invalid values. Without the final branch,
+    /// the compiler would still emit an error, but the error's message would not mention the two
+    /// valid values.
     ///
-    /// [`std::compile_error!`]: ../std/macro.compile_error.html
+    /// ```compile_fail
+    /// macro_rules! give_me_foo_or_bar {
+    ///     (foo) => {};
+    ///     (bar) => {};
+    ///     ($x:ident) => {
+    ///         compile_error!("This macro only accepts `foo` or `bar`");
+    ///     }
+    /// }
+    ///
+    /// give_me_foo_or_bar!(neither);
+    /// // ^ will fail at compile time with message "This macro only accepts `foo` or `bar`"
+    /// ```
+    ///
+    /// Emit compiler error if one of a number of features isn't available.
+    ///
+    /// ```compile_fail
+    /// #[cfg(not(any(feature = "foo", feature = "bar")))]
+    /// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.");
+    /// ```
+    ///
+    /// [`panic!`]: ../std/macro.panic.html
     #[stable(feature = "compile_error_macro", since = "1.20.0")]
-    #[rustc_doc_only_macro]
+    #[rustc_builtin_macro]
+    #[macro_export]
     macro_rules! compile_error {
         ($msg:expr) => ({ /* compiler built-in */ });
-        ($msg:expr,) => ({ /* compiler built-in */ });
+        ($msg:expr,) => ({ /* compiler built-in */ })
     }
 
     /// Constructs parameters for the other string-formatting macros.
     ///
-    /// For more information, see the documentation for [`std::format_args!`].
+    /// This macro functions by taking a formatting string literal containing
+    /// `{}` for each additional argument passed. `format_args!` prepares the
+    /// additional parameters to ensure the output can be interpreted as a string
+    /// and canonicalizes the arguments into a single type. Any value that implements
+    /// the [`Display`] trait can be passed to `format_args!`, as can any
+    /// [`Debug`] implementation be passed to a `{:?}` within the formatting string.
+    ///
+    /// This macro produces a value of type [`fmt::Arguments`]. This value can be
+    /// passed to the macros within [`std::fmt`] for performing useful redirection.
+    /// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are
+    /// proxied through this one. `format_args!`, unlike its derived macros, avoids
+    /// heap allocations.
+    ///
+    /// You can use the [`fmt::Arguments`] value that `format_args!` returns
+    /// in `Debug` and `Display` contexts as seen below. The example also shows
+    /// that `Debug` and `Display` format to the same thing: the interpolated
+    /// format string in `format_args!`.
+    ///
+    /// ```rust
+    /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
+    /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
+    /// assert_eq!("1 foo 2", display);
+    /// assert_eq!(display, debug);
+    /// ```
     ///
-    /// [`std::format_args!`]: ../std/macro.format_args.html
+    /// For more information, see the documentation in [`std::fmt`].
+    ///
+    /// [`Display`]: ../std/fmt/trait.Display.html
+    /// [`Debug`]: ../std/fmt/trait.Debug.html
+    /// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html
+    /// [`std::fmt`]: ../std/fmt/index.html
+    /// [`format!`]: ../std/macro.format.html
+    /// [`write!`]: ../std/macro.write.html
+    /// [`println!`]: ../std/macro.println.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fmt;
+    ///
+    /// let s = fmt::format(format_args!("hello {}", "world"));
+    /// assert_eq!(s, format!("hello {}", "world"));
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
+    #[allow_internal_unstable(fmt_internals)]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    #[rustc_macro_transparency = "opaque"]
     macro_rules! format_args {
         ($fmt:expr) => ({ /* compiler built-in */ });
-        ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
+        ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
+    }
+
+    /// Same as `format_args`, but adds a newline in the end.
+    #[unstable(feature = "format_args_nl", issue = "0",
+               reason = "`format_args_nl` is only for internal \
+                         language use and is subject to change")]
+    #[allow_internal_unstable(fmt_internals)]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    #[rustc_macro_transparency = "opaque"]
+    macro_rules! format_args_nl {
+        ($fmt:expr) => ({ /* compiler built-in */ });
+        ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
     }
 
     /// Inspects an environment variable at compile time.
     ///
-    /// For more information, see the documentation for [`std::env!`].
+    /// This macro will expand to the value of the named environment variable at
+    /// compile time, yielding an expression of type `&'static str`.
+    ///
+    /// If the environment variable is not defined, then a compilation error
+    /// will be emitted. To not emit a compile error, use the [`option_env!`]
+    /// macro instead.
     ///
-    /// [`std::env!`]: ../std/macro.env.html
+    /// [`option_env!`]: ../std/macro.option_env.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let path: &'static str = env!("PATH");
+    /// println!("the $PATH variable at the time of compiling was: {}", path);
+    /// ```
+    ///
+    /// You can customize the error message by passing a string as the second
+    /// parameter:
+    ///
+    /// ```compile_fail
+    /// let doc: &'static str = env!("documentation", "what's that?!");
+    /// ```
+    ///
+    /// If the `documentation` environment variable is not defined, you'll get
+    /// the following error:
+    ///
+    /// ```text
+    /// error: what's that?!
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
+    #[rustc_builtin_macro]
+    #[macro_export]
     macro_rules! env {
         ($name:expr) => ({ /* compiler built-in */ });
-        ($name:expr,) => ({ /* compiler built-in */ });
+        ($name:expr,) => ({ /* compiler built-in */ })
     }
 
     /// Optionally inspects an environment variable at compile time.
     ///
-    /// For more information, see the documentation for [`std::option_env!`].
+    /// If the named environment variable is present at compile time, this will
+    /// expand into an expression of type `Option<&'static str>` whose value is
+    /// `Some` of the value of the environment variable. If the environment
+    /// variable is not present, then this will expand to `None`. See
+    /// [`Option<T>`][option] for more information on this type.
+    ///
+    /// A compile time error is never emitted when using this macro regardless
+    /// of whether the environment variable is present or not.
     ///
-    /// [`std::option_env!`]: ../std/macro.option_env.html
+    /// [option]: ../std/option/enum.Option.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let key: Option<&'static str> = option_env!("SECRET_KEY");
+    /// println!("the secret key might be: {:?}", key);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
+    #[rustc_builtin_macro]
+    #[macro_export]
     macro_rules! option_env {
         ($name:expr) => ({ /* compiler built-in */ });
-        ($name:expr,) => ({ /* compiler built-in */ });
+        ($name:expr,) => ({ /* compiler built-in */ })
     }
 
     /// Concatenates identifiers into one identifier.
     ///
-    /// For more information, see the documentation for [`std::concat_idents!`].
+    /// This macro takes any number of comma-separated identifiers, and
+    /// concatenates them all into one, yielding an expression which is a new
+    /// identifier. Note that hygiene makes it such that this macro cannot
+    /// capture local variables. Also, as a general rule, macros are only
+    /// allowed in item, statement or expression position. That means while
+    /// you may use this macro for referring to existing variables, functions or
+    /// modules etc, you cannot define a new one with it.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(concat_idents)]
     ///
-    /// [`std::concat_idents!`]: ../std/macro.concat_idents.html
-    #[unstable(feature = "concat_idents_macro", issue = "29599")]
-    #[rustc_doc_only_macro]
+    /// # fn main() {
+    /// fn foobar() -> u32 { 23 }
+    ///
+    /// let f = concat_idents!(foo, bar);
+    /// println!("{}", f());
+    ///
+    /// // fn concat_idents!(new, fun, name) { } // not usable in this way!
+    /// # }
+    /// ```
+    #[unstable(feature = "concat_idents", issue = "29599",
+               reason = "`concat_idents` is not stable enough for use and is subject to change")]
+    #[rustc_builtin_macro]
+    #[macro_export]
     macro_rules! concat_idents {
         ($($e:ident),+) => ({ /* compiler built-in */ });
-        ($($e:ident,)+) => ({ /* compiler built-in */ });
+        ($($e:ident,)+) => ({ /* compiler built-in */ })
     }
 
     /// Concatenates literals into a static string slice.
     ///
-    /// For more information, see the documentation for [`std::concat!`].
+    /// This macro takes any number of comma-separated literals, yielding an
+    /// expression of type `&'static str` which represents all of the literals
+    /// concatenated left-to-right.
+    ///
+    /// Integer and floating point literals are stringified in order to be
+    /// concatenated.
     ///
-    /// [`std::concat!`]: ../std/macro.concat.html
+    /// # Examples
+    ///
+    /// ```
+    /// let s = concat!("test", 10, 'b', true);
+    /// assert_eq!(s, "test10btrue");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
+    #[rustc_builtin_macro]
+    #[macro_export]
     macro_rules! concat {
         ($($e:expr),*) => ({ /* compiler built-in */ });
-        ($($e:expr,)*) => ({ /* compiler built-in */ });
+        ($($e:expr,)*) => ({ /* compiler built-in */ })
     }
 
     /// Expands to the line number on which it was invoked.
     ///
-    /// For more information, see the documentation for [`std::line!`].
+    /// With [`column!`] and [`file!`], these macros provide debugging information for
+    /// developers about the location within the source.
+    ///
+    /// The expanded expression has type `u32` and is 1-based, so the first line
+    /// in each file evaluates to 1, the second to 2, etc. This is consistent
+    /// with error messages by common compilers or popular editors.
+    /// The returned line is *not necessarily* the line of the `line!` invocation itself,
+    /// but rather the first macro invocation leading up to the invocation
+    /// of the `line!` macro.
+    ///
+    /// [`column!`]: macro.column.html
+    /// [`file!`]: macro.file.html
+    ///
+    /// # Examples
     ///
-    /// [`std::line!`]: ../std/macro.line.html
+    /// ```
+    /// let current_line = line!();
+    /// println!("defined on line: {}", current_line);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! line { () => ({ /* compiler built-in */ }) }
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! line { () => { /* compiler built-in */ } }
 
-    /// Expands to the column number on which it was invoked.
+    /// Expands to the column number at which it was invoked.
+    ///
+    /// With [`line!`] and [`file!`], these macros provide debugging information for
+    /// developers about the location within the source.
+    ///
+    /// The expanded expression has type `u32` and is 1-based, so the first column
+    /// in each line evaluates to 1, the second to 2, etc. This is consistent
+    /// with error messages by common compilers or popular editors.
+    /// The returned column is *not necessarily* the line of the `column!` invocation itself,
+    /// but rather the first macro invocation leading up to the invocation
+    /// of the `column!` macro.
+    ///
+    /// [`line!`]: macro.line.html
+    /// [`file!`]: macro.file.html
     ///
-    /// For more information, see the documentation for [`std::column!`].
+    /// # Examples
     ///
-    /// [`std::column!`]: ../std/macro.column.html
+    /// ```
+    /// let current_col = column!();
+    /// println!("defined on column: {}", current_col);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! column { () => ({ /* compiler built-in */ }) }
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! column { () => { /* compiler built-in */ } }
 
-    /// Expands to the file name from which it was invoked.
+    /// Expands to the file name in which it was invoked.
     ///
-    /// For more information, see the documentation for [`std::file!`].
+    /// With [`line!`] and [`column!`], these macros provide debugging information for
+    /// developers about the location within the source.
     ///
-    /// [`std::file!`]: ../std/macro.file.html
+    ///
+    /// The expanded expression has type `&'static str`, and the returned file
+    /// is not the invocation of the `file!` macro itself, but rather the
+    /// first macro invocation leading up to the invocation of the `file!`
+    /// macro.
+    ///
+    /// [`line!`]: macro.line.html
+    /// [`column!`]: macro.column.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let this_file = file!();
+    /// println!("defined in file: {}", this_file);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! file { () => ({ /* compiler built-in */ }) }
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! file { () => { /* compiler built-in */ } }
 
     /// Stringifies its arguments.
     ///
-    /// For more information, see the documentation for [`std::stringify!`].
+    /// This macro will yield an expression of type `&'static str` which is the
+    /// stringification of all the tokens passed to the macro. No restrictions
+    /// are placed on the syntax of the macro invocation itself.
     ///
-    /// [`std::stringify!`]: ../std/macro.stringify.html
+    /// Note that the expanded results of the input tokens may change in the
+    /// future. You should be careful if you rely on the output.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let one_plus_one = stringify!(1 + 1);
+    /// assert_eq!(one_plus_one, "1 + 1");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! stringify { ($($t:tt)*) => ({ /* compiler built-in */ }) }
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! stringify { ($($t:tt)*) => { /* compiler built-in */ } }
 
     /// Includes a utf8-encoded file as a string.
     ///
-    /// For more information, see the documentation for [`std::include_str!`].
+    /// The file is located relative to the current file. (similarly to how
+    /// modules are found)
+    ///
+    /// This macro will yield an expression of type `&'static str` which is the
+    /// contents of the file.
+    ///
+    /// # Examples
     ///
-    /// [`std::include_str!`]: ../std/macro.include_str.html
+    /// Assume there are two files in the same directory with the following
+    /// contents:
+    ///
+    /// File 'spanish.in':
+    ///
+    /// ```text
+    /// adiós
+    /// ```
+    ///
+    /// File 'main.rs':
+    ///
+    /// ```ignore (cannot-doctest-external-file-dependency)
+    /// fn main() {
+    ///     let my_str = include_str!("spanish.in");
+    ///     assert_eq!(my_str, "adiós\n");
+    ///     print!("{}", my_str);
+    /// }
+    /// ```
+    ///
+    /// Compiling 'main.rs' and running the resulting binary will print "adiós".
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
+    #[rustc_builtin_macro]
+    #[macro_export]
     macro_rules! include_str {
         ($file:expr) => ({ /* compiler built-in */ });
-        ($file:expr,) => ({ /* compiler built-in */ });
+        ($file:expr,) => ({ /* compiler built-in */ })
     }
 
     /// Includes a file as a reference to a byte array.
     ///
-    /// For more information, see the documentation for [`std::include_bytes!`].
+    /// The file is located relative to the current file. (similarly to how
+    /// modules are found)
+    ///
+    /// This macro will yield an expression of type `&'static [u8; N]` which is
+    /// the contents of the file.
+    ///
+    /// # Examples
     ///
-    /// [`std::include_bytes!`]: ../std/macro.include_bytes.html
+    /// Assume there are two files in the same directory with the following
+    /// contents:
+    ///
+    /// File 'spanish.in':
+    ///
+    /// ```text
+    /// adiós
+    /// ```
+    ///
+    /// File 'main.rs':
+    ///
+    /// ```ignore (cannot-doctest-external-file-dependency)
+    /// fn main() {
+    ///     let bytes = include_bytes!("spanish.in");
+    ///     assert_eq!(bytes, b"adi\xc3\xb3s\n");
+    ///     print!("{}", String::from_utf8_lossy(bytes));
+    /// }
+    /// ```
+    ///
+    /// Compiling 'main.rs' and running the resulting binary will print "adiós".
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
+    #[rustc_builtin_macro]
+    #[macro_export]
     macro_rules! include_bytes {
         ($file:expr) => ({ /* compiler built-in */ });
-        ($file:expr,) => ({ /* compiler built-in */ });
+        ($file:expr,) => ({ /* compiler built-in */ })
     }
 
     /// Expands to a string that represents the current module path.
     ///
-    /// For more information, see the documentation for [`std::module_path!`].
+    /// The current module path can be thought of as the hierarchy of modules
+    /// leading back up to the crate root. The first component of the path
+    /// returned is the name of the crate currently being compiled.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// mod test {
+    ///     pub fn foo() {
+    ///         assert!(module_path!().ends_with("test"));
+    ///     }
+    /// }
     ///
-    /// [`std::module_path!`]: ../std/macro.module_path.html
+    /// test::foo();
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! module_path { () => ({ /* compiler built-in */ }) }
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! module_path { () => { /* compiler built-in */ } }
 
-    /// Evaluates boolean combinations of configuration flags, at compile-time.
+    /// Evaluates boolean combinations of configuration flags at compile-time.
     ///
-    /// For more information, see the documentation for [`std::cfg!`].
+    /// In addition to the `#[cfg]` attribute, this macro is provided to allow
+    /// boolean expression evaluation of configuration flags. This frequently
+    /// leads to less duplicated code.
     ///
-    /// [`std::cfg!`]: ../std/macro.cfg.html
+    /// The syntax given to this macro is the same syntax as the [`cfg`]
+    /// attribute.
+    ///
+    /// [`cfg`]: ../reference/conditional-compilation.html#the-cfg-attribute
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let my_directory = if cfg!(windows) {
+    ///     "windows-specific-directory"
+    /// } else {
+    ///     "unix-directory"
+    /// };
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! cfg { ($($cfg:tt)*) => { /* compiler built-in */ } }
 
     /// Parses a file as an expression or an item according to the context.
     ///
-    /// For more information, see the documentation for [`std::include!`].
+    /// The file is located relative to the current file (similarly to how
+    /// modules are found).
+    ///
+    /// Using this macro is often a bad idea, because if the file is
+    /// parsed as an expression, it is going to be placed in the
+    /// surrounding code unhygienically. This could result in variables
+    /// or functions being different from what the file expected if
+    /// there are variables or functions that have the same name in
+    /// the current file.
+    ///
+    /// # Examples
+    ///
+    /// Assume there are two files in the same directory with the following
+    /// contents:
+    ///
+    /// File 'monkeys.in':
     ///
-    /// [`std::include!`]: ../std/macro.include.html
+    /// ```ignore (only-for-syntax-highlight)
+    /// ['🙈', '🙊', '🙉']
+    ///     .iter()
+    ///     .cycle()
+    ///     .take(6)
+    ///     .collect::<String>()
+    /// ```
+    ///
+    /// File 'main.rs':
+    ///
+    /// ```ignore (cannot-doctest-external-file-dependency)
+    /// fn main() {
+    ///     let my_string = include!("monkeys.in");
+    ///     assert_eq!("🙈🙊🙉🙈🙊🙉", my_string);
+    ///     println!("{}", my_string);
+    /// }
+    /// ```
+    ///
+    /// Compiling 'main.rs' and running the resulting binary will print
+    /// "🙈🙊🙉🙈🙊🙉".
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
+    #[rustc_builtin_macro]
+    #[macro_export]
     macro_rules! include {
         ($file:expr) => ({ /* compiler built-in */ });
-        ($file:expr,) => ({ /* compiler built-in */ });
+        ($file:expr,) => ({ /* compiler built-in */ })
     }
 
     /// Asserts that a boolean expression is `true` at runtime.
     ///
-    /// For more information, see the documentation for [`std::assert!`].
+    /// This will invoke the [`panic!`] macro if the provided expression cannot be
+    /// evaluated to `true` at runtime.
+    ///
+    /// # Uses
+    ///
+    /// Assertions are always checked in both debug and release builds, and cannot
+    /// be disabled. See [`debug_assert!`] for assertions that are not enabled in
+    /// release builds by default.
+    ///
+    /// Unsafe code relies on `assert!` to enforce run-time invariants that, if
+    /// violated could lead to unsafety.
+    ///
+    /// Other use-cases of `assert!` include testing and enforcing run-time
+    /// invariants in safe code (whose violation cannot result in unsafety).
+    ///
+    /// # Custom Messages
+    ///
+    /// This macro has a second form, where a custom panic message can
+    /// be provided with or without arguments for formatting. See [`std::fmt`]
+    /// for syntax for this form.
+    ///
+    /// [`panic!`]: macro.panic.html
+    /// [`debug_assert!`]: macro.debug_assert.html
+    /// [`std::fmt`]: ../std/fmt/index.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// // the panic message for these assertions is the stringified value of the
+    /// // expression given.
+    /// assert!(true);
+    ///
+    /// fn some_computation() -> bool { true } // a very simple function
+    ///
+    /// assert!(some_computation());
+    ///
+    /// // assert with a custom message
+    /// let x = true;
+    /// assert!(x, "x wasn't true!");
     ///
-    /// [`std::assert!`]: ../std/macro.assert.html
-    #[rustc_doc_only_macro]
+    /// let a = 3; let b = 27;
+    /// assert!(a + b == 30, "a = {}, b = {}", a, b);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_builtin_macro]
+    #[macro_export]
     macro_rules! assert {
         ($cond:expr) => ({ /* compiler built-in */ });
         ($cond:expr,) => ({ /* compiler built-in */ });
-        ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ });
+        ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ })
     }
+
+    /// Inline assembly.
+    #[unstable(feature = "asm", issue = "29722",
+               reason = "inline assembly is not stable enough for use and is subject to change")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! asm { ("assembly template"
+                        : $("output"(operand),)*
+                        : $("input"(operand),)*
+                        : $("clobbers",)*
+                        : $("options",)*) => { /* compiler built-in */ } }
+
+    /// Module-level inline assembly.
+    #[unstable(feature = "global_asm", issue = "35119",
+               reason = "`global_asm!` is not stable enough for use and is subject to change")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! global_asm { ("assembly") => { /* compiler built-in */ } }
+
+    /// Prints passed tokens into the standard output.
+    #[unstable(feature = "log_syntax", issue = "29598",
+               reason = "`log_syntax!` is not stable enough for use and is subject to change")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! log_syntax { ($($arg:tt)*) => { /* compiler built-in */ } }
+
+    /// Enables or disables tracing functionality used for debugging other macros.
+    #[unstable(feature = "trace_macros", issue = "29598",
+               reason = "`trace_macros` is not stable enough for use and is subject to change")]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! trace_macros {
+        (true) => ({ /* compiler built-in */ });
+        (false) => ({ /* compiler built-in */ })
+    }
+
+    /// Attribute macro applied to a function to turn it into a unit test.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow_internal_unstable(test, rustc_attrs)]
+    #[rustc_builtin_macro]
+    #[rustc_macro_transparency = "semitransparent"]
+    pub macro test($item:item) { /* compiler built-in */ }
+
+    /// Attribute macro applied to a function to turn it into a benchmark test.
+    #[unstable(feature = "test", issue = "50297",
+               reason = "`bench` is a part of custom test frameworks which are unstable")]
+    #[allow_internal_unstable(test, rustc_attrs)]
+    #[rustc_builtin_macro]
+    #[rustc_macro_transparency = "semitransparent"]
+    pub macro bench($item:item) { /* compiler built-in */ }
+
+    /// An implementation detail of the `#[test]` and `#[bench]` macros.
+    #[unstable(feature = "custom_test_frameworks", issue = "50297",
+               reason = "custom test frameworks are an unstable feature")]
+    #[allow_internal_unstable(test, rustc_attrs)]
+    #[rustc_builtin_macro]
+    #[rustc_macro_transparency = "semitransparent"]
+    pub macro test_case($item:item) { /* compiler built-in */ }
+
+    /// Attribute macro applied to a static to register it as a global allocator.
+    #[stable(feature = "global_allocator", since = "1.28.0")]
+    #[allow_internal_unstable(rustc_attrs)]
+    #[rustc_builtin_macro]
+    #[rustc_macro_transparency = "semitransparent"]
+    pub macro global_allocator($item:item) { /* compiler built-in */ }
+
+    /// Unstable implementation detail of the `rustc` compiler, do not use.
+    #[rustc_builtin_macro]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
+    pub macro RustcDecodable($item:item) { /* compiler built-in */ }
+
+    /// Unstable implementation detail of the `rustc` compiler, do not use.
+    #[rustc_builtin_macro]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow_internal_unstable(core_intrinsics)]
+    pub macro RustcEncodable($item:item) { /* compiler built-in */ }
 }
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 74f685a6de2..89af2528c05 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -73,9 +73,9 @@ impl<T: ?Sized> !Send for *mut T { }
 /// impl Foo for Impl { }
 /// impl Bar for Impl { }
 ///
-/// let x: &Foo = &Impl;    // OK
-/// // let y: &Bar = &Impl; // error: the trait `Bar` cannot
-///                         // be made into an object
+/// let x: &dyn Foo = &Impl;    // OK
+/// // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot
+///                             // be made into an object
 /// ```
 ///
 /// [trait object]: ../../book/ch17-02-trait-objects.html
@@ -103,7 +103,7 @@ pub trait Sized {
 /// `Unsize` is implemented for:
 ///
 /// - `[T; N]` is `Unsize<[T]>`
-/// - `T` is `Unsize<Trait>` when `T: Trait`
+/// - `T` is `Unsize<dyn Trait>` when `T: Trait`
 /// - `Foo<..., T, ...>` is `Unsize<Foo<..., U, ...>>` if:
 ///   - `T: Unsize<U>`
 ///   - Foo is a struct
@@ -288,6 +288,13 @@ pub trait Copy : Clone {
     // Empty.
 }
 
+/// Derive macro generating an impl of the trait `Copy`.
+#[rustc_builtin_macro]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
+pub macro Copy($item:item) { /* compiler built-in */ }
+
 /// Types for which it is safe to share references between threads.
 ///
 /// This trait is automatically implemented when the compiler determines
@@ -498,7 +505,7 @@ macro_rules! impls{
 /// #     end: *const T,
 /// #     phantom: PhantomData<&'a T>,
 /// # }
-/// fn borrow_vec<'a, T>(vec: &'a Vec<T>) -> Slice<'a, T> {
+/// fn borrow_vec<T>(vec: &Vec<T>) -> Slice<'_, T> {
 ///     let ptr = vec.as_ptr();
 ///     Slice {
 ///         start: ptr,
@@ -655,6 +662,12 @@ impl<'a, T: ?Sized + 'a> Unpin for &'a T {}
 #[stable(feature = "pin", since = "1.33.0")]
 impl<'a, T: ?Sized + 'a> Unpin for &'a mut T {}
 
+#[stable(feature = "pin_raw", since = "1.38.0")]
+impl<T: ?Sized> Unpin for *const T {}
+
+#[stable(feature = "pin_raw", since = "1.38.0")]
+impl<T: ?Sized> Unpin for *mut T {}
+
 /// Implementations of `Copy` for primitive types.
 ///
 /// Implementations that cannot be described in Rust
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
deleted file mode 100644
index 9fb071d2952..00000000000
--- a/src/libcore/mem.rs
+++ /dev/null
@@ -1,1435 +0,0 @@
-//! Basic functions for dealing with memory.
-//!
-//! This module contains functions for querying the size and alignment of
-//! types, initializing and manipulating memory.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use crate::clone;
-use crate::cmp;
-use crate::fmt;
-use crate::hash;
-use crate::intrinsics;
-use crate::marker::{Copy, PhantomData, Sized};
-use crate::ptr;
-use crate::ops::{Deref, DerefMut};
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(inline)]
-pub use crate::intrinsics::transmute;
-
-/// Takes ownership and "forgets" about the value **without running its destructor**.
-///
-/// Any resources the value manages, such as heap memory or a file handle, will linger
-/// forever in an unreachable state. However, it does not guarantee that pointers
-/// to this memory will remain valid.
-///
-/// * If you want to leak memory, see [`Box::leak`][leak].
-/// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`][into_raw].
-/// * If you want to dispose of a value properly, running its destructor, see
-/// [`mem::drop`][drop].
-///
-/// # Safety
-///
-/// `forget` is not marked as `unsafe`, because Rust's safety guarantees
-/// do not include a guarantee that destructors will always run. For example,
-/// a program can create a reference cycle using [`Rc`][rc], or call
-/// [`process::exit`][exit] to exit without running destructors. Thus, allowing
-/// `mem::forget` from safe code does not fundamentally change Rust's safety
-/// guarantees.
-///
-/// That said, leaking resources such as memory or I/O objects is usually undesirable,
-/// so `forget` is only recommended for specialized use cases like those shown below.
-///
-/// Because forgetting a value is allowed, any `unsafe` code you write must
-/// allow for this possibility. You cannot return a value and expect that the
-/// caller will necessarily run the value's destructor.
-///
-/// [rc]: ../../std/rc/struct.Rc.html
-/// [exit]: ../../std/process/fn.exit.html
-///
-/// # Examples
-///
-/// Leak an I/O object, never closing the file:
-///
-/// ```no_run
-/// use std::mem;
-/// use std::fs::File;
-///
-/// let file = File::open("foo.txt").unwrap();
-/// mem::forget(file);
-/// ```
-///
-/// The practical use cases for `forget` are rather specialized and mainly come
-/// up in unsafe or FFI code.
-///
-/// ## Use case 1
-///
-/// You have created an uninitialized value using [`mem::uninitialized`][uninit].
-/// You must either initialize or `forget` it on every computation path before
-/// Rust drops it automatically, like at the end of a scope or after a panic.
-/// Running the destructor on an uninitialized value would be [undefined behavior][ub].
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// # let some_condition = false;
-/// unsafe {
-///     let mut uninit_vec: Vec<u32> = mem::uninitialized();
-///
-///     if some_condition {
-///         // Initialize the variable.
-///         ptr::write(&mut uninit_vec, Vec::new());
-///     } else {
-///         // Forget the uninitialized value so its destructor doesn't run.
-///         mem::forget(uninit_vec);
-///     }
-/// }
-/// ```
-///
-/// ## Use case 2
-///
-/// You have duplicated the bytes making up a value, without doing a proper
-/// [`Clone`][clone]. You need the value's destructor to run only once,
-/// because a double `free` is undefined behavior.
-///
-/// An example is a possible implementation of [`mem::swap`][swap]:
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// # #[allow(dead_code)]
-/// fn swap<T>(x: &mut T, y: &mut T) {
-///     unsafe {
-///         // Give ourselves some scratch space to work with
-///         let mut t: T = mem::uninitialized();
-///
-///         // Perform the swap, `&mut` pointers never alias
-///         ptr::copy_nonoverlapping(&*x, &mut t, 1);
-///         ptr::copy_nonoverlapping(&*y, x, 1);
-///         ptr::copy_nonoverlapping(&t, y, 1);
-///
-///         // y and t now point to the same thing, but we need to completely
-///         // forget `t` because we do not want to run the destructor for `T`
-///         // on its value, which is still owned somewhere outside this function.
-///         mem::forget(t);
-///     }
-/// }
-/// ```
-///
-/// [drop]: fn.drop.html
-/// [uninit]: fn.uninitialized.html
-/// [clone]: ../clone/trait.Clone.html
-/// [swap]: fn.swap.html
-/// [box]: ../../std/boxed/struct.Box.html
-/// [leak]: ../../std/boxed/struct.Box.html#method.leak
-/// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw
-/// [ub]: ../../reference/behavior-considered-undefined.html
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn forget<T>(t: T) {
-    ManuallyDrop::new(t);
-}
-
-/// Like [`forget`], but also accepts unsized values.
-///
-/// This function is just a shim intended to be removed when the `unsized_locals` feature gets
-/// stabilized.
-///
-/// [`forget`]: fn.forget.html
-#[inline]
-#[unstable(feature = "forget_unsized", issue = "0")]
-pub fn forget_unsized<T: ?Sized>(t: T) {
-    unsafe { intrinsics::forget(t) }
-}
-
-/// Returns the size of a type in bytes.
-///
-/// More specifically, this is the offset in bytes between successive elements
-/// in an array with that item type including alignment padding. Thus, for any
-/// type `T` and length `n`, `[T; n]` has a size of `n * size_of::<T>()`.
-///
-/// In general, the size of a type is not stable across compilations, but
-/// specific types such as primitives are.
-///
-/// The following table gives the size for primitives.
-///
-/// Type | size_of::\<Type>()
-/// ---- | ---------------
-/// () | 0
-/// bool | 1
-/// u8 | 1
-/// u16 | 2
-/// u32 | 4
-/// u64 | 8
-/// u128 | 16
-/// i8 | 1
-/// i16 | 2
-/// i32 | 4
-/// i64 | 8
-/// i128 | 16
-/// f32 | 4
-/// f64 | 8
-/// char | 4
-///
-/// Furthermore, `usize` and `isize` have the same size.
-///
-/// The types `*const T`, `&T`, `Box<T>`, `Option<&T>`, and `Option<Box<T>>` all have
-/// the same size. If `T` is Sized, all of those types have the same size as `usize`.
-///
-/// The mutability of a pointer does not change its size. As such, `&T` and `&mut T`
-/// have the same size. Likewise for `*const T` and `*mut T`.
-///
-/// # Size of `#[repr(C)]` items
-///
-/// The `C` representation for items has a defined layout. With this layout,
-/// the size of items is also stable as long as all fields have a stable size.
-///
-/// ## Size of Structs
-///
-/// For `structs`, the size is determined by the following algorithm.
-///
-/// For each field in the struct ordered by declaration order:
-///
-/// 1. Add the size of the field.
-/// 2. Round up the current size to the nearest multiple of the next field's [alignment].
-///
-/// Finally, round the size of the struct to the nearest multiple of its [alignment].
-/// The alignment of the struct is usually the largest alignment of all its
-/// fields; this can be changed with the use of `repr(align(N))`.
-///
-/// Unlike `C`, zero sized structs are not rounded up to one byte in size.
-///
-/// ## Size of Enums
-///
-/// Enums that carry no data other than the discriminant have the same size as C enums
-/// on the platform they are compiled for.
-///
-/// ## Size of Unions
-///
-/// The size of a union is the size of its largest field.
-///
-/// Unlike `C`, zero sized unions are not rounded up to one byte in size.
-///
-/// # Examples
-///
-/// ```
-/// use std::mem;
-///
-/// // Some primitives
-/// assert_eq!(4, mem::size_of::<i32>());
-/// assert_eq!(8, mem::size_of::<f64>());
-/// assert_eq!(0, mem::size_of::<()>());
-///
-/// // Some arrays
-/// assert_eq!(8, mem::size_of::<[i32; 2]>());
-/// assert_eq!(12, mem::size_of::<[i32; 3]>());
-/// assert_eq!(0, mem::size_of::<[i32; 0]>());
-///
-///
-/// // Pointer size equality
-/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<*const i32>());
-/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Box<i32>>());
-/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>());
-/// assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>());
-/// ```
-///
-/// Using `#[repr(C)]`.
-///
-/// ```
-/// use std::mem;
-///
-/// #[repr(C)]
-/// struct FieldStruct {
-///     first: u8,
-///     second: u16,
-///     third: u8
-/// }
-///
-/// // The size of the first field is 1, so add 1 to the size. Size is 1.
-/// // The alignment of the second field is 2, so add 1 to the size for padding. Size is 2.
-/// // The size of the second field is 2, so add 2 to the size. Size is 4.
-/// // The alignment of the third field is 1, so add 0 to the size for padding. Size is 4.
-/// // The size of the third field is 1, so add 1 to the size. Size is 5.
-/// // Finally, the alignment of the struct is 2 (because the largest alignment amongst its
-/// // fields is 2), so add 1 to the size for padding. Size is 6.
-/// assert_eq!(6, mem::size_of::<FieldStruct>());
-///
-/// #[repr(C)]
-/// struct TupleStruct(u8, u16, u8);
-///
-/// // Tuple structs follow the same rules.
-/// assert_eq!(6, mem::size_of::<TupleStruct>());
-///
-/// // Note that reordering the fields can lower the size. We can remove both padding bytes
-/// // by putting `third` before `second`.
-/// #[repr(C)]
-/// struct FieldStructOptimized {
-///     first: u8,
-///     third: u8,
-///     second: u16
-/// }
-///
-/// assert_eq!(4, mem::size_of::<FieldStructOptimized>());
-///
-/// // Union size is the size of the largest field.
-/// #[repr(C)]
-/// union ExampleUnion {
-///     smaller: u8,
-///     larger: u16
-/// }
-///
-/// assert_eq!(2, mem::size_of::<ExampleUnion>());
-/// ```
-///
-/// [alignment]: ./fn.align_of.html
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_promotable]
-pub const fn size_of<T>() -> usize {
-    intrinsics::size_of::<T>()
-}
-
-/// Returns the size of the pointed-to value in bytes.
-///
-/// This is usually the same as `size_of::<T>()`. However, when `T` *has* no
-/// statically-known size, e.g., a slice [`[T]`][slice] or a [trait object],
-/// then `size_of_val` can be used to get the dynamically-known size.
-///
-/// [slice]: ../../std/primitive.slice.html
-/// [trait object]: ../../book/ch17-02-trait-objects.html
-///
-/// # Examples
-///
-/// ```
-/// use std::mem;
-///
-/// assert_eq!(4, mem::size_of_val(&5i32));
-///
-/// let x: [u8; 13] = [0; 13];
-/// let y: &[u8] = &x;
-/// assert_eq!(13, mem::size_of_val(y));
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn size_of_val<T: ?Sized>(val: &T) -> usize {
-    unsafe { intrinsics::size_of_val(val) }
-}
-
-/// Returns the [ABI]-required minimum alignment of a type.
-///
-/// Every reference to a value of the type `T` must be a multiple of this number.
-///
-/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
-///
-/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
-///
-/// # Examples
-///
-/// ```
-/// # #![allow(deprecated)]
-/// use std::mem;
-///
-/// assert_eq!(4, mem::min_align_of::<i32>());
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_deprecated(reason = "use `align_of` instead", since = "1.2.0")]
-pub fn min_align_of<T>() -> usize {
-    intrinsics::min_align_of::<T>()
-}
-
-/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to.
-///
-/// Every reference to a value of the type `T` must be a multiple of this number.
-///
-/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
-///
-/// # Examples
-///
-/// ```
-/// # #![allow(deprecated)]
-/// use std::mem;
-///
-/// assert_eq!(4, mem::min_align_of_val(&5i32));
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_deprecated(reason = "use `align_of_val` instead", since = "1.2.0")]
-pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
-    unsafe { intrinsics::min_align_of_val(val) }
-}
-
-/// Returns the [ABI]-required minimum alignment of a type.
-///
-/// Every reference to a value of the type `T` must be a multiple of this number.
-///
-/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
-///
-/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
-///
-/// # Examples
-///
-/// ```
-/// use std::mem;
-///
-/// assert_eq!(4, mem::align_of::<i32>());
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_promotable]
-pub const fn align_of<T>() -> usize {
-    intrinsics::min_align_of::<T>()
-}
-
-/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to.
-///
-/// Every reference to a value of the type `T` must be a multiple of this number.
-///
-/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
-///
-/// # Examples
-///
-/// ```
-/// use std::mem;
-///
-/// assert_eq!(4, mem::align_of_val(&5i32));
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
-    unsafe { intrinsics::min_align_of_val(val) }
-}
-
-/// Returns `true` if dropping values of type `T` matters.
-///
-/// This is purely an optimization hint, and may be implemented conservatively:
-/// it may return `true` for types that don't actually need to be dropped.
-/// As such always returning `true` would be a valid implementation of
-/// this function. However if this function actually returns `false`, then you
-/// can be certain dropping `T` has no side effect.
-///
-/// Low level implementations of things like collections, which need to manually
-/// drop their data, should use this function to avoid unnecessarily
-/// trying to drop all their contents when they are destroyed. This might not
-/// make a difference in release builds (where a loop that has no side-effects
-/// is easily detected and eliminated), but is often a big win for debug builds.
-///
-/// Note that `ptr::drop_in_place` already performs this check, so if your workload
-/// can be reduced to some small number of drop_in_place calls, using this is
-/// unnecessary. In particular note that you can drop_in_place a slice, and that
-/// will do a single needs_drop check for all the values.
-///
-/// Types like Vec therefore just `drop_in_place(&mut self[..])` without using
-/// needs_drop explicitly. Types like HashMap, on the other hand, have to drop
-/// values one at a time and should use this API.
-///
-///
-/// # Examples
-///
-/// Here's an example of how a collection might make use of needs_drop:
-///
-/// ```
-/// use std::{mem, ptr};
-///
-/// pub struct MyCollection<T> {
-/// #   data: [T; 1],
-///     /* ... */
-/// }
-/// # impl<T> MyCollection<T> {
-/// #   fn iter_mut(&mut self) -> &mut [T] { &mut self.data }
-/// #   fn free_buffer(&mut self) {}
-/// # }
-///
-/// impl<T> Drop for MyCollection<T> {
-///     fn drop(&mut self) {
-///         unsafe {
-///             // drop the data
-///             if mem::needs_drop::<T>() {
-///                 for x in self.iter_mut() {
-///                     ptr::drop_in_place(x);
-///                 }
-///             }
-///             self.free_buffer();
-///         }
-///     }
-/// }
-/// ```
-#[inline]
-#[stable(feature = "needs_drop", since = "1.21.0")]
-pub const fn needs_drop<T>() -> bool {
-    intrinsics::needs_drop::<T>()
-}
-
-/// Creates a value whose bytes are all zero.
-///
-/// This has the same effect as allocating space with
-/// [`mem::uninitialized`][uninit] and then zeroing it out. It is useful for
-/// FFI sometimes, but should generally be avoided.
-///
-/// There is no guarantee that an all-zero byte-pattern represents a valid value of
-/// some type `T`. If `T` has a destructor and the value is destroyed (due to
-/// a panic or the end of a scope) before being initialized, then the destructor
-/// will run on zeroed data, likely leading to [undefined behavior][ub].
-///
-/// See also the documentation for [`mem::uninitialized`][uninit], which has
-/// many of the same caveats.
-///
-/// [uninit]: fn.uninitialized.html
-/// [ub]: ../../reference/behavior-considered-undefined.html
-///
-/// # Examples
-///
-/// ```
-/// use std::mem;
-///
-/// let x: i32 = unsafe { mem::zeroed() };
-/// assert_eq!(0, x);
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub unsafe fn zeroed<T>() -> T {
-    intrinsics::panic_if_uninhabited::<T>();
-    intrinsics::init()
-}
-
-/// Bypasses Rust's normal memory-initialization checks by pretending to
-/// produce a value of type `T`, while doing nothing at all.
-///
-/// **This is incredibly dangerous and should not be done lightly. Deeply
-/// consider initializing your memory with a default value instead.**
-///
-/// This is useful for FFI functions and initializing arrays sometimes,
-/// but should generally be avoided.
-///
-/// # Undefined behavior
-///
-/// It is [undefined behavior][ub] to read uninitialized memory, even just an
-/// uninitialized boolean. For instance, if you branch on the value of such
-/// a boolean, your program may take one, both, or neither of the branches.
-///
-/// Writing to the uninitialized value is similarly dangerous. Rust believes the
-/// value is initialized, and will therefore try to [`Drop`] the uninitialized
-/// value and its fields if you try to overwrite it in a normal manner. The only way
-/// to safely initialize an uninitialized value is with [`ptr::write`][write],
-/// [`ptr::copy`][copy], or [`ptr::copy_nonoverlapping`][copy_no].
-///
-/// If the value does implement [`Drop`], it must be initialized before
-/// it goes out of scope (and therefore would be dropped). Note that this
-/// includes a `panic` occurring and unwinding the stack suddenly.
-///
-/// If you partially initialize an array, you may need to use
-/// [`ptr::drop_in_place`][drop_in_place] to remove the elements you have fully
-/// initialized followed by [`mem::forget`][mem_forget] to prevent drop running
-/// on the array. If a partially allocated array is dropped this will lead to
-/// undefined behaviour.
-///
-/// # Examples
-///
-/// Here's how to safely initialize an array of [`Vec`]s.
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// // Only declare the array. This safely leaves it
-/// // uninitialized in a way that Rust will track for us.
-/// // However we can't initialize it element-by-element
-/// // safely, and we can't use the `[value; 1000]`
-/// // constructor because it only works with `Copy` data.
-/// let mut data: [Vec<u32>; 1000];
-///
-/// unsafe {
-///     // So we need to do this to initialize it.
-///     data = mem::uninitialized();
-///
-///     // DANGER ZONE: if anything panics or otherwise
-///     // incorrectly reads the array here, we will have
-///     // Undefined Behavior.
-///
-///     // It's ok to mutably iterate the data, since this
-///     // doesn't involve reading it at all.
-///     // (ptr and len are statically known for arrays)
-///     for elem in &mut data[..] {
-///         // *elem = Vec::new() would try to drop the
-///         // uninitialized memory at `elem` -- bad!
-///         //
-///         // Vec::new doesn't allocate or do really
-///         // anything. It's only safe to call here
-///         // because we know it won't panic.
-///         ptr::write(elem, Vec::new());
-///     }
-///
-///     // SAFE ZONE: everything is initialized.
-/// }
-///
-/// println!("{:?}", &data[0]);
-/// ```
-///
-/// This example emphasizes exactly how delicate and dangerous using `mem::uninitialized`
-/// can be. Note that the [`vec!`] macro *does* let you initialize every element with a
-/// value that is only [`Clone`], so the following is semantically equivalent and
-/// vastly less dangerous, as long as you can live with an extra heap
-/// allocation:
-///
-/// ```
-/// let data: Vec<Vec<u32>> = vec![Vec::new(); 1000];
-/// println!("{:?}", &data[0]);
-/// ```
-///
-/// This example shows how to handle partially initialized arrays, which could
-/// be found in low-level datastructures.
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// // Count the number of elements we have assigned.
-/// let mut data_len: usize = 0;
-/// let mut data: [String; 1000];
-///
-/// unsafe {
-///     data = mem::uninitialized();
-///
-///     for elem in &mut data[0..500] {
-///         ptr::write(elem, String::from("hello"));
-///         data_len += 1;
-///     }
-///
-///     // For each item in the array, drop if we allocated it.
-///     for i in &mut data[0..data_len] {
-///         ptr::drop_in_place(i);
-///     }
-/// }
-/// // Forget the data. If this is allowed to drop, you may see a crash such as:
-/// // 'mem_uninit_test(2457,0x7fffb55dd380) malloc: *** error for object
-/// // 0x7ff3b8402920: pointer being freed was not allocated'
-/// mem::forget(data);
-/// ```
-///
-/// [`Vec`]: ../../std/vec/struct.Vec.html
-/// [`vec!`]: ../../std/macro.vec.html
-/// [`Clone`]: ../../std/clone/trait.Clone.html
-/// [ub]: ../../reference/behavior-considered-undefined.html
-/// [write]: ../ptr/fn.write.html
-/// [drop_in_place]: ../ptr/fn.drop_in_place.html
-/// [mem_zeroed]: fn.zeroed.html
-/// [mem_forget]: fn.forget.html
-/// [copy]: ../intrinsics/fn.copy.html
-/// [copy_no]: ../intrinsics/fn.copy_nonoverlapping.html
-/// [`Drop`]: ../ops/trait.Drop.html
-#[inline]
-#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninit` instead")]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub unsafe fn uninitialized<T>() -> T {
-    intrinsics::panic_if_uninhabited::<T>();
-    intrinsics::uninit()
-}
-
-/// Swaps the values at two mutable locations, without deinitializing either one.
-///
-/// # Examples
-///
-/// ```
-/// use std::mem;
-///
-/// let mut x = 5;
-/// let mut y = 42;
-///
-/// mem::swap(&mut x, &mut y);
-///
-/// assert_eq!(42, x);
-/// assert_eq!(5, y);
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn swap<T>(x: &mut T, y: &mut T) {
-    unsafe {
-        ptr::swap_nonoverlapping_one(x, y);
-    }
-}
-
-/// Moves `src` into the referenced `dest`, returning the previous `dest` value.
-///
-/// Neither value is dropped.
-///
-/// # Examples
-///
-/// A simple example:
-///
-/// ```
-/// use std::mem;
-///
-/// let mut v: Vec<i32> = vec![1, 2];
-///
-/// let old_v = mem::replace(&mut v, vec![3, 4, 5]);
-/// assert_eq!(vec![1, 2], old_v);
-/// assert_eq!(vec![3, 4, 5], v);
-/// ```
-///
-/// `replace` allows consumption of a struct field by replacing it with another value.
-/// Without `replace` you can run into issues like these:
-///
-/// ```compile_fail,E0507
-/// struct Buffer<T> { buf: Vec<T> }
-///
-/// impl<T> Buffer<T> {
-///     fn get_and_reset(&mut self) -> Vec<T> {
-///         // error: cannot move out of dereference of `&mut`-pointer
-///         let buf = self.buf;
-///         self.buf = Vec::new();
-///         buf
-///     }
-/// }
-/// ```
-///
-/// Note that `T` does not necessarily implement [`Clone`], so it can't even clone and reset
-/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from
-/// `self`, allowing it to be returned:
-///
-/// ```
-/// # #![allow(dead_code)]
-/// use std::mem;
-///
-/// # struct Buffer<T> { buf: Vec<T> }
-/// impl<T> Buffer<T> {
-///     fn get_and_reset(&mut self) -> Vec<T> {
-///         mem::replace(&mut self.buf, Vec::new())
-///     }
-/// }
-/// ```
-///
-/// [`Clone`]: ../../std/clone/trait.Clone.html
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn replace<T>(dest: &mut T, mut src: T) -> T {
-    swap(dest, &mut src);
-    src
-}
-
-/// Disposes of a value.
-///
-/// This does call the argument's implementation of [`Drop`][drop].
-///
-/// This effectively does nothing for types which implement `Copy`, e.g.
-/// integers. Such values are copied and _then_ moved into the function, so the
-/// value persists after this function call.
-///
-/// This function is not magic; it is literally defined as
-///
-/// ```
-/// pub fn drop<T>(_x: T) { }
-/// ```
-///
-/// Because `_x` is moved into the function, it is automatically dropped before
-/// the function returns.
-///
-/// [drop]: ../ops/trait.Drop.html
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// let v = vec![1, 2, 3];
-///
-/// drop(v); // explicitly drop the vector
-/// ```
-///
-/// Since [`RefCell`] enforces the borrow rules at runtime, `drop` can
-/// release a [`RefCell`] borrow:
-///
-/// ```
-/// use std::cell::RefCell;
-///
-/// let x = RefCell::new(1);
-///
-/// let mut mutable_borrow = x.borrow_mut();
-/// *mutable_borrow = 1;
-///
-/// drop(mutable_borrow); // relinquish the mutable borrow on this slot
-///
-/// let borrow = x.borrow();
-/// println!("{}", *borrow);
-/// ```
-///
-/// Integers and other types implementing [`Copy`] are unaffected by `drop`.
-///
-/// ```
-/// #[derive(Copy, Clone)]
-/// struct Foo(u8);
-///
-/// let x = 1;
-/// let y = Foo(2);
-/// drop(x); // a copy of `x` is moved and dropped
-/// drop(y); // a copy of `y` is moved and dropped
-///
-/// println!("x: {}, y: {}", x, y.0); // still available
-/// ```
-///
-/// [`RefCell`]: ../../std/cell/struct.RefCell.html
-/// [`Copy`]: ../../std/marker/trait.Copy.html
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn drop<T>(_x: T) { }
-
-/// Interprets `src` as having type `&U`, and then reads `src` without moving
-/// the contained value.
-///
-/// This function will unsafely assume the pointer `src` is valid for
-/// [`size_of::<U>`][size_of] bytes by transmuting `&T` to `&U` and then reading
-/// the `&U`. It will also unsafely create a copy of the contained value instead of
-/// moving out of `src`.
-///
-/// It is not a compile-time error if `T` and `U` have different sizes, but it
-/// is highly encouraged to only invoke this function where `T` and `U` have the
-/// same size. This function triggers [undefined behavior][ub] if `U` is larger than
-/// `T`.
-///
-/// [ub]: ../../reference/behavior-considered-undefined.html
-/// [size_of]: fn.size_of.html
-///
-/// # Examples
-///
-/// ```
-/// use std::mem;
-///
-/// #[repr(packed)]
-/// struct Foo {
-///     bar: u8,
-/// }
-///
-/// let foo_slice = [10u8];
-///
-/// unsafe {
-///     // Copy the data from 'foo_slice' and treat it as a 'Foo'
-///     let mut foo_struct: Foo = mem::transmute_copy(&foo_slice);
-///     assert_eq!(foo_struct.bar, 10);
-///
-///     // Modify the copied data
-///     foo_struct.bar = 20;
-///     assert_eq!(foo_struct.bar, 20);
-/// }
-///
-/// // The contents of 'foo_slice' should not have changed
-/// assert_eq!(foo_slice, [10]);
-/// ```
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
-    ptr::read_unaligned(src as *const T as *const U)
-}
-
-/// Opaque type representing the discriminant of an enum.
-///
-/// See the [`discriminant`] function in this module for more information.
-///
-/// [`discriminant`]: fn.discriminant.html
-#[stable(feature = "discriminant_value", since = "1.21.0")]
-pub struct Discriminant<T>(u64, PhantomData<fn() -> T>);
-
-// N.B. These trait implementations cannot be derived because we don't want any bounds on T.
-
-#[stable(feature = "discriminant_value", since = "1.21.0")]
-impl<T> Copy for Discriminant<T> {}
-
-#[stable(feature = "discriminant_value", since = "1.21.0")]
-impl<T> clone::Clone for Discriminant<T> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-#[stable(feature = "discriminant_value", since = "1.21.0")]
-impl<T> cmp::PartialEq for Discriminant<T> {
-    fn eq(&self, rhs: &Self) -> bool {
-        self.0 == rhs.0
-    }
-}
-
-#[stable(feature = "discriminant_value", since = "1.21.0")]
-impl<T> cmp::Eq for Discriminant<T> {}
-
-#[stable(feature = "discriminant_value", since = "1.21.0")]
-impl<T> hash::Hash for Discriminant<T> {
-    fn hash<H: hash::Hasher>(&self, state: &mut H) {
-        self.0.hash(state);
-    }
-}
-
-#[stable(feature = "discriminant_value", since = "1.21.0")]
-impl<T> fmt::Debug for Discriminant<T> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt.debug_tuple("Discriminant")
-           .field(&self.0)
-           .finish()
-    }
-}
-
-/// Returns a value uniquely identifying the enum variant in `v`.
-///
-/// If `T` is not an enum, calling this function will not result in undefined behavior, but the
-/// return value is unspecified.
-///
-/// # Stability
-///
-/// The discriminant of an enum variant may change if the enum definition changes. A discriminant
-/// of some variant will not change between compilations with the same compiler.
-///
-/// # Examples
-///
-/// This can be used to compare enums that carry data, while disregarding
-/// the actual data:
-///
-/// ```
-/// use std::mem;
-///
-/// enum Foo { A(&'static str), B(i32), C(i32) }
-///
-/// assert!(mem::discriminant(&Foo::A("bar")) == mem::discriminant(&Foo::A("baz")));
-/// assert!(mem::discriminant(&Foo::B(1))     == mem::discriminant(&Foo::B(2)));
-/// assert!(mem::discriminant(&Foo::B(3))     != mem::discriminant(&Foo::C(3)));
-/// ```
-#[stable(feature = "discriminant_value", since = "1.21.0")]
-pub fn discriminant<T>(v: &T) -> Discriminant<T> {
-    unsafe {
-        Discriminant(intrinsics::discriminant_value(v), PhantomData)
-    }
-}
-
-// FIXME: Reference `MaybeUninit` from these docs, once that is stable.
-/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
-///
-/// This wrapper is 0-cost.
-///
-/// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
-/// As a consequence, it has *no effect* on the assumptions that the compiler makes
-/// about all values being initialized at their type.  In particular, initializing
-/// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior.
-///
-/// # Examples
-///
-/// This wrapper helps with explicitly documenting the drop order dependencies between fields of
-/// the type:
-///
-/// ```rust
-/// use std::mem::ManuallyDrop;
-/// struct Peach;
-/// struct Banana;
-/// struct Melon;
-/// struct FruitBox {
-///     // Immediately clear there’s something non-trivial going on with these fields.
-///     peach: ManuallyDrop<Peach>,
-///     melon: Melon, // Field that’s independent of the other two.
-///     banana: ManuallyDrop<Banana>,
-/// }
-///
-/// impl Drop for FruitBox {
-///     fn drop(&mut self) {
-///         unsafe {
-///             // Explicit ordering in which field destructors are run specified in the intuitive
-///             // location – the destructor of the structure containing the fields.
-///             // Moreover, one can now reorder fields within the struct however much they want.
-///             ManuallyDrop::drop(&mut self.peach);
-///             ManuallyDrop::drop(&mut self.banana);
-///         }
-///         // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
-///         // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
-///     }
-/// }
-/// ```
-///
-/// [`mem::zeroed`]: fn.zeroed.html
-#[stable(feature = "manually_drop", since = "1.20.0")]
-#[lang = "manually_drop"]
-#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(transparent)]
-pub struct ManuallyDrop<T: ?Sized> {
-    value: T,
-}
-
-impl<T> ManuallyDrop<T> {
-    /// Wrap a value to be manually dropped.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use std::mem::ManuallyDrop;
-    /// ManuallyDrop::new(Box::new(()));
-    /// ```
-    #[stable(feature = "manually_drop", since = "1.20.0")]
-    #[inline(always)]
-    pub const fn new(value: T) -> ManuallyDrop<T> {
-        ManuallyDrop { value }
-    }
-
-    /// Extracts the value from the `ManuallyDrop` container.
-    ///
-    /// This allows the value to be dropped again.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use std::mem::ManuallyDrop;
-    /// let x = ManuallyDrop::new(Box::new(()));
-    /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
-    /// ```
-    #[stable(feature = "manually_drop", since = "1.20.0")]
-    #[inline(always)]
-    pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
-        slot.value
-    }
-
-    /// Takes the contained value out.
-    ///
-    /// This method is primarily intended for moving out values in drop.
-    /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
-    /// you can use this method to take the value and use it however desired.
-    /// `Drop` will be invoked on the returned value following normal end-of-scope rules.
-    ///
-    /// If you have ownership of the container, you can use [`ManuallyDrop::into_inner`] instead.
-    ///
-    /// # Safety
-    ///
-    /// This function semantically moves out the contained value without preventing further usage.
-    /// It is up to the user of this method to ensure that this container is not used again.
-    ///
-    /// [`ManuallyDrop::drop`]: #method.drop
-    /// [`ManuallyDrop::into_inner`]: #method.into_inner
-    #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
-    #[unstable(feature = "manually_drop_take", issue = "55422")]
-    #[inline]
-    pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
-        ManuallyDrop::into_inner(ptr::read(slot))
-    }
-}
-
-impl<T: ?Sized> ManuallyDrop<T> {
-    /// Manually drops the contained value.
-    ///
-    /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead.
-    ///
-    /// # Safety
-    ///
-    /// This function runs the destructor of the contained value and thus the wrapped value
-    /// now represents uninitialized data. It is up to the user of this method to ensure the
-    /// uninitialized data is not actually used.
-    ///
-    /// [`ManuallyDrop::into_inner`]: #method.into_inner
-    #[stable(feature = "manually_drop", since = "1.20.0")]
-    #[inline]
-    pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
-        ptr::drop_in_place(&mut slot.value)
-    }
-}
-
-#[stable(feature = "manually_drop", since = "1.20.0")]
-impl<T: ?Sized> Deref for ManuallyDrop<T> {
-    type Target = T;
-    #[inline(always)]
-    fn deref(&self) -> &T {
-        &self.value
-    }
-}
-
-#[stable(feature = "manually_drop", since = "1.20.0")]
-impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
-    #[inline(always)]
-    fn deref_mut(&mut self) -> &mut T {
-        &mut self.value
-    }
-}
-
-/// A wrapper to construct uninitialized instances of `T`.
-///
-/// The compiler, in general, assumes that variables are properly initialized
-/// at their respective type. For example, a variable of reference type must
-/// be aligned and non-NULL. This is an invariant that must *always* be upheld,
-/// even in unsafe code. As a consequence, zero-initializing a variable of reference
-/// type causes instantaneous undefined behavior, no matter whether that reference
-/// ever gets used to access memory:
-///
-/// ```rust,no_run
-/// #![feature(maybe_uninit)]
-/// use std::mem::{self, MaybeUninit};
-///
-/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
-/// // The equivalent code with `MaybeUninit<&i32>`:
-/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior!
-/// ```
-///
-/// This is exploited by the compiler for various optimizations, such as eliding
-/// run-time checks and optimizing `enum` layout.
-///
-/// Similarly, entirely uninitialized memory may have any content, while a `bool` must
-/// always be `true` or `false`. Hence, creating an uninitialized `bool` is undefined behavior:
-///
-/// ```rust,no_run
-/// #![feature(maybe_uninit)]
-/// use std::mem::{self, MaybeUninit};
-///
-/// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior!
-/// // The equivalent code with `MaybeUninit<bool>`:
-/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior!
-/// ```
-///
-/// Moreover, uninitialized memory is special in that the compiler knows that
-/// it does not have a fixed value. This makes it undefined behavior to have
-/// uninitialized data in a variable even if that variable has an integer type,
-/// which otherwise can hold any bit pattern:
-///
-/// ```rust,no_run
-/// #![feature(maybe_uninit)]
-/// use std::mem::{self, MaybeUninit};
-///
-/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior!
-/// // The equivalent code with `MaybeUninit<i32>`:
-/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior!
-/// ```
-/// (Notice that the rules around uninitialized integers are not finalized yet, but
-/// until they are, it is advisable to avoid them.)
-///
-/// `MaybeUninit<T>` serves to enable unsafe code to deal with uninitialized data.
-/// It is a signal to the compiler indicating that the data here might *not*
-/// be initialized:
-///
-/// ```rust
-/// #![feature(maybe_uninit)]
-/// use std::mem::MaybeUninit;
-///
-/// // Create an explicitly uninitialized reference. The compiler knows that data inside
-/// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
-/// let mut x = MaybeUninit::<&i32>::uninit();
-/// // Set it to a valid value.
-/// x.write(&0);
-/// // Extract the initialized data -- this is only allowed *after* properly
-/// // initializing `x`!
-/// let x = unsafe { x.assume_init() };
-/// ```
-///
-/// The compiler then knows to not make any incorrect assumptions or optimizations on this code.
-//
-// FIXME before stabilizing, explain how to initialize a struct field-by-field.
-#[allow(missing_debug_implementations)]
-#[unstable(feature = "maybe_uninit", issue = "53491")]
-#[derive(Copy)]
-// NOTE: after stabilizing `MaybeUninit`, proceed to deprecate `mem::uninitialized`.
-pub union MaybeUninit<T> {
-    uninit: (),
-    value: ManuallyDrop<T>,
-}
-
-#[unstable(feature = "maybe_uninit", issue = "53491")]
-impl<T: Copy> Clone for MaybeUninit<T> {
-    #[inline(always)]
-    fn clone(&self) -> Self {
-        // Not calling `T::clone()`, we cannot know if we are initialized enough for that.
-        *self
-    }
-}
-
-impl<T> MaybeUninit<T> {
-    /// Creates a new `MaybeUninit<T>` initialized with the given value.
-    ///
-    /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
-    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
-    #[unstable(feature = "maybe_uninit", issue = "53491")]
-    #[inline(always)]
-    pub const fn new(val: T) -> MaybeUninit<T> {
-        MaybeUninit { value: ManuallyDrop::new(val) }
-    }
-
-    /// Creates a new `MaybeUninit<T>` in an uninitialized state.
-    ///
-    /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
-    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
-    #[unstable(feature = "maybe_uninit", issue = "53491")]
-    #[inline(always)]
-    pub const fn uninit() -> MaybeUninit<T> {
-        MaybeUninit { uninit: () }
-    }
-
-    /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
-    /// filled with `0` bytes. It depends on `T` whether that already makes for
-    /// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
-    /// but `MaybeUninit<&'static i32>::zeroed()` is not because references must not
-    /// be null.
-    ///
-    /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
-    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
-    ///
-    /// # Example
-    ///
-    /// Correct usage of this function: initializing a struct with zero, where all
-    /// fields of the struct can hold the bit-pattern 0 as a valid value.
-    ///
-    /// ```rust
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let x = MaybeUninit::<(u8, bool)>::zeroed();
-    /// let x = unsafe { x.assume_init() };
-    /// assert_eq!(x, (0, false));
-    /// ```
-    ///
-    /// *Incorrect* usage of this function: initializing a struct with zero, where some fields
-    /// cannot hold 0 as a valid value.
-    ///
-    /// ```rust,no_run
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// enum NotZero { One = 1, Two = 2 };
-    ///
-    /// let x = MaybeUninit::<(u8, NotZero)>::zeroed();
-    /// let x = unsafe { x.assume_init() };
-    /// // Inside a pair, we create a `NotZero` that does not have a valid discriminant.
-    /// // This is undefined behavior.
-    /// ```
-    #[unstable(feature = "maybe_uninit", issue = "53491")]
-    #[inline]
-    pub fn zeroed() -> MaybeUninit<T> {
-        let mut u = MaybeUninit::<T>::uninit();
-        unsafe {
-            u.as_mut_ptr().write_bytes(0u8, 1);
-        }
-        u
-    }
-
-    /// Sets the value of the `MaybeUninit<T>`. This overwrites any previous value
-    /// without dropping it, so be careful not to use this twice unless you want to
-    /// skip running the destructor. For your convenience, this also returns a mutable
-    /// reference to the (now safely initialized) contents of `self`.
-    #[unstable(feature = "maybe_uninit", issue = "53491")]
-    #[inline(always)]
-    pub fn write(&mut self, val: T) -> &mut T {
-        unsafe {
-            self.value = ManuallyDrop::new(val);
-            self.get_mut()
-        }
-    }
-
-    /// Gets a pointer to the contained value. Reading from this pointer or turning it
-    /// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
-    ///
-    /// # Examples
-    ///
-    /// Correct usage of this method:
-    ///
-    /// ```rust
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
-    /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); }
-    /// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
-    /// let x_vec = unsafe { &*x.as_ptr() };
-    /// assert_eq!(x_vec.len(), 3);
-    /// ```
-    ///
-    /// *Incorrect* usage of this method:
-    ///
-    /// ```rust,no_run
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let x = MaybeUninit::<Vec<u32>>::uninit();
-    /// let x_vec = unsafe { &*x.as_ptr() };
-    /// // We have created a reference to an uninitialized vector! This is undefined behavior.
-    /// ```
-    ///
-    /// (Notice that the rules around references to uninitialized data are not finalized yet, but
-    /// until they are, it is advisable to avoid them.)
-    #[unstable(feature = "maybe_uninit", issue = "53491")]
-    #[inline(always)]
-    pub fn as_ptr(&self) -> *const T {
-        unsafe { &*self.value as *const T }
-    }
-
-    /// Gets a mutable pointer to the contained value. Reading from this pointer or turning it
-    /// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
-    ///
-    /// # Examples
-    ///
-    /// Correct usage of this method:
-    ///
-    /// ```rust
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
-    /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); }
-    /// // Create a reference into the `MaybeUninit<Vec<u32>>`.
-    /// // This is okay because we initialized it.
-    /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
-    /// x_vec.push(3);
-    /// assert_eq!(x_vec.len(), 4);
-    /// ```
-    ///
-    /// *Incorrect* usage of this method:
-    ///
-    /// ```rust,no_run
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
-    /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
-    /// // We have created a reference to an uninitialized vector! This is undefined behavior.
-    /// ```
-    ///
-    /// (Notice that the rules around references to uninitialized data are not finalized yet, but
-    /// until they are, it is advisable to avoid them.)
-    #[unstable(feature = "maybe_uninit", issue = "53491")]
-    #[inline(always)]
-    pub fn as_mut_ptr(&mut self) -> *mut T {
-        unsafe { &mut *self.value as *mut T }
-    }
-
-    /// Extracts the value from the `MaybeUninit<T>` container. This is a great way
-    /// to ensure that the data will get dropped, because the resulting `T` is
-    /// subject to the usual drop handling.
-    ///
-    /// # Safety
-    ///
-    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
-    /// state. Calling this when the content is not yet fully initialized causes undefined
-    /// behavior.
-    ///
-    /// # Examples
-    ///
-    /// Correct usage of this method:
-    ///
-    /// ```rust
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut x = MaybeUninit::<bool>::uninit();
-    /// unsafe { x.as_mut_ptr().write(true); }
-    /// let x_init = unsafe { x.assume_init() };
-    /// assert_eq!(x_init, true);
-    /// ```
-    ///
-    /// *Incorrect* usage of this method:
-    ///
-    /// ```rust,no_run
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let x = MaybeUninit::<Vec<u32>>::uninit();
-    /// let x_init = unsafe { x.assume_init() };
-    /// // `x` had not been initialized yet, so this last line caused undefined behavior.
-    /// ```
-    #[unstable(feature = "maybe_uninit", issue = "53491")]
-    #[inline(always)]
-    pub unsafe fn assume_init(self) -> T {
-        intrinsics::panic_if_uninhabited::<T>();
-        ManuallyDrop::into_inner(self.value)
-    }
-
-    /// Reads the value from the `MaybeUninit<T>` container. The resulting `T` is subject
-    /// to the usual drop handling.
-    ///
-    /// Whenever possible, it is preferrable to use [`assume_init`] instead, which
-    /// prevents duplicating the content of the `MaybeUninit<T>`.
-    ///
-    /// # Safety
-    ///
-    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
-    /// state. Calling this when the content is not yet fully initialized causes undefined
-    /// behavior.
-    ///
-    /// Moreover, this leaves a copy of the same data behind in the `MaybeUninit<T>`. When using
-    /// multiple copies of the data (by calling `read` multiple times, or first
-    /// calling `read` and then [`assume_init`]), it is your responsibility
-    /// to ensure that that data may indeed be duplicated.
-    ///
-    /// [`assume_init`]: #method.assume_init
-    ///
-    /// # Examples
-    ///
-    /// Correct usage of this method:
-    ///
-    /// ```rust
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut x = MaybeUninit::<u32>::uninit();
-    /// x.write(13);
-    /// let x1 = unsafe { x.read() };
-    /// // `u32` is `Copy`, so we may read multiple times.
-    /// let x2 = unsafe { x.read() };
-    /// assert_eq!(x1, x2);
-    ///
-    /// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
-    /// x.write(None);
-    /// let x1 = unsafe { x.read() };
-    /// // Duplicating a `None` value is okay, so we may read multiple times.
-    /// let x2 = unsafe { x.read() };
-    /// assert_eq!(x1, x2);
-    /// ```
-    ///
-    /// *Incorrect* usage of this method:
-    ///
-    /// ```rust,no_run
-    /// #![feature(maybe_uninit)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
-    /// x.write(Some(vec![0,1,2]));
-    /// let x1 = unsafe { x.read() };
-    /// let x2 = unsafe { x.read() };
-    /// // We now created two copies of the same vector, leading to a double-free when
-    /// // they both get dropped!
-    /// ```
-    #[unstable(feature = "maybe_uninit", issue = "53491")]
-    #[inline(always)]
-    pub unsafe fn read(&self) -> T {
-        intrinsics::panic_if_uninhabited::<T>();
-        self.as_ptr().read()
-    }
-
-    /// Gets a reference to the contained value.
-    ///
-    /// # Safety
-    ///
-    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
-    /// state. Calling this when the content is not yet fully initialized causes undefined
-    /// behavior.
-    #[unstable(feature = "maybe_uninit_ref", issue = "53491")]
-    #[inline(always)]
-    pub unsafe fn get_ref(&self) -> &T {
-        &*self.value
-    }
-
-    /// Gets a mutable reference to the contained value.
-    ///
-    /// # Safety
-    ///
-    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
-    /// state. Calling this when the content is not yet fully initialized causes undefined
-    /// behavior.
-    // FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references
-    // to uninitialized data (e.g., in `libcore/fmt/float.rs`).  We should make
-    // a final decision about the rules before stabilization.
-    #[unstable(feature = "maybe_uninit_ref", issue = "53491")]
-    #[inline(always)]
-    pub unsafe fn get_mut(&mut self) -> &mut T {
-        &mut *self.value
-    }
-
-    /// Gets a pointer to the first element of the array.
-    #[unstable(feature = "maybe_uninit_slice", issue = "53491")]
-    #[inline(always)]
-    pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T {
-        this as *const [MaybeUninit<T>] as *const T
-    }
-
-    /// Gets a mutable pointer to the first element of the array.
-    #[unstable(feature = "maybe_uninit_slice", issue = "53491")]
-    #[inline(always)]
-    pub fn first_ptr_mut(this: &mut [MaybeUninit<T>]) -> *mut T {
-        this as *mut [MaybeUninit<T>] as *mut T
-    }
-}
diff --git a/src/libcore/mem/manually_drop.rs b/src/libcore/mem/manually_drop.rs
new file mode 100644
index 00000000000..bb353993236
--- /dev/null
+++ b/src/libcore/mem/manually_drop.rs
@@ -0,0 +1,148 @@
+use crate::ptr;
+use crate::ops::{Deref, DerefMut};
+
+/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
+///
+/// This wrapper is 0-cost.
+///
+/// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
+/// As a consequence, it has *no effect* on the assumptions that the compiler makes
+/// about all values being initialized at their type.  In particular, initializing
+/// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior.
+/// If you need to handle uninitialized data, use [`MaybeUninit<T>`] instead.
+///
+/// # Examples
+///
+/// This wrapper helps with explicitly documenting the drop order dependencies between fields of
+/// the type:
+///
+/// ```rust
+/// use std::mem::ManuallyDrop;
+/// struct Peach;
+/// struct Banana;
+/// struct Melon;
+/// struct FruitBox {
+///     // Immediately clear there’s something non-trivial going on with these fields.
+///     peach: ManuallyDrop<Peach>,
+///     melon: Melon, // Field that’s independent of the other two.
+///     banana: ManuallyDrop<Banana>,
+/// }
+///
+/// impl Drop for FruitBox {
+///     fn drop(&mut self) {
+///         unsafe {
+///             // Explicit ordering in which field destructors are run specified in the intuitive
+///             // location – the destructor of the structure containing the fields.
+///             // Moreover, one can now reorder fields within the struct however much they want.
+///             ManuallyDrop::drop(&mut self.peach);
+///             ManuallyDrop::drop(&mut self.banana);
+///         }
+///         // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
+///         // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
+///     }
+/// }
+/// ```
+///
+/// [`mem::zeroed`]: fn.zeroed.html
+/// [`MaybeUninit<T>`]: union.MaybeUninit.html
+#[stable(feature = "manually_drop", since = "1.20.0")]
+#[lang = "manually_drop"]
+#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(transparent)]
+pub struct ManuallyDrop<T: ?Sized> {
+    value: T,
+}
+
+impl<T> ManuallyDrop<T> {
+    /// Wrap a value to be manually dropped.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::mem::ManuallyDrop;
+    /// ManuallyDrop::new(Box::new(()));
+    /// ```
+    #[stable(feature = "manually_drop", since = "1.20.0")]
+    #[inline(always)]
+    pub const fn new(value: T) -> ManuallyDrop<T> {
+        ManuallyDrop { value }
+    }
+
+    /// Extracts the value from the `ManuallyDrop` container.
+    ///
+    /// This allows the value to be dropped again.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::mem::ManuallyDrop;
+    /// let x = ManuallyDrop::new(Box::new(()));
+    /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
+    /// ```
+    #[stable(feature = "manually_drop", since = "1.20.0")]
+    #[inline(always)]
+    pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
+        slot.value
+    }
+
+    /// Takes the contained value out.
+    ///
+    /// This method is primarily intended for moving out values in drop.
+    /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
+    /// you can use this method to take the value and use it however desired.
+    /// `Drop` will be invoked on the returned value following normal end-of-scope rules.
+    ///
+    /// If you have ownership of the container, you can use [`ManuallyDrop::into_inner`] instead.
+    ///
+    /// # Safety
+    ///
+    /// This function semantically moves out the contained value without preventing further usage.
+    /// It is up to the user of this method to ensure that this container is not used again.
+    ///
+    /// [`ManuallyDrop::drop`]: #method.drop
+    /// [`ManuallyDrop::into_inner`]: #method.into_inner
+    #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
+    #[unstable(feature = "manually_drop_take", issue = "55422")]
+    #[inline]
+    pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
+        ManuallyDrop::into_inner(ptr::read(slot))
+    }
+}
+
+impl<T: ?Sized> ManuallyDrop<T> {
+    /// Manually drops the contained value.
+    ///
+    /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead.
+    ///
+    /// # Safety
+    ///
+    /// This function runs the destructor of the contained value and thus the wrapped value
+    /// now represents uninitialized data. It is up to the user of this method to ensure the
+    /// uninitialized data is not actually used.
+    /// In particular, this function can only be called called at most once
+    /// for a given instance of `ManuallyDrop<T>`.
+    ///
+    /// [`ManuallyDrop::into_inner`]: #method.into_inner
+    #[stable(feature = "manually_drop", since = "1.20.0")]
+    #[inline]
+    pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
+        ptr::drop_in_place(&mut slot.value)
+    }
+}
+
+#[stable(feature = "manually_drop", since = "1.20.0")]
+impl<T: ?Sized> Deref for ManuallyDrop<T> {
+    type Target = T;
+    #[inline(always)]
+    fn deref(&self) -> &T {
+        &self.value
+    }
+}
+
+#[stable(feature = "manually_drop", since = "1.20.0")]
+impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
+    #[inline(always)]
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.value
+    }
+}
diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs
new file mode 100644
index 00000000000..9e9e901c76d
--- /dev/null
+++ b/src/libcore/mem/maybe_uninit.rs
@@ -0,0 +1,554 @@
+use crate::intrinsics;
+use crate::mem::ManuallyDrop;
+
+/// A wrapper type to construct uninitialized instances of `T`.
+///
+/// # Initialization invariant
+///
+/// The compiler, in general, assumes that variables are properly initialized
+/// at their respective type. For example, a variable of reference type must
+/// be aligned and non-NULL. This is an invariant that must *always* be upheld,
+/// even in unsafe code. As a consequence, zero-initializing a variable of reference
+/// type causes instantaneous [undefined behavior][ub], no matter whether that reference
+/// ever gets used to access memory:
+///
+/// ```rust,no_run
+/// # #![allow(invalid_value)]
+/// use std::mem::{self, MaybeUninit};
+///
+/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
+/// // The equivalent code with `MaybeUninit<&i32>`:
+/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior!
+/// ```
+///
+/// This is exploited by the compiler for various optimizations, such as eliding
+/// run-time checks and optimizing `enum` layout.
+///
+/// Similarly, entirely uninitialized memory may have any content, while a `bool` must
+/// always be `true` or `false`. Hence, creating an uninitialized `bool` is undefined behavior:
+///
+/// ```rust,no_run
+/// # #![allow(invalid_value)]
+/// use std::mem::{self, MaybeUninit};
+///
+/// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior!
+/// // The equivalent code with `MaybeUninit<bool>`:
+/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior!
+/// ```
+///
+/// Moreover, uninitialized memory is special in that the compiler knows that
+/// it does not have a fixed value. This makes it undefined behavior to have
+/// uninitialized data in a variable even if that variable has an integer type,
+/// which otherwise can hold any *fixed* bit pattern:
+///
+/// ```rust,no_run
+/// # #![allow(invalid_value)]
+/// use std::mem::{self, MaybeUninit};
+///
+/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior!
+/// // The equivalent code with `MaybeUninit<i32>`:
+/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior!
+/// ```
+/// (Notice that the rules around uninitialized integers are not finalized yet, but
+/// until they are, it is advisable to avoid them.)
+///
+/// On top of that, remember that most types have additional invariants beyond merely
+/// being considered initialized at the type level. For example, a `1`-initialized [`Vec<T>`]
+/// is considered initialized (under the current implementation; this does not constitute
+/// a stable guarantee) because the only requirement the compiler knows about it
+/// is that the data pointer must be non-null. Creating such a `Vec<T>` does not cause
+/// *immediate* undefined behavior, but will cause undefined behavior with most
+/// safe operations (including dropping it).
+///
+/// [`Vec<T>`]: ../../std/vec/struct.Vec.html
+///
+/// # Examples
+///
+/// `MaybeUninit<T>` serves to enable unsafe code to deal with uninitialized data.
+/// It is a signal to the compiler indicating that the data here might *not*
+/// be initialized:
+///
+/// ```rust
+/// use std::mem::MaybeUninit;
+///
+/// // Create an explicitly uninitialized reference. The compiler knows that data inside
+/// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
+/// let mut x = MaybeUninit::<&i32>::uninit();
+/// // Set it to a valid value.
+/// unsafe { x.as_mut_ptr().write(&0); }
+/// // Extract the initialized data -- this is only allowed *after* properly
+/// // initializing `x`!
+/// let x = unsafe { x.assume_init() };
+/// ```
+///
+/// The compiler then knows to not make any incorrect assumptions or optimizations on this code.
+///
+/// You can think of `MaybeUninit<T>` as being a bit like `Option<T>` but without
+/// any of the run-time tracking and without any of the safety checks.
+///
+/// ## out-pointers
+///
+/// You can use `MaybeUninit<T>` to implement "out-pointers": instead of returning data
+/// from a function, pass it a pointer to some (uninitialized) memory to put the
+/// result into. This can be useful when it is important for the caller to control
+/// how the memory the result is stored in gets allocated, and you want to avoid
+/// unnecessary moves.
+///
+/// ```
+/// use std::mem::MaybeUninit;
+///
+/// unsafe fn make_vec(out: *mut Vec<i32>) {
+///     // `write` does not drop the old contents, which is important.
+///     out.write(vec![1, 2, 3]);
+/// }
+///
+/// let mut v = MaybeUninit::uninit();
+/// unsafe { make_vec(v.as_mut_ptr()); }
+/// // Now we know `v` is initialized! This also makes sure the vector gets
+/// // properly dropped.
+/// let v = unsafe { v.assume_init() };
+/// assert_eq!(&v, &[1, 2, 3]);
+/// ```
+///
+/// ## Initializing an array element-by-element
+///
+/// `MaybeUninit<T>` can be used to initialize a large array element-by-element:
+///
+/// ```
+/// use std::mem::{self, MaybeUninit};
+///
+/// let data = {
+///     // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
+///     // safe because the type we are claiming to have initialized here is a
+///     // bunch of `MaybeUninit`s, which do not require initialization.
+///     let mut data: [MaybeUninit<Vec<u32>>; 1000] = unsafe {
+///         MaybeUninit::uninit().assume_init()
+///     };
+///
+///     // Dropping a `MaybeUninit` does nothing. Thus using raw pointer
+///     // assignment instead of `ptr::write` does not cause the old
+///     // uninitialized value to be dropped. Also if there is a panic during
+///     // this loop, we have a memory leak, but there is no memory safety
+///     // issue.
+///     for elem in &mut data[..] {
+///         *elem = MaybeUninit::new(vec![42]);
+///     }
+///
+///     // Everything is initialized. Transmute the array to the
+///     // initialized type.
+///     unsafe { mem::transmute::<_, [Vec<u32>; 1000]>(data) }
+/// };
+///
+/// assert_eq!(&data[0], &[42]);
+/// ```
+///
+/// You can also work with partially initialized arrays, which could
+/// be found in low-level datastructures.
+///
+/// ```
+/// use std::mem::MaybeUninit;
+/// use std::ptr;
+///
+/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
+/// // safe because the type we are claiming to have initialized here is a
+/// // bunch of `MaybeUninit`s, which do not require initialization.
+/// let mut data: [MaybeUninit<String>; 1000] = unsafe { MaybeUninit::uninit().assume_init() };
+/// // Count the number of elements we have assigned.
+/// let mut data_len: usize = 0;
+///
+/// for elem in &mut data[0..500] {
+///     *elem = MaybeUninit::new(String::from("hello"));
+///     data_len += 1;
+/// }
+///
+/// // For each item in the array, drop if we allocated it.
+/// for elem in &mut data[0..data_len] {
+///     unsafe { ptr::drop_in_place(elem.as_mut_ptr()); }
+/// }
+/// ```
+///
+/// ## Initializing a struct field-by-field
+///
+/// There is currently no supported way to create a raw pointer or reference
+/// to a field of a struct inside `MaybeUninit<Struct>`. That means it is not possible
+/// to create a struct by calling `MaybeUninit::uninit::<Struct>()` and then writing
+/// to its fields.
+///
+/// [ub]: ../../reference/behavior-considered-undefined.html
+///
+/// # Layout
+///
+/// `MaybeUninit<T>` is guaranteed to have the same size, alignment, and ABI as `T`:
+///
+/// ```rust
+/// use std::mem::{MaybeUninit, size_of, align_of};
+/// assert_eq!(size_of::<MaybeUninit<u64>>(), size_of::<u64>());
+/// assert_eq!(align_of::<MaybeUninit<u64>>(), align_of::<u64>());
+/// ```
+///
+/// However remember that a type *containing* a `MaybeUninit<T>` is not necessarily the same
+/// layout; Rust does not in general guarantee that the fields of a `Foo<T>` have the same order as
+/// a `Foo<U>` even if `T` and `U` have the same size and alignment. Furthermore because any bit
+/// value is valid for a `MaybeUninit<T>` the compiler can't apply non-zero/niche-filling
+/// optimizations, potentially resulting in a larger size:
+///
+/// ```rust
+/// # use std::mem::{MaybeUninit, size_of};
+/// assert_eq!(size_of::<Option<bool>>(), 1);
+/// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
+/// ```
+///
+/// If `T` is FFI-safe, then so is `MaybeUninit<T>`.
+///
+/// While `MaybeUninit` is `#[repr(transparent)]` (indicating it guarantees the same size,
+/// alignment, and ABI as `T`), this does *not* change any of the previous caveats. `Option<T>` and
+/// `Option<MaybeUninit<T>>` may still have different sizes, and types containing a field of type
+/// `T` may be laid out (and sized) differently than if that field were `MaybeUninit<T>`.
+/// `MaybeUninit` is a union type, and `#[repr(transparent)]` on unions is unstable (see [the
+/// tracking issue](https://github.com/rust-lang/rust/issues/60405)). Over time, the exact
+/// guarantees of `#[repr(transparent)]` on unions may evolve, and `MaybeUninit` may or may not
+/// remain `#[repr(transparent)]`. That said, `MaybeUninit<T>` will *always* guarantee that it has
+/// the same size, alignment, and ABI as `T`; it's just that the way `MaybeUninit` implements that
+/// guarantee may evolve.
+#[allow(missing_debug_implementations)]
+#[stable(feature = "maybe_uninit", since = "1.36.0")]
+// Lang item so we can wrap other types in it. This is useful for generators.
+#[lang = "maybe_uninit"]
+#[derive(Copy)]
+#[repr(transparent)]
+pub union MaybeUninit<T> {
+    uninit: (),
+    value: ManuallyDrop<T>,
+}
+
+#[stable(feature = "maybe_uninit", since = "1.36.0")]
+impl<T: Copy> Clone for MaybeUninit<T> {
+    #[inline(always)]
+    fn clone(&self) -> Self {
+        // Not calling `T::clone()`, we cannot know if we are initialized enough for that.
+        *self
+    }
+}
+
+impl<T> MaybeUninit<T> {
+    /// Creates a new `MaybeUninit<T>` initialized with the given value.
+    /// It is safe to call [`assume_init`] on the return value of this function.
+    ///
+    /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
+    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
+    ///
+    /// [`assume_init`]: #method.assume_init
+    #[stable(feature = "maybe_uninit", since = "1.36.0")]
+    #[inline(always)]
+    pub const fn new(val: T) -> MaybeUninit<T> {
+        MaybeUninit { value: ManuallyDrop::new(val) }
+    }
+
+    /// Creates a new `MaybeUninit<T>` in an uninitialized state.
+    ///
+    /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
+    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
+    ///
+    /// See the [type-level documentation][type] for some examples.
+    ///
+    /// [type]: union.MaybeUninit.html
+    #[stable(feature = "maybe_uninit", since = "1.36.0")]
+    #[inline(always)]
+    pub const fn uninit() -> MaybeUninit<T> {
+        MaybeUninit { uninit: () }
+    }
+
+    /// A promotable constant, equivalent to `uninit()`.
+    #[unstable(feature = "internal_uninit_const", issue = "0",
+        reason = "hack to work around promotability")]
+    pub const UNINIT: Self = Self::uninit();
+
+    /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
+    /// filled with `0` bytes. It depends on `T` whether that already makes for
+    /// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
+    /// but `MaybeUninit<&'static i32>::zeroed()` is not because references must not
+    /// be null.
+    ///
+    /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
+    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
+    ///
+    /// # Example
+    ///
+    /// Correct usage of this function: initializing a struct with zero, where all
+    /// fields of the struct can hold the bit-pattern 0 as a valid value.
+    ///
+    /// ```rust
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let x = MaybeUninit::<(u8, bool)>::zeroed();
+    /// let x = unsafe { x.assume_init() };
+    /// assert_eq!(x, (0, false));
+    /// ```
+    ///
+    /// *Incorrect* usage of this function: initializing a struct with zero, where some fields
+    /// cannot hold 0 as a valid value.
+    ///
+    /// ```rust,no_run
+    /// use std::mem::MaybeUninit;
+    ///
+    /// enum NotZero { One = 1, Two = 2 };
+    ///
+    /// let x = MaybeUninit::<(u8, NotZero)>::zeroed();
+    /// let x = unsafe { x.assume_init() };
+    /// // Inside a pair, we create a `NotZero` that does not have a valid discriminant.
+    /// // This is undefined behavior.
+    /// ```
+    #[stable(feature = "maybe_uninit", since = "1.36.0")]
+    #[inline]
+    pub fn zeroed() -> MaybeUninit<T> {
+        let mut u = MaybeUninit::<T>::uninit();
+        unsafe {
+            u.as_mut_ptr().write_bytes(0u8, 1);
+        }
+        u
+    }
+
+    /// Sets the value of the `MaybeUninit<T>`. This overwrites any previous value
+    /// without dropping it, so be careful not to use this twice unless you want to
+    /// skip running the destructor. For your convenience, this also returns a mutable
+    /// reference to the (now safely initialized) contents of `self`.
+    #[unstable(feature = "maybe_uninit_extra", issue = "63567")]
+    #[inline(always)]
+    pub fn write(&mut self, val: T) -> &mut T {
+        unsafe {
+            self.value = ManuallyDrop::new(val);
+            self.get_mut()
+        }
+    }
+
+    /// Gets a pointer to the contained value. Reading from this pointer or turning it
+    /// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
+    /// Writing to memory that this pointer (non-transitively) points to is undefined behavior
+    /// (except inside an `UnsafeCell<T>`).
+    ///
+    /// # Examples
+    ///
+    /// Correct usage of this method:
+    ///
+    /// ```rust
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
+    /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); }
+    /// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
+    /// let x_vec = unsafe { &*x.as_ptr() };
+    /// assert_eq!(x_vec.len(), 3);
+    /// ```
+    ///
+    /// *Incorrect* usage of this method:
+    ///
+    /// ```rust,no_run
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let x = MaybeUninit::<Vec<u32>>::uninit();
+    /// let x_vec = unsafe { &*x.as_ptr() };
+    /// // We have created a reference to an uninitialized vector! This is undefined behavior.
+    /// ```
+    ///
+    /// (Notice that the rules around references to uninitialized data are not finalized yet, but
+    /// until they are, it is advisable to avoid them.)
+    #[stable(feature = "maybe_uninit", since = "1.36.0")]
+    #[inline(always)]
+    pub fn as_ptr(&self) -> *const T {
+        unsafe { &*self.value as *const T }
+    }
+
+    /// Gets a mutable pointer to the contained value. Reading from this pointer or turning it
+    /// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
+    ///
+    /// # Examples
+    ///
+    /// Correct usage of this method:
+    ///
+    /// ```rust
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
+    /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); }
+    /// // Create a reference into the `MaybeUninit<Vec<u32>>`.
+    /// // This is okay because we initialized it.
+    /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
+    /// x_vec.push(3);
+    /// assert_eq!(x_vec.len(), 4);
+    /// ```
+    ///
+    /// *Incorrect* usage of this method:
+    ///
+    /// ```rust,no_run
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
+    /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
+    /// // We have created a reference to an uninitialized vector! This is undefined behavior.
+    /// ```
+    ///
+    /// (Notice that the rules around references to uninitialized data are not finalized yet, but
+    /// until they are, it is advisable to avoid them.)
+    #[stable(feature = "maybe_uninit", since = "1.36.0")]
+    #[inline(always)]
+    pub fn as_mut_ptr(&mut self) -> *mut T {
+        unsafe { &mut *self.value as *mut T }
+    }
+
+    /// Extracts the value from the `MaybeUninit<T>` container. This is a great way
+    /// to ensure that the data will get dropped, because the resulting `T` is
+    /// subject to the usual drop handling.
+    ///
+    /// # Safety
+    ///
+    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
+    /// state. Calling this when the content is not yet fully initialized causes immediate undefined
+    /// behavior. The [type-level documentation][inv] contains more information about
+    /// this initialization invariant.
+    ///
+    /// [inv]: #initialization-invariant
+    ///
+    /// On top of that, remember that most types have additional invariants beyond merely
+    /// being considered initialized at the type level. For example, a `1`-initialized [`Vec<T>`]
+    /// is considered initialized (under the current implementation; this does not constitute
+    /// a stable guarantee) because the only requirement the compiler knows about it
+    /// is that the data pointer must be non-null. Creating such a `Vec<T>` does not cause
+    /// *immediate* undefined behavior, but will cause undefined behavior with most
+    /// safe operations (including dropping it).
+    ///
+    /// # Examples
+    ///
+    /// Correct usage of this method:
+    ///
+    /// ```rust
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut x = MaybeUninit::<bool>::uninit();
+    /// unsafe { x.as_mut_ptr().write(true); }
+    /// let x_init = unsafe { x.assume_init() };
+    /// assert_eq!(x_init, true);
+    /// ```
+    ///
+    /// *Incorrect* usage of this method:
+    ///
+    /// ```rust,no_run
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let x = MaybeUninit::<Vec<u32>>::uninit();
+    /// let x_init = unsafe { x.assume_init() };
+    /// // `x` had not been initialized yet, so this last line caused undefined behavior.
+    /// ```
+    #[stable(feature = "maybe_uninit", since = "1.36.0")]
+    #[inline(always)]
+    pub unsafe fn assume_init(self) -> T {
+        intrinsics::panic_if_uninhabited::<T>();
+        ManuallyDrop::into_inner(self.value)
+    }
+
+    /// Reads the value from the `MaybeUninit<T>` container. The resulting `T` is subject
+    /// to the usual drop handling.
+    ///
+    /// Whenever possible, it is preferable to use [`assume_init`] instead, which
+    /// prevents duplicating the content of the `MaybeUninit<T>`.
+    ///
+    /// # Safety
+    ///
+    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
+    /// state. Calling this when the content is not yet fully initialized causes undefined
+    /// behavior. The [type-level documentation][inv] contains more information about
+    /// this initialization invariant.
+    ///
+    /// Moreover, this leaves a copy of the same data behind in the `MaybeUninit<T>`. When using
+    /// multiple copies of the data (by calling `read` multiple times, or first
+    /// calling `read` and then [`assume_init`]), it is your responsibility
+    /// to ensure that that data may indeed be duplicated.
+    ///
+    /// [inv]: #initialization-invariant
+    /// [`assume_init`]: #method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// Correct usage of this method:
+    ///
+    /// ```rust
+    /// #![feature(maybe_uninit_extra)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut x = MaybeUninit::<u32>::uninit();
+    /// x.write(13);
+    /// let x1 = unsafe { x.read() };
+    /// // `u32` is `Copy`, so we may read multiple times.
+    /// let x2 = unsafe { x.read() };
+    /// assert_eq!(x1, x2);
+    ///
+    /// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
+    /// x.write(None);
+    /// let x1 = unsafe { x.read() };
+    /// // Duplicating a `None` value is okay, so we may read multiple times.
+    /// let x2 = unsafe { x.read() };
+    /// assert_eq!(x1, x2);
+    /// ```
+    ///
+    /// *Incorrect* usage of this method:
+    ///
+    /// ```rust,no_run
+    /// #![feature(maybe_uninit_extra)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
+    /// x.write(Some(vec![0,1,2]));
+    /// let x1 = unsafe { x.read() };
+    /// let x2 = unsafe { x.read() };
+    /// // We now created two copies of the same vector, leading to a double-free when
+    /// // they both get dropped!
+    /// ```
+    #[unstable(feature = "maybe_uninit_extra", issue = "63567")]
+    #[inline(always)]
+    pub unsafe fn read(&self) -> T {
+        intrinsics::panic_if_uninhabited::<T>();
+        self.as_ptr().read()
+    }
+
+    /// Gets a reference to the contained value.
+    ///
+    /// # Safety
+    ///
+    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
+    /// state. Calling this when the content is not yet fully initialized causes undefined
+    /// behavior.
+    #[unstable(feature = "maybe_uninit_ref", issue = "63568")]
+    #[inline(always)]
+    pub unsafe fn get_ref(&self) -> &T {
+        &*self.value
+    }
+
+    /// Gets a mutable reference to the contained value.
+    ///
+    /// # Safety
+    ///
+    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
+    /// state. Calling this when the content is not yet fully initialized causes undefined
+    /// behavior.
+    // FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references
+    // to uninitialized data (e.g., in `libcore/fmt/float.rs`).  We should make
+    // a final decision about the rules before stabilization.
+    #[unstable(feature = "maybe_uninit_ref", issue = "63568")]
+    #[inline(always)]
+    pub unsafe fn get_mut(&mut self) -> &mut T {
+        &mut *self.value
+    }
+
+    /// Gets a pointer to the first element of the array.
+    #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
+    #[inline(always)]
+    pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T {
+        this as *const [MaybeUninit<T>] as *const T
+    }
+
+    /// Gets a mutable pointer to the first element of the array.
+    #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
+    #[inline(always)]
+    pub fn first_ptr_mut(this: &mut [MaybeUninit<T>]) -> *mut T {
+        this as *mut [MaybeUninit<T>] as *mut T
+    }
+}
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
new file mode 100644
index 00000000000..87ec05a243d
--- /dev/null
+++ b/src/libcore/mem/mod.rs
@@ -0,0 +1,830 @@
+//! Basic functions for dealing with memory.
+//!
+//! This module contains functions for querying the size and alignment of
+//! types, initializing and manipulating memory.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use crate::clone;
+use crate::cmp;
+use crate::fmt;
+use crate::hash;
+use crate::intrinsics;
+use crate::marker::{Copy, PhantomData, Sized};
+use crate::ptr;
+
+mod manually_drop;
+#[stable(feature = "manually_drop", since = "1.20.0")]
+pub use manually_drop::ManuallyDrop;
+
+mod maybe_uninit;
+#[stable(feature = "maybe_uninit", since = "1.36.0")]
+pub use maybe_uninit::MaybeUninit;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[doc(inline)]
+pub use crate::intrinsics::transmute;
+
+/// Takes ownership and "forgets" about the value **without running its destructor**.
+///
+/// Any resources the value manages, such as heap memory or a file handle, will linger
+/// forever in an unreachable state. However, it does not guarantee that pointers
+/// to this memory will remain valid.
+///
+/// * If you want to leak memory, see [`Box::leak`][leak].
+/// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`][into_raw].
+/// * If you want to dispose of a value properly, running its destructor, see
+/// [`mem::drop`][drop].
+///
+/// # Safety
+///
+/// `forget` is not marked as `unsafe`, because Rust's safety guarantees
+/// do not include a guarantee that destructors will always run. For example,
+/// a program can create a reference cycle using [`Rc`][rc], or call
+/// [`process::exit`][exit] to exit without running destructors. Thus, allowing
+/// `mem::forget` from safe code does not fundamentally change Rust's safety
+/// guarantees.
+///
+/// That said, leaking resources such as memory or I/O objects is usually undesirable,
+/// so `forget` is only recommended for specialized use cases like those shown below.
+///
+/// Because forgetting a value is allowed, any `unsafe` code you write must
+/// allow for this possibility. You cannot return a value and expect that the
+/// caller will necessarily run the value's destructor.
+///
+/// [rc]: ../../std/rc/struct.Rc.html
+/// [exit]: ../../std/process/fn.exit.html
+///
+/// # Examples
+///
+/// Leak an I/O object, never closing the file:
+///
+/// ```no_run
+/// use std::mem;
+/// use std::fs::File;
+///
+/// let file = File::open("foo.txt").unwrap();
+/// mem::forget(file);
+/// ```
+///
+/// The practical use cases for `forget` are rather specialized and mainly come
+/// up in unsafe or FFI code.
+///
+/// [drop]: fn.drop.html
+/// [uninit]: fn.uninitialized.html
+/// [clone]: ../clone/trait.Clone.html
+/// [swap]: fn.swap.html
+/// [box]: ../../std/boxed/struct.Box.html
+/// [leak]: ../../std/boxed/struct.Box.html#method.leak
+/// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw
+/// [ub]: ../../reference/behavior-considered-undefined.html
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn forget<T>(t: T) {
+    ManuallyDrop::new(t);
+}
+
+/// Like [`forget`], but also accepts unsized values.
+///
+/// This function is just a shim intended to be removed when the `unsized_locals` feature gets
+/// stabilized.
+///
+/// [`forget`]: fn.forget.html
+#[inline]
+#[unstable(feature = "forget_unsized", issue = "0")]
+pub fn forget_unsized<T: ?Sized>(t: T) {
+    unsafe { intrinsics::forget(t) }
+}
+
+/// Returns the size of a type in bytes.
+///
+/// More specifically, this is the offset in bytes between successive elements
+/// in an array with that item type including alignment padding. Thus, for any
+/// type `T` and length `n`, `[T; n]` has a size of `n * size_of::<T>()`.
+///
+/// In general, the size of a type is not stable across compilations, but
+/// specific types such as primitives are.
+///
+/// The following table gives the size for primitives.
+///
+/// Type | size_of::\<Type>()
+/// ---- | ---------------
+/// () | 0
+/// bool | 1
+/// u8 | 1
+/// u16 | 2
+/// u32 | 4
+/// u64 | 8
+/// u128 | 16
+/// i8 | 1
+/// i16 | 2
+/// i32 | 4
+/// i64 | 8
+/// i128 | 16
+/// f32 | 4
+/// f64 | 8
+/// char | 4
+///
+/// Furthermore, `usize` and `isize` have the same size.
+///
+/// The types `*const T`, `&T`, `Box<T>`, `Option<&T>`, and `Option<Box<T>>` all have
+/// the same size. If `T` is Sized, all of those types have the same size as `usize`.
+///
+/// The mutability of a pointer does not change its size. As such, `&T` and `&mut T`
+/// have the same size. Likewise for `*const T` and `*mut T`.
+///
+/// # Size of `#[repr(C)]` items
+///
+/// The `C` representation for items has a defined layout. With this layout,
+/// the size of items is also stable as long as all fields have a stable size.
+///
+/// ## Size of Structs
+///
+/// For `structs`, the size is determined by the following algorithm.
+///
+/// For each field in the struct ordered by declaration order:
+///
+/// 1. Add the size of the field.
+/// 2. Round up the current size to the nearest multiple of the next field's [alignment].
+///
+/// Finally, round the size of the struct to the nearest multiple of its [alignment].
+/// The alignment of the struct is usually the largest alignment of all its
+/// fields; this can be changed with the use of `repr(align(N))`.
+///
+/// Unlike `C`, zero sized structs are not rounded up to one byte in size.
+///
+/// ## Size of Enums
+///
+/// Enums that carry no data other than the discriminant have the same size as C enums
+/// on the platform they are compiled for.
+///
+/// ## Size of Unions
+///
+/// The size of a union is the size of its largest field.
+///
+/// Unlike `C`, zero sized unions are not rounded up to one byte in size.
+///
+/// # Examples
+///
+/// ```
+/// use std::mem;
+///
+/// // Some primitives
+/// assert_eq!(4, mem::size_of::<i32>());
+/// assert_eq!(8, mem::size_of::<f64>());
+/// assert_eq!(0, mem::size_of::<()>());
+///
+/// // Some arrays
+/// assert_eq!(8, mem::size_of::<[i32; 2]>());
+/// assert_eq!(12, mem::size_of::<[i32; 3]>());
+/// assert_eq!(0, mem::size_of::<[i32; 0]>());
+///
+///
+/// // Pointer size equality
+/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<*const i32>());
+/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Box<i32>>());
+/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>());
+/// assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>());
+/// ```
+///
+/// Using `#[repr(C)]`.
+///
+/// ```
+/// use std::mem;
+///
+/// #[repr(C)]
+/// struct FieldStruct {
+///     first: u8,
+///     second: u16,
+///     third: u8
+/// }
+///
+/// // The size of the first field is 1, so add 1 to the size. Size is 1.
+/// // The alignment of the second field is 2, so add 1 to the size for padding. Size is 2.
+/// // The size of the second field is 2, so add 2 to the size. Size is 4.
+/// // The alignment of the third field is 1, so add 0 to the size for padding. Size is 4.
+/// // The size of the third field is 1, so add 1 to the size. Size is 5.
+/// // Finally, the alignment of the struct is 2 (because the largest alignment amongst its
+/// // fields is 2), so add 1 to the size for padding. Size is 6.
+/// assert_eq!(6, mem::size_of::<FieldStruct>());
+///
+/// #[repr(C)]
+/// struct TupleStruct(u8, u16, u8);
+///
+/// // Tuple structs follow the same rules.
+/// assert_eq!(6, mem::size_of::<TupleStruct>());
+///
+/// // Note that reordering the fields can lower the size. We can remove both padding bytes
+/// // by putting `third` before `second`.
+/// #[repr(C)]
+/// struct FieldStructOptimized {
+///     first: u8,
+///     third: u8,
+///     second: u16
+/// }
+///
+/// assert_eq!(4, mem::size_of::<FieldStructOptimized>());
+///
+/// // Union size is the size of the largest field.
+/// #[repr(C)]
+/// union ExampleUnion {
+///     smaller: u8,
+///     larger: u16
+/// }
+///
+/// assert_eq!(2, mem::size_of::<ExampleUnion>());
+/// ```
+///
+/// [alignment]: ./fn.align_of.html
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_promotable]
+pub const fn size_of<T>() -> usize {
+    intrinsics::size_of::<T>()
+}
+
+/// Returns the size of the pointed-to value in bytes.
+///
+/// This is usually the same as `size_of::<T>()`. However, when `T` *has* no
+/// statically-known size, e.g., a slice [`[T]`][slice] or a [trait object],
+/// then `size_of_val` can be used to get the dynamically-known size.
+///
+/// [slice]: ../../std/primitive.slice.html
+/// [trait object]: ../../book/ch17-02-trait-objects.html
+///
+/// # Examples
+///
+/// ```
+/// use std::mem;
+///
+/// assert_eq!(4, mem::size_of_val(&5i32));
+///
+/// let x: [u8; 13] = [0; 13];
+/// let y: &[u8] = &x;
+/// assert_eq!(13, mem::size_of_val(y));
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn size_of_val<T: ?Sized>(val: &T) -> usize {
+    unsafe { intrinsics::size_of_val(val) }
+}
+
+/// Returns the [ABI]-required minimum alignment of a type.
+///
+/// Every reference to a value of the type `T` must be a multiple of this number.
+///
+/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
+///
+/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
+///
+/// # Examples
+///
+/// ```
+/// # #![allow(deprecated)]
+/// use std::mem;
+///
+/// assert_eq!(4, mem::min_align_of::<i32>());
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_deprecated(reason = "use `align_of` instead", since = "1.2.0")]
+pub fn min_align_of<T>() -> usize {
+    intrinsics::min_align_of::<T>()
+}
+
+/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to.
+///
+/// Every reference to a value of the type `T` must be a multiple of this number.
+///
+/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
+///
+/// # Examples
+///
+/// ```
+/// # #![allow(deprecated)]
+/// use std::mem;
+///
+/// assert_eq!(4, mem::min_align_of_val(&5i32));
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_deprecated(reason = "use `align_of_val` instead", since = "1.2.0")]
+pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
+    unsafe { intrinsics::min_align_of_val(val) }
+}
+
+/// Returns the [ABI]-required minimum alignment of a type.
+///
+/// Every reference to a value of the type `T` must be a multiple of this number.
+///
+/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
+///
+/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
+///
+/// # Examples
+///
+/// ```
+/// use std::mem;
+///
+/// assert_eq!(4, mem::align_of::<i32>());
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_promotable]
+pub const fn align_of<T>() -> usize {
+    intrinsics::min_align_of::<T>()
+}
+
+/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to.
+///
+/// Every reference to a value of the type `T` must be a multiple of this number.
+///
+/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
+///
+/// # Examples
+///
+/// ```
+/// use std::mem;
+///
+/// assert_eq!(4, mem::align_of_val(&5i32));
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
+    unsafe { intrinsics::min_align_of_val(val) }
+}
+
+/// Returns `true` if dropping values of type `T` matters.
+///
+/// This is purely an optimization hint, and may be implemented conservatively:
+/// it may return `true` for types that don't actually need to be dropped.
+/// As such always returning `true` would be a valid implementation of
+/// this function. However if this function actually returns `false`, then you
+/// can be certain dropping `T` has no side effect.
+///
+/// Low level implementations of things like collections, which need to manually
+/// drop their data, should use this function to avoid unnecessarily
+/// trying to drop all their contents when they are destroyed. This might not
+/// make a difference in release builds (where a loop that has no side-effects
+/// is easily detected and eliminated), but is often a big win for debug builds.
+///
+/// Note that `ptr::drop_in_place` already performs this check, so if your workload
+/// can be reduced to some small number of drop_in_place calls, using this is
+/// unnecessary. In particular note that you can drop_in_place a slice, and that
+/// will do a single needs_drop check for all the values.
+///
+/// Types like Vec therefore just `drop_in_place(&mut self[..])` without using
+/// needs_drop explicitly. Types like `HashMap`, on the other hand, have to drop
+/// values one at a time and should use this API.
+///
+///
+/// # Examples
+///
+/// Here's an example of how a collection might make use of `needs_drop`:
+///
+/// ```
+/// use std::{mem, ptr};
+///
+/// pub struct MyCollection<T> {
+/// #   data: [T; 1],
+///     /* ... */
+/// }
+/// # impl<T> MyCollection<T> {
+/// #   fn iter_mut(&mut self) -> &mut [T] { &mut self.data }
+/// #   fn free_buffer(&mut self) {}
+/// # }
+///
+/// impl<T> Drop for MyCollection<T> {
+///     fn drop(&mut self) {
+///         unsafe {
+///             // drop the data
+///             if mem::needs_drop::<T>() {
+///                 for x in self.iter_mut() {
+///                     ptr::drop_in_place(x);
+///                 }
+///             }
+///             self.free_buffer();
+///         }
+///     }
+/// }
+/// ```
+#[inline]
+#[stable(feature = "needs_drop", since = "1.21.0")]
+pub const fn needs_drop<T>() -> bool {
+    intrinsics::needs_drop::<T>()
+}
+
+/// Returns the value of type `T` represented by the all-zero byte-pattern.
+///
+/// This means that, for example, the padding byte in `(u8, u16)` is not
+/// necessarily zeroed.
+///
+/// There is no guarantee that an all-zero byte-pattern represents a valid value of
+/// some type `T`. For example, the all-zero byte-pattern is not a valid value
+/// for reference types (`&T` and `&mut T`). Using `zeroed` on such types
+/// causes immediate [undefined behavior][ub] because [the Rust compiler assumes][inv]
+/// that there always is a valid value in a variable it considers initialized.
+///
+/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed].
+/// It is useful for FFI sometimes, but should generally be avoided.
+///
+/// [zeroed]: union.MaybeUninit.html#method.zeroed
+/// [ub]: ../../reference/behavior-considered-undefined.html
+/// [inv]: union.MaybeUninit.html#initialization-invariant
+///
+/// # Examples
+///
+/// Correct usage of this function: initializing an integer with zero.
+///
+/// ```
+/// use std::mem;
+///
+/// let x: i32 = unsafe { mem::zeroed() };
+/// assert_eq!(0, x);
+/// ```
+///
+/// *Incorrect* usage of this function: initializing a reference with zero.
+///
+/// ```rust,no_run
+/// # #![allow(invalid_value)]
+/// use std::mem;
+///
+/// let _x: &i32 = unsafe { mem::zeroed() }; // Undefined behavior!
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated_in_future)]
+#[allow(deprecated)]
+pub unsafe fn zeroed<T>() -> T {
+    intrinsics::panic_if_uninhabited::<T>();
+    intrinsics::init()
+}
+
+/// Bypasses Rust's normal memory-initialization checks by pretending to
+/// produce a value of type `T`, while doing nothing at all.
+///
+/// **This function is deprecated.** Use [`MaybeUninit<T>`] instead.
+///
+/// The reason for deprecation is that the function basically cannot be used
+/// correctly: [the Rust compiler assumes][inv] that values are properly initialized.
+/// As a consequence, calling e.g. `mem::uninitialized::<bool>()` causes immediate
+/// undefined behavior for returning a `bool` that is not definitely either `true`
+/// or `false`. Worse, truly uninitialized memory like what gets returned here
+/// is special in that the compiler knows that it does not have a fixed value.
+/// This makes it undefined behavior to have uninitialized data in a variable even
+/// if that variable has an integer type.
+/// (Notice that the rules around uninitialized integers are not finalized yet, but
+/// until they are, it is advisable to avoid them.)
+///
+/// [`MaybeUninit<T>`]: union.MaybeUninit.html
+/// [inv]: union.MaybeUninit.html#initialization-invariant
+#[inline]
+#[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated_in_future)]
+#[allow(deprecated)]
+pub unsafe fn uninitialized<T>() -> T {
+    intrinsics::panic_if_uninhabited::<T>();
+    intrinsics::uninit()
+}
+
+/// Swaps the values at two mutable locations, without deinitializing either one.
+///
+/// # Examples
+///
+/// ```
+/// use std::mem;
+///
+/// let mut x = 5;
+/// let mut y = 42;
+///
+/// mem::swap(&mut x, &mut y);
+///
+/// assert_eq!(42, x);
+/// assert_eq!(5, y);
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn swap<T>(x: &mut T, y: &mut T) {
+    unsafe {
+        ptr::swap_nonoverlapping_one(x, y);
+    }
+}
+
+/// Replace `dest` with the default value of `T`, and return the previous `dest` value.
+///
+/// # Examples
+///
+/// A simple example:
+///
+/// ```
+/// #![feature(mem_take)]
+///
+/// use std::mem;
+///
+/// let mut v: Vec<i32> = vec![1, 2];
+///
+/// let old_v = mem::take(&mut v);
+/// assert_eq!(vec![1, 2], old_v);
+/// assert!(v.is_empty());
+/// ```
+///
+/// `take` allows taking ownership of a struct field by replacing it with an "empty" value.
+/// Without `take` you can run into issues like these:
+///
+/// ```compile_fail,E0507
+/// struct Buffer<T> { buf: Vec<T> }
+///
+/// impl<T> Buffer<T> {
+///     fn get_and_reset(&mut self) -> Vec<T> {
+///         // error: cannot move out of dereference of `&mut`-pointer
+///         let buf = self.buf;
+///         self.buf = Vec::new();
+///         buf
+///     }
+/// }
+/// ```
+///
+/// Note that `T` does not necessarily implement [`Clone`], so it can't even clone and reset
+/// `self.buf`. But `take` can be used to disassociate the original value of `self.buf` from
+/// `self`, allowing it to be returned:
+///
+/// ```
+/// #![feature(mem_take)]
+///
+/// use std::mem;
+///
+/// # struct Buffer<T> { buf: Vec<T> }
+/// impl<T> Buffer<T> {
+///     fn get_and_reset(&mut self) -> Vec<T> {
+///         mem::take(&mut self.buf)
+///     }
+/// }
+///
+/// let mut buffer = Buffer { buf: vec![0, 1] };
+/// assert_eq!(buffer.buf.len(), 2);
+///
+/// assert_eq!(buffer.get_and_reset(), vec![0, 1]);
+/// assert_eq!(buffer.buf.len(), 0);
+/// ```
+///
+/// [`Clone`]: ../../std/clone/trait.Clone.html
+#[inline]
+#[unstable(feature = "mem_take", issue = "61129")]
+pub fn take<T: Default>(dest: &mut T) -> T {
+    replace(dest, T::default())
+}
+
+/// Moves `src` into the referenced `dest`, returning the previous `dest` value.
+///
+/// Neither value is dropped.
+///
+/// # Examples
+///
+/// A simple example:
+///
+/// ```
+/// use std::mem;
+///
+/// let mut v: Vec<i32> = vec![1, 2];
+///
+/// let old_v = mem::replace(&mut v, vec![3, 4, 5]);
+/// assert_eq!(vec![1, 2], old_v);
+/// assert_eq!(vec![3, 4, 5], v);
+/// ```
+///
+/// `replace` allows consumption of a struct field by replacing it with another value.
+/// Without `replace` you can run into issues like these:
+///
+/// ```compile_fail,E0507
+/// struct Buffer<T> { buf: Vec<T> }
+///
+/// impl<T> Buffer<T> {
+///     fn replace_index(&mut self, i: usize, v: T) -> T {
+///         // error: cannot move out of dereference of `&mut`-pointer
+///         let t = self.buf[i];
+///         self.buf[i] = v;
+///         t
+///     }
+/// }
+/// ```
+///
+/// Note that `T` does not necessarily implement [`Clone`], so we can't even clone `self.buf[i]` to
+/// avoid the move. But `replace` can be used to disassociate the original value at that index from
+/// `self`, allowing it to be returned:
+///
+/// ```
+/// # #![allow(dead_code)]
+/// use std::mem;
+///
+/// # struct Buffer<T> { buf: Vec<T> }
+/// impl<T> Buffer<T> {
+///     fn replace_index(&mut self, i: usize, v: T) -> T {
+///         mem::replace(&mut self.buf[i], v)
+///     }
+/// }
+///
+/// let mut buffer = Buffer { buf: vec![0, 1] };
+/// assert_eq!(buffer.buf[0], 0);
+///
+/// assert_eq!(buffer.replace_index(0, 2), 0);
+/// assert_eq!(buffer.buf[0], 2);
+/// ```
+///
+/// [`Clone`]: ../../std/clone/trait.Clone.html
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn replace<T>(dest: &mut T, mut src: T) -> T {
+    swap(dest, &mut src);
+    src
+}
+
+/// Disposes of a value.
+///
+/// This does call the argument's implementation of [`Drop`][drop].
+///
+/// This effectively does nothing for types which implement `Copy`, e.g.
+/// integers. Such values are copied and _then_ moved into the function, so the
+/// value persists after this function call.
+///
+/// This function is not magic; it is literally defined as
+///
+/// ```
+/// pub fn drop<T>(_x: T) { }
+/// ```
+///
+/// Because `_x` is moved into the function, it is automatically dropped before
+/// the function returns.
+///
+/// [drop]: ../ops/trait.Drop.html
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// let v = vec![1, 2, 3];
+///
+/// drop(v); // explicitly drop the vector
+/// ```
+///
+/// Since [`RefCell`] enforces the borrow rules at runtime, `drop` can
+/// release a [`RefCell`] borrow:
+///
+/// ```
+/// use std::cell::RefCell;
+///
+/// let x = RefCell::new(1);
+///
+/// let mut mutable_borrow = x.borrow_mut();
+/// *mutable_borrow = 1;
+///
+/// drop(mutable_borrow); // relinquish the mutable borrow on this slot
+///
+/// let borrow = x.borrow();
+/// println!("{}", *borrow);
+/// ```
+///
+/// Integers and other types implementing [`Copy`] are unaffected by `drop`.
+///
+/// ```
+/// #[derive(Copy, Clone)]
+/// struct Foo(u8);
+///
+/// let x = 1;
+/// let y = Foo(2);
+/// drop(x); // a copy of `x` is moved and dropped
+/// drop(y); // a copy of `y` is moved and dropped
+///
+/// println!("x: {}, y: {}", x, y.0); // still available
+/// ```
+///
+/// [`RefCell`]: ../../std/cell/struct.RefCell.html
+/// [`Copy`]: ../../std/marker/trait.Copy.html
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn drop<T>(_x: T) { }
+
+/// Interprets `src` as having type `&U`, and then reads `src` without moving
+/// the contained value.
+///
+/// This function will unsafely assume the pointer `src` is valid for
+/// [`size_of::<U>`][size_of] bytes by transmuting `&T` to `&U` and then reading
+/// the `&U`. It will also unsafely create a copy of the contained value instead of
+/// moving out of `src`.
+///
+/// It is not a compile-time error if `T` and `U` have different sizes, but it
+/// is highly encouraged to only invoke this function where `T` and `U` have the
+/// same size. This function triggers [undefined behavior][ub] if `U` is larger than
+/// `T`.
+///
+/// [ub]: ../../reference/behavior-considered-undefined.html
+/// [size_of]: fn.size_of.html
+///
+/// # Examples
+///
+/// ```
+/// use std::mem;
+///
+/// #[repr(packed)]
+/// struct Foo {
+///     bar: u8,
+/// }
+///
+/// let foo_slice = [10u8];
+///
+/// unsafe {
+///     // Copy the data from 'foo_slice' and treat it as a 'Foo'
+///     let mut foo_struct: Foo = mem::transmute_copy(&foo_slice);
+///     assert_eq!(foo_struct.bar, 10);
+///
+///     // Modify the copied data
+///     foo_struct.bar = 20;
+///     assert_eq!(foo_struct.bar, 20);
+/// }
+///
+/// // The contents of 'foo_slice' should not have changed
+/// assert_eq!(foo_slice, [10]);
+/// ```
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
+    ptr::read_unaligned(src as *const T as *const U)
+}
+
+/// Opaque type representing the discriminant of an enum.
+///
+/// See the [`discriminant`] function in this module for more information.
+///
+/// [`discriminant`]: fn.discriminant.html
+#[stable(feature = "discriminant_value", since = "1.21.0")]
+pub struct Discriminant<T>(u64, PhantomData<fn() -> T>);
+
+// N.B. These trait implementations cannot be derived because we don't want any bounds on T.
+
+#[stable(feature = "discriminant_value", since = "1.21.0")]
+impl<T> Copy for Discriminant<T> {}
+
+#[stable(feature = "discriminant_value", since = "1.21.0")]
+impl<T> clone::Clone for Discriminant<T> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+#[stable(feature = "discriminant_value", since = "1.21.0")]
+impl<T> cmp::PartialEq for Discriminant<T> {
+    fn eq(&self, rhs: &Self) -> bool {
+        self.0 == rhs.0
+    }
+}
+
+#[stable(feature = "discriminant_value", since = "1.21.0")]
+impl<T> cmp::Eq for Discriminant<T> {}
+
+#[stable(feature = "discriminant_value", since = "1.21.0")]
+impl<T> hash::Hash for Discriminant<T> {
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.0.hash(state);
+    }
+}
+
+#[stable(feature = "discriminant_value", since = "1.21.0")]
+impl<T> fmt::Debug for Discriminant<T> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_tuple("Discriminant")
+           .field(&self.0)
+           .finish()
+    }
+}
+
+/// Returns a value uniquely identifying the enum variant in `v`.
+///
+/// If `T` is not an enum, calling this function will not result in undefined behavior, but the
+/// return value is unspecified.
+///
+/// # Stability
+///
+/// The discriminant of an enum variant may change if the enum definition changes. A discriminant
+/// of some variant will not change between compilations with the same compiler.
+///
+/// # Examples
+///
+/// This can be used to compare enums that carry data, while disregarding
+/// the actual data:
+///
+/// ```
+/// use std::mem;
+///
+/// enum Foo { A(&'static str), B(i32), C(i32) }
+///
+/// assert!(mem::discriminant(&Foo::A("bar")) == mem::discriminant(&Foo::A("baz")));
+/// assert!(mem::discriminant(&Foo::B(1))     == mem::discriminant(&Foo::B(2)));
+/// assert!(mem::discriminant(&Foo::B(3))     != mem::discriminant(&Foo::C(3)));
+/// ```
+#[stable(feature = "discriminant_value", since = "1.21.0")]
+pub fn discriminant<T>(v: &T) -> Discriminant<T> {
+    unsafe {
+        Discriminant(intrinsics::discriminant_value(v), PhantomData)
+    }
+}
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 3f8d142c845..8ff78166a9f 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -7,6 +7,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(not(test))]
+use crate::intrinsics;
+
 use crate::mem;
 use crate::num::FpCategory;
 
@@ -372,15 +375,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn max(self, other: f32) -> f32 {
-        // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
-        // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-        // is either x or y, canonicalized (this means results might differ among implementations).
-        // When either x or y is a signalingNaN, then the result is according to 6.2.
-        //
-        // Since we do not support sNaN in Rust yet, we do not need to handle them.
-        // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-        // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-        (if self.is_nan() || self < other { other } else { self }) * 1.0
+        intrinsics::maxnumf32(self, other)
     }
 
     /// Returns the minimum of the two numbers.
@@ -396,15 +391,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn min(self, other: f32) -> f32 {
-        // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
-        // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-        // is either x or y, canonicalized (this means results might differ among implementations).
-        // When either x or y is a signalingNaN, then the result is according to 6.2.
-        //
-        // Since we do not support sNaN in Rust yet, we do not need to handle them.
-        // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-        // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-        (if other.is_nan() || self < other { self } else { other }) * 1.0
+        intrinsics::minnumf32(self, other)
     }
 
     /// Raw transmutation to `u32`.
@@ -463,10 +450,8 @@ impl f32 {
     /// # Examples
     ///
     /// ```
-    /// use std::f32;
     /// let v = f32::from_bits(0x41480000);
-    /// let difference = (v - 12.5).abs();
-    /// assert!(difference <= 1e-5);
+    /// assert_eq!(v, 12.5);
     /// ```
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
@@ -474,4 +459,121 @@ impl f32 {
         // It turns out the safety issues with sNaN were overblown! Hooray!
         unsafe { mem::transmute(v) }
     }
+
+    /// Return the memory representation of this floating point number as a byte array in
+    /// big-endian (network) byte order.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let bytes = 12.5f32.to_be_bytes();
+    /// assert_eq!(bytes, [0x41, 0x48, 0x00, 0x00]);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn to_be_bytes(self) -> [u8; 4] {
+        self.to_bits().to_be_bytes()
+    }
+
+    /// Return the memory representation of this floating point number as a byte array in
+    /// little-endian byte order.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let bytes = 12.5f32.to_le_bytes();
+    /// assert_eq!(bytes, [0x00, 0x00, 0x48, 0x41]);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn to_le_bytes(self) -> [u8; 4] {
+        self.to_bits().to_le_bytes()
+    }
+
+    /// Return the memory representation of this floating point number as a byte array in
+    /// native byte order.
+    ///
+    /// As the target platform's native endianness is used, portable code
+    /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
+    ///
+    /// [`to_be_bytes`]: #method.to_be_bytes
+    /// [`to_le_bytes`]: #method.to_le_bytes
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let bytes = 12.5f32.to_ne_bytes();
+    /// assert_eq!(
+    ///     bytes,
+    ///     if cfg!(target_endian = "big") {
+    ///         [0x41, 0x48, 0x00, 0x00]
+    ///     } else {
+    ///         [0x00, 0x00, 0x48, 0x41]
+    ///     }
+    /// );
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn to_ne_bytes(self) -> [u8; 4] {
+        self.to_bits().to_ne_bytes()
+    }
+
+    /// Create a floating point value from its representation as a byte array in big endian.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let value = f32::from_be_bytes([0x41, 0x48, 0x00, 0x00]);
+    /// assert_eq!(value, 12.5);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn from_be_bytes(bytes: [u8; 4]) -> Self {
+        Self::from_bits(u32::from_be_bytes(bytes))
+    }
+
+    /// Create a floating point value from its representation as a byte array in little endian.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let value = f32::from_le_bytes([0x00, 0x00, 0x48, 0x41]);
+    /// assert_eq!(value, 12.5);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn from_le_bytes(bytes: [u8; 4]) -> Self {
+        Self::from_bits(u32::from_le_bytes(bytes))
+    }
+
+    /// Create a floating point value from its representation as a byte array in native endian.
+    ///
+    /// As the target platform's native endianness is used, portable code
+    /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
+    /// appropriate instead.
+    ///
+    /// [`from_be_bytes`]: #method.from_be_bytes
+    /// [`from_le_bytes`]: #method.from_le_bytes
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let value = f32::from_ne_bytes(if cfg!(target_endian = "big") {
+    ///     [0x41, 0x48, 0x00, 0x00]
+    /// } else {
+    ///     [0x00, 0x00, 0x48, 0x41]
+    /// });
+    /// assert_eq!(value, 12.5);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn from_ne_bytes(bytes: [u8; 4]) -> Self {
+        Self::from_bits(u32::from_ne_bytes(bytes))
+    }
 }
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 7f19101fe6e..d45c04f45af 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -7,6 +7,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(not(test))]
+use crate::intrinsics;
+
 use crate::mem;
 use crate::num::FpCategory;
 
@@ -385,15 +388,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn max(self, other: f64) -> f64 {
-        // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
-        // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-        // is either x or y, canonicalized (this means results might differ among implementations).
-        // When either x or y is a signalingNaN, then the result is according to 6.2.
-        //
-        // Since we do not support sNaN in Rust yet, we do not need to handle them.
-        // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-        // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-        (if self.is_nan() || self < other { other } else { self }) * 1.0
+        intrinsics::maxnumf64(self, other)
     }
 
     /// Returns the minimum of the two numbers.
@@ -409,15 +404,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn min(self, other: f64) -> f64 {
-        // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
-        // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-        // is either x or y, canonicalized (this means results might differ among implementations).
-        // When either x or y is a signalingNaN, then the result is according to 6.2.
-        //
-        // Since we do not support sNaN in Rust yet, we do not need to handle them.
-        // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-        // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-        (if other.is_nan() || self < other { self } else { other }) * 1.0
+        intrinsics::minnumf64(self, other)
     }
 
     /// Raw transmutation to `u64`.
@@ -476,10 +463,8 @@ impl f64 {
     /// # Examples
     ///
     /// ```
-    /// use std::f64;
     /// let v = f64::from_bits(0x4029000000000000);
-    /// let difference = (v - 12.5).abs();
-    /// assert!(difference <= 1e-5);
+    /// assert_eq!(v, 12.5);
     /// ```
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
@@ -487,4 +472,121 @@ impl f64 {
         // It turns out the safety issues with sNaN were overblown! Hooray!
         unsafe { mem::transmute(v) }
     }
+
+    /// Return the memory representation of this floating point number as a byte array in
+    /// big-endian (network) byte order.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let bytes = 12.5f64.to_be_bytes();
+    /// assert_eq!(bytes, [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn to_be_bytes(self) -> [u8; 8] {
+        self.to_bits().to_be_bytes()
+    }
+
+    /// Return the memory representation of this floating point number as a byte array in
+    /// little-endian byte order.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let bytes = 12.5f64.to_le_bytes();
+    /// assert_eq!(bytes, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn to_le_bytes(self) -> [u8; 8] {
+        self.to_bits().to_le_bytes()
+    }
+
+    /// Return the memory representation of this floating point number as a byte array in
+    /// native byte order.
+    ///
+    /// As the target platform's native endianness is used, portable code
+    /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
+    ///
+    /// [`to_be_bytes`]: #method.to_be_bytes
+    /// [`to_le_bytes`]: #method.to_le_bytes
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let bytes = 12.5f64.to_ne_bytes();
+    /// assert_eq!(
+    ///     bytes,
+    ///     if cfg!(target_endian = "big") {
+    ///         [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
+    ///     } else {
+    ///         [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]
+    ///     }
+    /// );
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn to_ne_bytes(self) -> [u8; 8] {
+        self.to_bits().to_ne_bytes()
+    }
+
+    /// Create a floating point value from its representation as a byte array in big endian.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let value = f64::from_be_bytes([0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
+    /// assert_eq!(value, 12.5);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn from_be_bytes(bytes: [u8; 8]) -> Self {
+        Self::from_bits(u64::from_be_bytes(bytes))
+    }
+
+    /// Create a floating point value from its representation as a byte array in little endian.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let value = f64::from_le_bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
+    /// assert_eq!(value, 12.5);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn from_le_bytes(bytes: [u8; 8]) -> Self {
+        Self::from_bits(u64::from_le_bytes(bytes))
+    }
+
+    /// Create a floating point value from its representation as a byte array in native endian.
+    ///
+    /// As the target platform's native endianness is used, portable code
+    /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
+    /// appropriate instead.
+    ///
+    /// [`from_be_bytes`]: #method.from_be_bytes
+    /// [`from_le_bytes`]: #method.from_le_bytes
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_to_from_bytes)]
+    /// let value = f64::from_ne_bytes(if cfg!(target_endian = "big") {
+    ///     [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
+    /// } else {
+    ///     [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]
+    /// });
+    /// assert_eq!(value, 12.5);
+    /// ```
+    #[unstable(feature = "float_to_from_bytes", issue = "60446")]
+    #[inline]
+    pub fn from_ne_bytes(bytes: [u8; 8]) -> Self {
+        Self::from_bits(u64::from_ne_bytes(bytes))
+    }
 }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 562a7a4b3c7..b46e06f8d8a 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -50,6 +50,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
                 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
                 #[repr(transparent)]
                 #[rustc_layout_scalar_valid_range_start(1)]
+                #[rustc_nonnull_optimization_guaranteed]
                 pub struct $Ty($Int);
             }
 
@@ -462,16 +463,14 @@ assert_eq!(m, ", $swapped, ");
 Basic usage:
 
 ```
-#![feature(reverse_bits)]
-
 let n = ", $swap_op, stringify!($SelfT), ";
 let m = n.reverse_bits();
 
 assert_eq!(m, ", $reversed, ");
 ```"),
-            #[unstable(feature = "reverse_bits", issue = "48763")]
-            #[rustc_const_unstable(feature = "const_int_conversion")]
+            #[stable(feature = "reverse_bits", since = "1.37.0")]
             #[inline]
+            #[must_use]
             pub const fn reverse_bits(self) -> Self {
                 (self as $UnsignedT).reverse_bits() as Self
             }
@@ -718,13 +717,12 @@ returning `None` if `rhs == 0` or the division results in overflow.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 assert_eq!((", stringify!($SelfT),
 "::min_value() + 1).checked_div_euclid(-1), Some(", stringify!($Max), "));
 assert_eq!(", stringify!($SelfT), "::min_value().checked_div_euclid(-1), None);
 assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None);
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -775,14 +773,13 @@ if `rhs == 0` or the division results in overflow.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 use std::", stringify!($SelfT), ";
 
 assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));
 assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
 assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None);
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1115,7 +1112,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_add(self, rhs: Self) -> Self {
-                intrinsics::overflowing_add(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_add(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_add(self, rhs)
+                }
             }
         }
 
@@ -1138,7 +1141,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_sub(self, rhs: Self) -> Self {
-                intrinsics::overflowing_sub(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_sub(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_sub(self, rhs)
+                }
             }
         }
 
@@ -1160,7 +1169,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_mul(self, rhs: Self) -> Self {
-                intrinsics::overflowing_mul(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_mul(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_mul(self, rhs)
+                }
             }
         }
 
@@ -1211,11 +1226,10 @@ This function will panic if `rhs` is 0.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
 assert_eq!((-128i8).wrapping_div_euclid(-1), -128);
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1270,11 +1284,10 @@ This function will panic if `rhs` is 0.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
 assert_eq!((-128i8).wrapping_rem_euclid(-1), 0);
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1567,7 +1580,6 @@ This function will panic if `rhs` is 0.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 use std::", stringify!($SelfT), ";
 
 assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));
@@ -1575,7 +1587,7 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringi
 "::MIN, true));
 ```"),
             #[inline]
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
@@ -1637,13 +1649,12 @@ This function will panic if `rhs` is 0.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 use std::", stringify!($SelfT), ";
 
 assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
 assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true));
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1874,7 +1885,6 @@ This function will panic if `rhs` is 0.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 let a: ", stringify!($SelfT), " = 7; // or any other integer type
 let b = 4;
 
@@ -1883,7 +1893,7 @@ assert_eq!(a.div_euclid(-b), -1); // 7 >= -4 * -1
 assert_eq!((-a).div_euclid(b), -2); // -7 >= 4 * -2
 assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1914,7 +1924,6 @@ This function will panic if `rhs` is 0.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 let a: ", stringify!($SelfT), " = 7; // or any other integer type
 let b = 4;
 
@@ -1923,7 +1932,7 @@ assert_eq!((-a).rem_euclid(b), 1);
 assert_eq!(a.rem_euclid(-b), 3);
 assert_eq!((-a).rem_euclid(-b), 1);
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -1994,13 +2003,10 @@ assert_eq!((-10", stringify!($SelfT), ").signum(), -1);",
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[rustc_const_unstable(feature = "const_int_sign")]
             #[inline]
-            pub fn signum(self) -> Self {
-                match self {
-                    n if n > 0 =>  1,
-                    0          =>  0,
-                    _          => -1,
-                }
+            pub const fn signum(self) -> Self {
+                (self > 0) as Self - (self < 0) as Self
             }
         }
 
@@ -2512,15 +2518,14 @@ assert_eq!(m, ", $swapped, ");
 Basic usage:
 
 ```
-#![feature(reverse_bits)]
-
 let n = ", $swap_op, stringify!($SelfT), ";
 let m = n.reverse_bits();
 
 assert_eq!(m, ", $reversed, ");
 ```"),
-            #[unstable(feature = "reverse_bits", issue = "48763")]
+            #[stable(feature = "reverse_bits", since = "1.37.0")]
             #[inline]
+            #[must_use]
             pub const fn reverse_bits(self) -> Self {
                 intrinsics::bitreverse(self as $ActualT) as Self
             }
@@ -2758,11 +2763,10 @@ if `rhs == 0`.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64));
 assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None);
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -2810,11 +2814,10 @@ if `rhs == 0`.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));
 assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3046,7 +3049,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_add(self, rhs: Self) -> Self {
-                intrinsics::overflowing_add(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_add(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_add(self, rhs)
+                }
             }
         }
 
@@ -3068,7 +3077,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_sub(self, rhs: Self) -> Self {
-                intrinsics::overflowing_sub(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_sub(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_sub(self, rhs)
+                }
             }
         }
 
@@ -3091,7 +3106,13 @@ $EndFeature, "
                           without modifying the original"]
         #[inline]
         pub const fn wrapping_mul(self, rhs: Self) -> Self {
-            intrinsics::overflowing_mul(self, rhs)
+            #[cfg(boostrap_stdarch_ignore_this)] {
+                intrinsics::overflowing_mul(self, rhs)
+            }
+
+            #[cfg(not(boostrap_stdarch_ignore_this))] {
+                intrinsics::wrapping_mul(self, rhs)
+            }
         }
 
         doc_comment! {
@@ -3132,10 +3153,9 @@ is exactly equal to `self.wrapping_div(rhs)`.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3184,10 +3204,9 @@ is exactly equal to `self.wrapping_rem(rhs)`.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3453,11 +3472,10 @@ This function will panic if `rhs` is 0.
 Basic usage
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));
 ```"),
             #[inline]
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
@@ -3513,11 +3531,10 @@ This function will panic if `rhs` is 0.
 Basic usage
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
 ```"),
             #[inline]
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
@@ -3701,10 +3718,9 @@ is exactly equal to `self / rhs`.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -3727,10 +3743,9 @@ is exactly equal to `self % rhs`.
 Basic usage:
 
 ```
-#![feature(euclidean_division)]
 assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type
 ```"),
-            #[unstable(feature = "euclidean_division", issue = "49048")]
+            #[stable(feature = "euclidean_division", since = "1.38.0")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
@@ -4171,8 +4186,8 @@ impl u8 {
 
     /// Checks if the value is an ASCII alphabetic character:
     ///
-    /// - U+0041 'A' ... U+005A 'Z', or
-    /// - U+0061 'a' ... U+007A 'z'.
+    /// - U+0041 'A' ..= U+005A 'Z', or
+    /// - U+0061 'a' ..= U+007A 'z'.
     ///
     /// # Examples
     ///
@@ -4207,7 +4222,7 @@ impl u8 {
     }
 
     /// Checks if the value is an ASCII uppercase character:
-    /// U+0041 'A' ... U+005A 'Z'.
+    /// U+0041 'A' ..= U+005A 'Z'.
     ///
     /// # Examples
     ///
@@ -4242,7 +4257,7 @@ impl u8 {
     }
 
     /// Checks if the value is an ASCII lowercase character:
-    /// U+0061 'a' ... U+007A 'z'.
+    /// U+0061 'a' ..= U+007A 'z'.
     ///
     /// # Examples
     ///
@@ -4278,9 +4293,9 @@ impl u8 {
 
     /// Checks if the value is an ASCII alphanumeric character:
     ///
-    /// - U+0041 'A' ... U+005A 'Z', or
-    /// - U+0061 'a' ... U+007A 'z', or
-    /// - U+0030 '0' ... U+0039 '9'.
+    /// - U+0041 'A' ..= U+005A 'Z', or
+    /// - U+0061 'a' ..= U+007A 'z', or
+    /// - U+0030 '0' ..= U+0039 '9'.
     ///
     /// # Examples
     ///
@@ -4315,7 +4330,7 @@ impl u8 {
     }
 
     /// Checks if the value is an ASCII decimal digit:
-    /// U+0030 '0' ... U+0039 '9'.
+    /// U+0030 '0' ..= U+0039 '9'.
     ///
     /// # Examples
     ///
@@ -4351,9 +4366,9 @@ impl u8 {
 
     /// Checks if the value is an ASCII hexadecimal digit:
     ///
-    /// - U+0030 '0' ... U+0039 '9', or
-    /// - U+0041 'A' ... U+0046 'F', or
-    /// - U+0061 'a' ... U+0066 'f'.
+    /// - U+0030 '0' ..= U+0039 '9', or
+    /// - U+0041 'A' ..= U+0046 'F', or
+    /// - U+0061 'a' ..= U+0066 'f'.
     ///
     /// # Examples
     ///
@@ -4389,10 +4404,10 @@ impl u8 {
 
     /// Checks if the value is an ASCII punctuation character:
     ///
-    /// - U+0021 ... U+002F `! " # $ % & ' ( ) * + , - . /`, or
-    /// - U+003A ... U+0040 `: ; < = > ? @`, or
-    /// - U+005B ... U+0060 ``[ \ ] ^ _ ` ``, or
-    /// - U+007B ... U+007E `{ | } ~`
+    /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
+    /// - U+003A ..= U+0040 `: ; < = > ? @`, or
+    /// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
+    /// - U+007B ..= U+007E `{ | } ~`
     ///
     /// # Examples
     ///
@@ -4427,7 +4442,7 @@ impl u8 {
     }
 
     /// Checks if the value is an ASCII graphic character:
-    /// U+0021 '!' ... U+007E '~'.
+    /// U+0021 '!' ..= U+007E '~'.
     ///
     /// # Examples
     ///
@@ -4514,7 +4529,7 @@ impl u8 {
     }
 
     /// Checks if the value is an ASCII control character:
-    /// U+0000 NUL ... U+001F UNIT SEPARATOR, or U+007F DELETE.
+    /// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
     /// Note that most ASCII whitespace characters are control
     /// characters, but SPACE is not.
     ///
diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs
index a3491bc3dc6..fd129a306d1 100644
--- a/src/libcore/num/wrapping.rs
+++ b/src/libcore/num/wrapping.rs
@@ -511,7 +511,6 @@ assert_eq!(n.trailing_zeros(), 3);
             /// Basic usage:
             ///
             /// ```
-            /// #![feature(reverse_bits)]
             /// use std::num::Wrapping;
             ///
             /// let n = Wrapping(0b0000000_01010101i16);
@@ -522,8 +521,9 @@ assert_eq!(n.trailing_zeros(), 3);
             /// assert_eq!(m.0 as u16, 0b10101010_00000000);
             /// assert_eq!(m, Wrapping(-22016));
             /// ```
-            #[unstable(feature = "reverse_bits", issue = "48763")]
+            #[stable(feature = "reverse_bits", since = "1.37.0")]
             #[inline]
+            #[must_use]
             pub const fn reverse_bits(self) -> Self {
                 Wrapping(self.0.reverse_bits())
             }
diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs
index 8139305f530..3c009d644c6 100644
--- a/src/libcore/ops/arith.rs
+++ b/src/libcore/ops/arith.rs
@@ -508,7 +508,7 @@ div_impl_float! { f32 f64 }
 pub trait Rem<Rhs=Self> {
     /// The resulting type after applying the `%` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
-    type Output = Self;
+    type Output;
 
     /// Performs the `%` operation.
     #[must_use]
diff --git a/src/libcore/ops/deref.rs b/src/libcore/ops/deref.rs
index e44a6c4d2a0..ce0d3fd01f7 100644
--- a/src/libcore/ops/deref.rs
+++ b/src/libcore/ops/deref.rs
@@ -23,9 +23,9 @@
 /// * Values of type `&T` are coerced to values of type `&U`
 /// * `T` implicitly implements all the (immutable) methods of the type `U`.
 ///
-/// For more details, visit [the chapter in *The Rust Programming Language*]
-/// [book] as well as the reference sections on [the dereference operator]
-/// [ref-deref-op], [method resolution] and [type coercions].
+/// For more details, visit [the chapter in *The Rust Programming Language*][book]
+/// as well as the reference sections on [the dereference operator][ref-deref-op],
+/// [method resolution] and [type coercions].
 ///
 /// [book]: ../../book/ch15-02-deref.html
 /// [`DerefMut`]: trait.DerefMut.html
@@ -113,9 +113,9 @@ impl<T: ?Sized> Deref for &mut T {
 /// * Values of type `&mut T` are coerced to values of type `&mut U`
 /// * `T` implicitly implements all the (mutable) methods of the type `U`.
 ///
-/// For more details, visit [the chapter in *The Rust Programming Language*]
-/// [book] as well as the reference sections on [the dereference operator]
-/// [ref-deref-op], [method resolution] and [type coercions].
+/// For more details, visit [the chapter in *The Rust Programming Language*][book]
+/// as well as the reference sections on [the dereference operator][ref-deref-op],
+/// [method resolution] and [type coercions].
 ///
 /// [book]: ../../book/ch15-02-deref.html
 /// [`Deref`]: trait.Deref.html
diff --git a/src/libcore/ops/function.rs b/src/libcore/ops/function.rs
index c69f5fd9896..b9552eaa1a0 100644
--- a/src/libcore/ops/function.rs
+++ b/src/libcore/ops/function.rs
@@ -137,6 +137,10 @@ pub trait Fn<Args> : FnMut<Args> {
 #[rustc_paren_sugar]
 #[rustc_on_unimplemented(
     on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
+    on(
+        all(Args="(char,)", _Self="std::string::String"),
+        note="borrowing the `{Self}` might fix the problem"
+    ),
     message="expected a `{FnMut}<{Args}>` closure, found `{Self}`",
     label="expected an `FnMut<{Args}>` closure, found `{Self}`",
 )]
diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs
index 3158f58e958..9cff474a760 100644
--- a/src/libcore/ops/index.rs
+++ b/src/libcore/ops/index.rs
@@ -105,7 +105,7 @@ pub trait Index<Idx: ?Sized> {
 /// impl Index<Side> for Balance {
 ///     type Output = Weight;
 ///
-///     fn index<'a>(&'a self, index: Side) -> &'a Self::Output {
+///     fn index(&self, index: Side) -> &Self::Output {
 ///         println!("Accessing {:?}-side of balance immutably", index);
 ///         match index {
 ///             Side::Left => &self.left,
@@ -115,7 +115,7 @@ pub trait Index<Idx: ?Sized> {
 /// }
 ///
 /// impl IndexMut<Side> for Balance {
-///     fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Self::Output {
+///     fn index_mut(&mut self, index: Side) -> &mut Self::Output {
 ///         println!("Accessing {:?}-side of balance mutably", index);
 ///         match index {
 ///             Side::Left => &mut self.left,
diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs
index a707f0cc062..1b4c4218cc1 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -696,6 +696,29 @@ pub enum Bound<T> {
     Unbounded,
 }
 
+impl<T: Clone> Bound<&T> {
+    /// Map a `Bound<&T>` to a `Bound<T>` by cloning the contents of the bound.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(bound_cloned)]
+    /// use std::ops::Bound::*;
+    /// use std::ops::RangeBounds;
+    ///
+    /// assert_eq!((1..12).start_bound(), Included(&1));
+    /// assert_eq!((1..12).start_bound().cloned(), Included(1));
+    /// ```
+    #[unstable(feature = "bound_cloned", issue = "61356")]
+    pub fn cloned(self) -> Bound<T> {
+        match self {
+            Bound::Unbounded => Bound::Unbounded,
+            Bound::Included(x) => Bound::Included(x.clone()),
+            Bound::Excluded(x) => Bound::Excluded(x.clone()),
+        }
+    }
+}
+
 #[stable(feature = "collections_range", since = "1.28.0")]
 /// `RangeBounds` is implemented by Rust's built-in range types, produced
 /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
diff --git a/src/libcore/ops/try.rs b/src/libcore/ops/try.rs
index 9fa2c81954e..76fec1020f1 100644
--- a/src/libcore/ops/try.rs
+++ b/src/libcore/ops/try.rs
@@ -8,12 +8,12 @@
 #[rustc_on_unimplemented(
    on(all(
        any(from_method="from_error", from_method="from_ok"),
-       from_desugaring="?"),
+       from_desugaring="QuestionMark"),
       message="the `?` operator can only be used in a \
                function that returns `Result` or `Option` \
                (or another type that implements `{Try}`)",
       label="cannot use the `?` operator in a function that returns `{Self}`"),
-   on(all(from_method="into_result", from_desugaring="?"),
+   on(all(from_method="into_result", from_desugaring="QuestionMark"),
       message="the `?` operator can only be applied to values \
                that implement `{Try}`",
       label="the `?` operator cannot be applied to type `{Self}`")
diff --git a/src/libcore/ops/unsize.rs b/src/libcore/ops/unsize.rs
index 7f81481ab5b..8e468300846 100644
--- a/src/libcore/ops/unsize.rs
+++ b/src/libcore/ops/unsize.rs
@@ -71,7 +71,7 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
 
 /// This is used for object safety, to check that a method's receiver type can be dispatched on.
 ///
-/// example impl:
+/// An example implementation of the trait:
 ///
 /// ```
 /// # #![feature(dispatch_from_dyn, unsize)]
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 6b7f491effb..259ed36c578 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -8,7 +8,7 @@
 //! * Initial values
 //! * Return values for functions that are not defined
 //!   over their entire input range (partial functions)
-//! * Return value for otherwise reporting simple errors, where `None` is
+//! * Return value for otherwise reporting simple errors, where [`None`] is
 //!   returned on error
 //! * Optional struct fields
 //! * Struct fields that can be loaned or "taken"
@@ -136,7 +136,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::iter::{FromIterator, FusedIterator, TrustedLen};
-use crate::{convert, hint, mem, ops::{self, Deref}};
+use crate::{convert, fmt, hint, mem, ops::{self, Deref, DerefMut}};
 use crate::pin::Pin;
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
@@ -145,7 +145,7 @@ use crate::pin::Pin;
 // which basically means it must be `Option`.
 
 /// The `Option` type. See [the module level documentation](index.html) for more.
-#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
+#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Option<T> {
     /// No value
@@ -178,7 +178,7 @@ impl<T> Option<T> {
     /// ```
     ///
     /// [`Some`]: #variant.Some
-    #[must_use]
+    #[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_some(&self) -> bool {
@@ -201,13 +201,40 @@ impl<T> Option<T> {
     /// ```
     ///
     /// [`None`]: #variant.None
-    #[must_use]
+    #[must_use = "if you intended to assert that this doesn't have a value, consider \
+                  `.and_then(|| panic!(\"`Option` had a value when expected `None`\"))` instead"]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_none(&self) -> bool {
         !self.is_some()
     }
 
+    /// Returns `true` if the option is a [`Some`] value containing the given value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(option_result_contains)]
+    ///
+    /// let x: Option<u32> = Some(2);
+    /// assert_eq!(x.contains(&2), true);
+    ///
+    /// let x: Option<u32> = Some(3);
+    /// assert_eq!(x.contains(&2), false);
+    ///
+    /// let x: Option<u32> = None;
+    /// assert_eq!(x.contains(&2), false);
+    /// ```
+    #[must_use]
+    #[inline]
+    #[unstable(feature = "option_result_contains", issue = "62358")]
+    pub fn contains<U>(&self, x: &U) -> bool where U: PartialEq<T> {
+        match self {
+            Some(y) => x == y,
+            None => false,
+        }
+    }
+
     /////////////////////////////////////////////////////////////////////////
     // Adapter for working with references
     /////////////////////////////////////////////////////////////////////////
@@ -263,7 +290,9 @@ impl<T> Option<T> {
     }
 
 
-    /// Converts from `Pin<&Option<T>>` to `Option<Pin<&T>>`
+    /// Converts from [`Pin`]`<&Option<T>>` to `Option<`[`Pin`]`<&T>>`.
+    ///
+    /// [`Pin`]: ../pin/struct.Pin.html
     #[inline]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_ref<'a>(self: Pin<&'a Option<T>>) -> Option<Pin<&'a T>> {
@@ -272,7 +301,9 @@ impl<T> Option<T> {
         }
     }
 
-    /// Converts from `Pin<&mut Option<T>>` to `Option<Pin<&mut T>>`
+    /// Converts from [`Pin`]`<&mut Option<T>>` to `Option<`[`Pin`]`<&mut T>>`.
+    ///
+    /// [`Pin`]: ../pin/struct.Pin.html
     #[inline]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_mut<'a>(self: Pin<&'a mut Option<T>>) -> Option<Pin<&'a mut T>> {
@@ -626,14 +657,14 @@ impl<T> Option<T> {
         }
     }
 
-    /// Returns `None` if the option is `None`, otherwise calls `predicate`
+    /// Returns [`None`] if the option is [`None`], otherwise calls `predicate`
     /// with the wrapped value and returns:
     ///
-    /// - `Some(t)` if `predicate` returns `true` (where `t` is the wrapped
+    /// - [`Some(t)`] if `predicate` returns `true` (where `t` is the wrapped
     ///   value), and
-    /// - `None` if `predicate` returns `false`.
+    /// - [`None`] if `predicate` returns `false`.
     ///
-    /// This function works similar to `Iterator::filter()`. You can imagine
+    /// This function works similar to [`Iterator::filter()`]. You can imagine
     /// the `Option<T>` being an iterator over one or zero elements. `filter()`
     /// lets you decide which elements to keep.
     ///
@@ -648,6 +679,10 @@ impl<T> Option<T> {
     /// assert_eq!(Some(3).filter(is_even), None);
     /// assert_eq!(Some(4).filter(is_even), Some(4));
     /// ```
+    ///
+    /// [`None`]: #variant.None
+    /// [`Some(t)`]: #variant.Some
+    /// [`Iterator::filter()`]: ../../std/iter/trait.Iterator.html#method.filter
     #[inline]
     #[stable(feature = "option_filter", since = "1.27.0")]
     pub fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Self {
@@ -717,7 +752,7 @@ impl<T> Option<T> {
         }
     }
 
-    /// Returns [`Some`] if exactly one of `self`, `optb` is [`Some`], otherwise returns `None`.
+    /// Returns [`Some`] if exactly one of `self`, `optb` is [`Some`], otherwise returns [`None`].
     ///
     /// [`Some`]: #variant.Some
     /// [`None`]: #variant.None
@@ -725,8 +760,6 @@ impl<T> Option<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(option_xor)]
-    ///
     /// let x = Some(2);
     /// let y: Option<u32> = None;
     /// assert_eq!(x.xor(y), Some(2));
@@ -744,7 +777,7 @@ impl<T> Option<T> {
     /// assert_eq!(x.xor(y), None);
     /// ```
     #[inline]
-    #[unstable(feature = "option_xor", issue = "50512")]
+    #[stable(feature = "option_xor", since = "1.37.0")]
     pub fn xor(self, optb: Option<T>) -> Option<T> {
         match (self, optb) {
             (Some(a), None) => Some(a),
@@ -779,15 +812,7 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "option_entry", since = "1.20.0")]
     pub fn get_or_insert(&mut self, v: T) -> &mut T {
-        match *self {
-            None => *self = Some(v),
-            _ => (),
-        }
-
-        match *self {
-            Some(ref mut v) => v,
-            None => unsafe { hint::unreachable_unchecked() },
-        }
+        self.get_or_insert_with(|| v)
     }
 
     /// Inserts a value computed from `f` into the option if it is [`None`], then
@@ -847,7 +872,7 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn take(&mut self) -> Option<T> {
-        mem::replace(self, None)
+        mem::take(self)
     }
 
     /// Replaces the actual value in the option by the value given in parameter,
@@ -952,6 +977,92 @@ impl<T: Clone> Option<&mut T> {
     }
 }
 
+impl<T: fmt::Debug> Option<T> {
+    /// Unwraps an option, expecting [`None`] and returning nothing.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the value is a [`Some`], with a panic message including the
+    /// passed message, and the content of the [`Some`].
+    ///
+    /// [`Some`]: #variant.Some
+    /// [`None`]: #variant.None
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(option_expect_none)]
+    ///
+    /// use std::collections::HashMap;
+    /// let mut squares = HashMap::new();
+    /// for i in -10..=10 {
+    ///     // This will not panic, since all keys are unique.
+    ///     squares.insert(i, i * i).expect_none("duplicate key");
+    /// }
+    /// ```
+    ///
+    /// ```{.should_panic}
+    /// #![feature(option_expect_none)]
+    ///
+    /// use std::collections::HashMap;
+    /// let mut sqrts = HashMap::new();
+    /// for i in -10..=10 {
+    ///     // This will panic, since both negative and positive `i` will
+    ///     // insert the same `i * i` key, returning the old `Some(i)`.
+    ///     sqrts.insert(i * i, i).expect_none("duplicate key");
+    /// }
+    /// ```
+    #[inline]
+    #[unstable(feature = "option_expect_none", reason = "newly added", issue = "62633")]
+    pub fn expect_none(self, msg: &str) {
+        if let Some(val) = self {
+            expect_none_failed(msg, &val);
+        }
+    }
+
+    /// Unwraps an option, expecting [`None`] and returning nothing.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the value is a [`Some`], with a custom panic message provided
+    /// by the [`Some`]'s value.
+    ///
+    /// [`Some(v)`]: #variant.Some
+    /// [`None`]: #variant.None
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(option_unwrap_none)]
+    ///
+    /// use std::collections::HashMap;
+    /// let mut squares = HashMap::new();
+    /// for i in -10..=10 {
+    ///     // This will not panic, since all keys are unique.
+    ///     squares.insert(i, i * i).unwrap_none();
+    /// }
+    /// ```
+    ///
+    /// ```{.should_panic}
+    /// #![feature(option_unwrap_none)]
+    ///
+    /// use std::collections::HashMap;
+    /// let mut sqrts = HashMap::new();
+    /// for i in -10..=10 {
+    ///     // This will panic, since both negative and positive `i` will
+    ///     // insert the same `i * i` key, returning the old `Some(i)`.
+    ///     sqrts.insert(i * i, i).unwrap_none();
+    /// }
+    /// ```
+    #[inline]
+    #[unstable(feature = "option_unwrap_none", reason = "newly added", issue = "62633")]
+    pub fn unwrap_none(self) {
+        if let Some(val) = self {
+            expect_none_failed("called `Option::unwrap_none()` on a `Some` value", &val);
+        }
+    }
+}
+
 impl<T: Default> Option<T> {
     /// Returns the contained value or a default
     ///
@@ -993,20 +1104,39 @@ impl<T: Default> Option<T> {
 
 #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T: Deref> Option<T> {
-    /// Converts from `&Option<T>` to `Option<&T::Target>`.
+    /// Converts from `Option<T>` (or `&Option<T>`) to `Option<&T::Target>`.
     ///
     /// Leaves the original Option in-place, creating a new one with a reference
-    /// to the original one, additionally coercing the contents via `Deref`.
-    pub fn deref(&self) -> Option<&T::Target> {
+    /// to the original one, additionally coercing the contents via [`Deref`].
+    ///
+    /// [`Deref`]: ../../std/ops/trait.Deref.html
+    pub fn as_deref(&self) -> Option<&T::Target> {
         self.as_ref().map(|t| t.deref())
     }
 }
 
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T: DerefMut> Option<T> {
+    /// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
+    ///
+    /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
+    /// the inner type's `Deref::Target` type.
+    pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> {
+        self.as_mut().map(|t| t.deref_mut())
+    }
+}
+
 impl<T, E> Option<Result<T, E>> {
-    /// Transposes an `Option` of a `Result` into a `Result` of an `Option`.
+    /// Transposes an `Option` of a [`Result`] into a [`Result`] of an `Option`.
     ///
-    /// `None` will be mapped to `Ok(None)`.
-    /// `Some(Ok(_))` and `Some(Err(_))` will be mapped to `Ok(Some(_))` and `Err(_)`.
+    /// [`None`] will be mapped to [`Ok`]`(`[`None`]`)`.
+    /// [`Some`]`(`[`Ok`]`(_))` and [`Some`]`(`[`Err`]`(_))` will be mapped to
+    /// [`Ok`]`(`[`Some`]`(_))` and [`Err`]`(_)`.
+    ///
+    /// [`None`]: #variant.None
+    /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
+    /// [`Some`]: #variant.Some
+    /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
     ///
     /// # Examples
     ///
@@ -1036,11 +1166,37 @@ fn expect_failed(msg: &str) -> ! {
     panic!("{}", msg)
 }
 
+// This is a separate function to reduce the code size of .expect_none() itself.
+#[inline(never)]
+#[cold]
+fn expect_none_failed(msg: &str, value: &dyn fmt::Debug) -> ! {
+    panic!("{}: {:?}", msg, value)
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // Trait implementations
 /////////////////////////////////////////////////////////////////////////////
 
 #[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Clone> Clone for Option<T> {
+    #[inline]
+    fn clone(&self) -> Self {
+        match self {
+            Some(x) => Some(x.clone()),
+            None => None,
+        }
+    }
+
+    #[inline]
+    fn clone_from(&mut self, source: &Self) {
+        match (self, source) {
+            (Some(to), Some(from)) => to.clone_from(from),
+            (to, from) => *to = from.clone(),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Default for Option<T> {
     /// Returns [`None`][Option::None].
     #[inline]
@@ -1343,45 +1499,10 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
         // FIXME(#11084): This could be replaced with Iterator::scan when this
         // performance bug is closed.
 
-        struct Adapter<Iter> {
-            iter: Iter,
-            found_none: bool,
-        }
-
-        impl<T, Iter: Iterator<Item=Option<T>>> Iterator for Adapter<Iter> {
-            type Item = T;
-
-            #[inline]
-            fn next(&mut self) -> Option<T> {
-                match self.iter.next() {
-                    Some(Some(value)) => Some(value),
-                    Some(None) => {
-                        self.found_none = true;
-                        None
-                    }
-                    None => None,
-                }
-            }
-
-            #[inline]
-            fn size_hint(&self) -> (usize, Option<usize>) {
-                if self.found_none {
-                    (0, Some(0))
-                } else {
-                    let (_, upper) = self.iter.size_hint();
-                    (0, upper)
-                }
-            }
-        }
-
-        let mut adapter = Adapter { iter: iter.into_iter(), found_none: false };
-        let v: V = FromIterator::from_iter(adapter.by_ref());
-
-        if adapter.found_none {
-            None
-        } else {
-            Some(v)
-        }
+        iter.into_iter()
+            .map(|x| x.ok_or(()))
+            .collect::<Result<_, _>>()
+            .ok()
     }
 }
 
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index 4ced860948b..6efeaf9ee7d 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -1,23 +1,24 @@
 //! Types that pin data to its location in memory.
 //!
-//! It is sometimes useful to have objects that are guaranteed to not move,
+//! It is sometimes useful to have objects that are guaranteed not to move,
 //! in the sense that their placement in memory does not change, and can thus be relied upon.
 //! A prime example of such a scenario would be building self-referential structs,
-//! since moving an object with pointers to itself will invalidate them,
-//! which could cause undefined behavior.
+//! as moving an object with pointers to itself will invalidate them, which could cause undefined
+//! behavior.
 //!
 //! A [`Pin<P>`] ensures that the pointee of any pointer type `P` has a stable location in memory,
 //! meaning it cannot be moved elsewhere and its memory cannot be deallocated
 //! until it gets dropped. We say that the pointee is "pinned".
 //!
 //! By default, all types in Rust are movable. Rust allows passing all types by-value,
-//! and common smart-pointer types such as `Box<T>` and `&mut T` allow replacing and
-//! moving the values they contain: you can move out of a `Box<T>`, or you can use [`mem::swap`].
-//! [`Pin<P>`] wraps a pointer type `P`, so `Pin<Box<T>>` functions much like a regular `Box<T>`:
-//! when a `Pin<Box<T>>` gets dropped, so do its contents, and the memory gets deallocated.
-//! Similarily, `Pin<&mut T>` is a lot like `&mut T`. However, [`Pin<P>`] does not let clients
-//! actually obtain a `Box<T>` or `&mut T` to pinned data, which implies that you cannot use
-//! operations such as [`mem::swap`]:
+//! and common smart-pointer types such as [`Box<T>`] and `&mut T` allow replacing and
+//! moving the values they contain: you can move out of a [`Box<T>`], or you can use [`mem::swap`].
+//! [`Pin<P>`] wraps a pointer type `P`, so [`Pin`]`<`[`Box`]`<T>>` functions much like a regular
+//! [`Box<T>`]: when a [`Pin`]`<`[`Box`]`<T>>` gets dropped, so do its contents, and the memory gets
+//! deallocated. Similarly, [`Pin`]`<&mut T>` is a lot like `&mut T`. However, [`Pin<P>`] does
+//! not let clients actually obtain a [`Box<T>`] or `&mut T` to pinned data, which implies that you
+//! cannot use operations such as [`mem::swap`]:
+//!
 //! ```
 //! use std::pin::Pin;
 //! fn swap_pins<T>(x: Pin<&mut T>, y: Pin<&mut T>) {
@@ -29,33 +30,33 @@
 //! ```
 //!
 //! It is worth reiterating that [`Pin<P>`] does *not* change the fact that a Rust compiler
-//! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, `Pin<P>`
-//! prevents certain *values* (pointed to by pointers wrapped in `Pin<P>`) from being
+//! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, [`Pin<P>`]
+//! prevents certain *values* (pointed to by pointers wrapped in [`Pin<P>`]) from being
 //! moved by making it impossible to call methods that require `&mut T` on them
 //! (like [`mem::swap`]).
 //!
 //! [`Pin<P>`] can be used to wrap any pointer type `P`, and as such it interacts with
-//! [`Deref`] and [`DerefMut`]. A `Pin<P>` where `P: Deref` should be considered
-//! as a "`P`-style pointer" to a pinned `P::Target` -- so, a `Pin<Box<T>>` is
-//! an owned pointer to a pinned `T`, and a `Pin<Rc<T>>` is a reference-counted
+//! [`Deref`] and [`DerefMut`]. A [`Pin<P>`] where `P: Deref` should be considered
+//! as a "`P`-style pointer" to a pinned `P::Target` -- so, a [`Pin`]`<`[`Box`]`<T>>` is
+//! an owned pointer to a pinned `T`, and a [`Pin`]`<`[`Rc`]`<T>>` is a reference-counted
 //! pointer to a pinned `T`.
-//! For correctness, [`Pin<P>`] relies on the [`Deref`] and [`DerefMut`] implementations
-//! to not move out of their `self` parameter, and to only ever return a pointer
-//! to pinned data when they are called on a pinned pointer.
+//! For correctness, [`Pin<P>`] relies on the implementations of [`Deref`] and
+//! [`DerefMut`] not to move out of their `self` parameter, and only ever to
+//! return a pointer to pinned data when they are called on a pinned pointer.
 //!
 //! # `Unpin`
 //!
-//! However, these restrictions are usually not necessary. Many types are always freely
-//! movable, even when pinned, because they do not rely on having a stable address.
-//! This includes all the basic types (like `bool`, `i32`, references)
-//! as well as types consisting solely of these types.
-//! Types that do not care about pinning implement the [`Unpin`] auto-trait, which
-//! cancels the effect of [`Pin<P>`]. For `T: Unpin`, `Pin<Box<T>>` and `Box<T>` function
-//! identically, as do `Pin<&mut T>` and `&mut T`.
-//!
-//! Note that pinning and `Unpin` only affect the pointed-to type `P::Target`, not the pointer
-//! type `P` itself that got wrapped in `Pin<P>`. For example, whether or not `Box<T>` is
-//! `Unpin` has no effect on the behavior of `Pin<Box<T>>` (here, `T` is the
+//! Many types are always freely movable, even when pinned, because they do not
+//! rely on having a stable address. This includes all the basic types (like
+//! [`bool`], [`i32`], and references) as well as types consisting solely of these
+//! types. Types that do not care about pinning implement the [`Unpin`]
+//! auto-trait, which cancels the effect of [`Pin<P>`]. For `T: Unpin`,
+//! [`Pin`]`<`[`Box`]`<T>>` and [`Box<T>`] function identically, as do [`Pin`]`<&mut T>` and
+//! `&mut T`.
+//!
+//! Note that pinning and [`Unpin`] only affect the pointed-to type `P::Target`, not the pointer
+//! type `P` itself that got wrapped in [`Pin<P>`]. For example, whether or not [`Box<T>`] is
+//! [`Unpin`] has no effect on the behavior of [`Pin`]`<`[`Box`]`<T>>` (here, `T` is the
 //! pointed-to type).
 //!
 //! # Example: self-referential struct
@@ -65,11 +66,11 @@
 //! use std::marker::PhantomPinned;
 //! use std::ptr::NonNull;
 //!
-//! // This is a self-referential struct since the slice field points to the data field.
+//! // This is a self-referential struct because the slice field points to the data field.
 //! // We cannot inform the compiler about that with a normal reference,
-//! // since this pattern cannot be described with the usual borrowing rules.
-//! // Instead we use a raw pointer, though one which is known to not be null,
-//! // since we know it's pointing at the string.
+//! // as this pattern cannot be described with the usual borrowing rules.
+//! // Instead we use a raw pointer, though one which is known not to be null,
+//! // as we know it's pointing at the string.
 //! struct Unmovable {
 //!     data: String,
 //!     slice: NonNull<String>,
@@ -121,15 +122,15 @@
 //!
 //! To make this work, every element has pointers to its predecessor and successor in
 //! the list. Elements can only be added when they are pinned, because moving the elements
-//! around would invalidate the pointers. Moreover, the `Drop` implementation of a linked
+//! around would invalidate the pointers. Moreover, the [`Drop`] implementation of a linked
 //! list element will patch the pointers of its predecessor and successor to remove itself
 //! from the list.
 //!
-//! Crucially, we have to be able to rely on `drop` being called. If an element
-//! could be deallocated or otherwise invalidated without calling `drop`, the pointers into it
+//! Crucially, we have to be able to rely on [`drop`] being called. If an element
+//! could be deallocated or otherwise invalidated without calling [`drop`], the pointers into it
 //! from its neighbouring elements would become invalid, which would break the data structure.
 //!
-//! Therefore, pinning also comes with a `drop`-related guarantee.
+//! Therefore, pinning also comes with a [`drop`]-related guarantee.
 //!
 //! # `Drop` guarantee
 //!
@@ -137,85 +138,164 @@
 //! To make this work, not just moving the data is restricted; deallocating, repurposing, or
 //! otherwise invalidating the memory used to store the data is restricted, too.
 //! Concretely, for pinned data you have to maintain the invariant
-//! that *its memory will not get invalidated from the moment it gets pinned until
-//! when `drop` is called*. Memory can be invalidated by deallocation, but also by
+//! that *its memory will not get invalidated or repurposed from the moment it gets pinned until
+//! when [`drop`] is called*. Memory can be invalidated by deallocation, but also by
 //! replacing a [`Some(v)`] by [`None`], or calling [`Vec::set_len`] to "kill" some elements
-//! off of a vector.
+//! off of a vector. It can be repurposed by using [`ptr::write`] to overwrite it without
+//! calling the destructor first.
 //!
 //! This is exactly the kind of guarantee that the intrusive linked list from the previous
 //! section needs to function correctly.
 //!
 //! Notice that this guarantee does *not* mean that memory does not leak! It is still
-//! completely okay not to ever call `drop` on a pinned element (e.g., you can still
-//! call [`mem::forget`] on a `Pin<Box<T>>`). In the example of the doubly-linked
+//! completely okay not ever to call [`drop`] on a pinned element (e.g., you can still
+//! call [`mem::forget`] on a [`Pin`]`<`[`Box`]`<T>>`). In the example of the doubly-linked
 //! list, that element would just stay in the list. However you may not free or reuse the storage
-//! *without calling `drop`*.
+//! *without calling [`drop`]*.
 //!
 //! # `Drop` implementation
 //!
 //! If your type uses pinning (such as the two examples above), you have to be careful
-//! when implementing `Drop`. The `drop` function takes `&mut self`, but this
+//! when implementing [`Drop`]. The [`drop`] function takes `&mut self`, but this
 //! is called *even if your type was previously pinned*! It is as if the
-//! compiler automatically called `get_unchecked_mut`.
+//! compiler automatically called [`Pin::get_unchecked_mut`].
 //!
 //! This can never cause a problem in safe code because implementing a type that
 //! relies on pinning requires unsafe code, but be aware that deciding to make
 //! use of pinning in your type (for example by implementing some operation on
-//! `Pin<&Self>` or `Pin<&mut Self>`) has consequences for your `Drop`
+//! [`Pin`]`<&Self>` or [`Pin`]`<&mut Self>`) has consequences for your [`Drop`]
 //! implementation as well: if an element of your type could have been pinned,
-//! you must treat Drop as implicitly taking `Pin<&mut Self>`.
+//! you must treat [`Drop`] as implicitly taking [`Pin`]`<&mut Self>`.
+//!
+//! For example, you could implement `Drop` as follows:
+//!
+//! ```rust,no_run
+//! # use std::pin::Pin;
+//! # struct Type { }
+//! impl Drop for Type {
+//!     fn drop(&mut self) {
+//!         // `new_unchecked` is okay because we know this value is never used
+//!         // again after being dropped.
+//!         inner_drop(unsafe { Pin::new_unchecked(self)});
+//!         fn inner_drop(this: Pin<&mut Type>) {
+//!             // Actual drop code goes here.
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! The function `inner_drop` has the type that [`drop`] *should* have, so this makes sure that
+//! you do not accidentally use `self`/`this` in a way that is in conflict with pinning.
 //!
-//! In particular, if your type is `#[repr(packed)]`, the compiler will automatically
-//! move fields around to be able to drop them. As a consequence, you cannot use
+//! Moreover, if your type is `#[repr(packed)]`, the compiler will automatically
+//! move fields around to be able to drop them. It might even do
+//! that for fields that happen to be sufficiently aligned. As a consequence, you cannot use
 //! pinning with a `#[repr(packed)]` type.
 //!
 //! # Projections and Structural Pinning
 //!
-//! One interesting question arises when considering the interaction of pinning
-//! and the fields of a struct. When can a struct have a "pinning projection",
-//! i.e., an operation with type `fn(Pin<&Struct>) -> Pin<&Field>`?  In a
-//! similar vein, when can a generic wrapper type (such as `Vec<T>`, `Box<T>`,
-//! or `RefCell<T>`) have an operation with type `fn(Pin<&Wrapper<T>>) ->
-//! Pin<&T>`?
+//! When working with pinned structs, the question arises how one can access the
+//! fields of that struct in a method that takes just [`Pin`]`<&mut Struct>`.
+//! The usual approach is to write helper methods (so called *projections*)
+//! that turn [`Pin`]`<&mut Struct>` into a reference to the field, but what
+//! type should that reference have? Is it [`Pin`]`<&mut Field>` or `&mut Field`?
+//! The same question arises with the fields of an `enum`, and also when considering
+//! container/wrapper types such as [`Vec<T>`], [`Box<T>`], or [`RefCell<T>`].
+//! (This question applies to both mutable and shared references, we just
+//! use the more common case of mutable references here for illustration.)
+//!
+//! It turns out that it is actually up to the author of the data structure
+//! to decide whether the pinned projection for a particular field turns
+//! [`Pin`]`<&mut Struct>` into [`Pin`]`<&mut Field>` or `&mut Field`. There are some
+//! constraints though, and the most important constraint is *consistency*:
+//! every field can be *either* projected to a pinned reference, *or* have
+//! pinning removed as part of the projection. If both are done for the same field,
+//! that will likely be unsound!
+//!
+//! As the author of a data structure you get to decide for each field whether pinning
+//! "propagates" to this field or not. Pinning that propagates is also called "structural",
+//! because it follows the structure of the type.
+//! In the following subsections, we describe the considerations that have to be made
+//! for either choice.
+//!
+//! ## Pinning *is not* structural for `field`
+//!
+//! It may seem counter-intuitive that the field of a pinned struct might not be pinned,
+//! but that is actually the easiest choice: if a [`Pin`]`<&mut Field>` is never created,
+//! nothing can go wrong! So, if you decide that some field does not have structural pinning,
+//! all you have to ensure is that you never create a pinned reference to that field.
+//!
+//! Fields without structural pinning may have a projection method that turns
+//! [`Pin`]`<&mut Struct>` into `&mut Field`:
+//!
+//! ```rust,no_run
+//! # use std::pin::Pin;
+//! # type Field = i32;
+//! # struct Struct { field: Field }
+//! impl Struct {
+//!     fn pin_get_field<'a>(self: Pin<&'a mut Self>) -> &'a mut Field {
+//!         // This is okay because `field` is never considered pinned.
+//!         unsafe { &mut self.get_unchecked_mut().field }
+//!     }
+//! }
+//! ```
 //!
-//! Note: For the entirety of this discussion, the same applies for mutable references as it
-//! does for shared references.
+//! You may also `impl Unpin for Struct` *even if* the type of `field`
+//! is not [`Unpin`]. What that type thinks about pinning is not relevant
+//! when no [`Pin`]`<&mut Field>` is ever created.
 //!
-//! Having a pinning projection for some field means that pinning is "structural":
-//! when the wrapper is pinned, the field must be considered pinned, too.
-//! After all, the pinning projection lets us get a `Pin<&Field>`.
+//! ## Pinning *is* structural for `field`
 //!
-//! However, structural pinning comes with a few extra requirements, so not all
-//! wrappers can be structural and hence not all wrappers can offer pinning projections:
+//! The other option is to decide that pinning is "structural" for `field`,
+//! meaning that if the struct is pinned then so is the field.
 //!
-//! 1.  The wrapper must only be [`Unpin`] if all the structural fields are
-//!     `Unpin`. This is the default, but `Unpin` is a safe trait, so as the author of
-//!     the wrapper it is your responsibility *not* to add something like
-//!     `impl<T> Unpin for Wrapper<T>`. (Notice that adding a projection operation
-//!     requires unsafe code, so the fact that `Unpin` is a safe trait  does not break
+//! This allows writing a projection that creates a [`Pin`]`<&mut Field>`, thus
+//! witnessing that the field is pinned:
+//!
+//! ```rust,no_run
+//! # use std::pin::Pin;
+//! # type Field = i32;
+//! # struct Struct { field: Field }
+//! impl Struct {
+//!     fn pin_get_field<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut Field> {
+//!         // This is okay because `field` is pinned when `self` is.
+//!         unsafe { self.map_unchecked_mut(|s| &mut s.field) }
+//!     }
+//! }
+//! ```
+//!
+//! However, structural pinning comes with a few extra requirements:
+//!
+//! 1.  The struct must only be [`Unpin`] if all the structural fields are
+//!     [`Unpin`]. This is the default, but [`Unpin`] is a safe trait, so as the author of
+//!     the struct it is your responsibility *not* to add something like
+//!     `impl<T> Unpin for Struct<T>`. (Notice that adding a projection operation
+//!     requires unsafe code, so the fact that [`Unpin`] is a safe trait does not break
 //!     the principle that you only have to worry about any of this if you use `unsafe`.)
-//! 2.  The destructor of the wrapper must not move structural fields out of its argument. This
+//! 2.  The destructor of the struct must not move structural fields out of its argument. This
 //!     is the exact point that was raised in the [previous section][drop-impl]: `drop` takes
-//!     `&mut self`, but the wrapper (and hence its fields) might have been pinned before.
-//!     You have to guarantee that you do not move a field inside your `Drop` implementation.
-//!     In particular, as explained previously, this means that your wrapper type must *not*
+//!     `&mut self`, but the struct (and hence its fields) might have been pinned before.
+//!     You have to guarantee that you do not move a field inside your [`Drop`] implementation.
+//!     In particular, as explained previously, this means that your struct must *not*
 //!     be `#[repr(packed)]`.
+//!     See that section for how to write [`drop`] in a way that the compiler can help you
+//!     not accidentally break pinning.
 //! 3.  You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]:
-//!     once your wrapper is pinned, the memory that contains the
+//!     once your struct is pinned, the memory that contains the
 //!     content is not overwritten or deallocated without calling the content's destructors.
-//!     This can be tricky, as witnessed by `VecDeque<T>`: the destructor of `VecDeque<T>` can fail
-//!     to call `drop` on all elements if one of the destructors panics. This violates the
-//!     `Drop` guarantee, because it can lead to elements being deallocated without
-//!     their destructor being called. (`VecDeque` has no pinning projections, so this
+//!     This can be tricky, as witnessed by [`VecDeque<T>`]: the destructor of [`VecDeque<T>`]
+//!     can fail to call [`drop`] on all elements if one of the destructors panics. This violates
+//!     the [`Drop`] guarantee, because it can lead to elements being deallocated without
+//!     their destructor being called. ([`VecDeque<T>`] has no pinning projections, so this
 //!     does not cause unsoundness.)
 //! 4.  You must not offer any other operations that could lead to data being moved out of
-//!     the fields when your type is pinned. For example, if the wrapper contains an
-//!     `Option<T>` and there is a `take`-like operation with type
-//!     `fn(Pin<&mut Wrapper<T>>) -> Option<T>`,
-//!     that operation can be used to move a `T` out of a pinned `Wrapper<T>` -- which means
-//!     pinning cannot be structural.
+//!     the structural fields when your type is pinned. For example, if the struct contains an
+//!     [`Option<T>`] and there is a `take`-like operation with type
+//!     `fn(Pin<&mut Struct<T>>) -> Option<T>`,
+//!     that operation can be used to move a `T` out of a pinned `Struct<T>` -- which means
+//!     pinning cannot be structural for the field holding this data.
 //!
-//!     For a more complex example of moving data out of a pinned type, imagine if `RefCell<T>`
+//!     For a more complex example of moving data out of a pinned type, imagine if [`RefCell<T>`]
 //!     had a method `fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>`.
 //!     Then we could do the following:
 //!     ```compile_fail
@@ -226,40 +306,69 @@
 //!         let content = &mut *b; // And here we have `&mut T` to the same data.
 //!     }
 //!     ```
-//!     This is catastrophic, it means we can first pin the content of the `RefCell<T>`
+//!     This is catastrophic, it means we can first pin the content of the [`RefCell<T>`]
 //!     (using `RefCell::get_pin_mut`) and then move that content using the mutable
 //!     reference we got later.
 //!
-//! For a type like `Vec<T>`, both possibilites (structural pinning or not) make sense,
-//! and the choice is up to the author. A `Vec<T>` with structural pinning could
-//! have `get_pin`/`get_pin_mut` projections. However, it could *not* allow calling
-//! `pop` on a pinned `Vec<T>` because that would move the (structurally pinned) contents!
-//! Nor could it allow `push`, which might reallocate and thus also move the contents.
-//! A `Vec<T>` without structural pinning could `impl<T> Unpin for Vec<T>`, because the contents
-//! are never pinned and the `Vec<T>` itself is fine with being moved as well.
+//! ## Examples
+//!
+//! For a type like [`Vec<T>`], both possibilites (structural pinning or not) make sense.
+//! A [`Vec<T>`] with structural pinning could have `get_pin`/`get_pin_mut` methods to get
+//! pinned references to elements. However, it could *not* allow calling
+//! [`pop`][Vec::pop] on a pinned [`Vec<T>`] because that would move the (structurally pinned)
+//! contents! Nor could it allow [`push`][Vec::push], which might reallocate and thus also move the
+//! contents.
+//!
+//! A [`Vec<T>`] without structural pinning could `impl<T> Unpin for Vec<T>`, because the contents
+//! are never pinned and the [`Vec<T>`] itself is fine with being moved as well.
+//! At that point pinning just has no effect on the vector at all.
 //!
 //! In the standard library, pointer types generally do not have structural pinning,
 //! and thus they do not offer pinning projections. This is why `Box<T>: Unpin` holds for all `T`.
 //! It makes sense to do this for pointer types, because moving the `Box<T>`
-//! does not actually move the `T`: the `Box<T>` can be freely movable (aka `Unpin`) even if the `T`
-//! is not. In fact, even `Pin<Box<T>>` and `Pin<&mut T>` are always `Unpin` themselves,
-//! for the same reason: their contents (the `T`) are pinned, but the pointers themselves
-//! can be moved without moving the pinned data. For both `Box<T>` and `Pin<Box<T>>`,
-//! whether the content is pinned is entirely independent of whether the pointer is
-//! pinned, meaning pinning is *not* structural.
+//! does not actually move the `T`: the [`Box<T>`] can be freely movable (aka `Unpin`) even if
+//! the `T` is not. In fact, even [`Pin`]`<`[`Box`]`<T>>` and [`Pin`]`<&mut T>` are always
+//! [`Unpin`] themselves, for the same reason: their contents (the `T`) are pinned, but the
+//! pointers themselves can be moved without moving the pinned data. For both [`Box<T>`] and
+//! [`Pin`]`<`[`Box`]`<T>>`, whether the content is pinned is entirely independent of whether the
+//! pointer is pinned, meaning pinning is *not* structural.
+//!
+//! When implementing a [`Future`] combinator, you will usually need structural pinning
+//! for the nested futures, as you need to get pinned references to them to call [`poll`].
+//! But if your combinator contains any other data that does not need to be pinned,
+//! you can make those fields not structural and hence freely access them with a
+//! mutable reference even when you just have [`Pin`]`<&mut Self>` (such as in your own
+//! [`poll`] implementation).
 //!
 //! [`Pin<P>`]: struct.Pin.html
-//! [`Unpin`]: ../../std/marker/trait.Unpin.html
-//! [`Deref`]: ../../std/ops/trait.Deref.html
-//! [`DerefMut`]: ../../std/ops/trait.DerefMut.html
-//! [`mem::swap`]: ../../std/mem/fn.swap.html
-//! [`mem::forget`]: ../../std/mem/fn.forget.html
+//! [`Unpin`]: ../marker/trait.Unpin.html
+//! [`Deref`]: ../ops/trait.Deref.html
+//! [`DerefMut`]: ../ops/trait.DerefMut.html
+//! [`mem::swap`]: ../mem/fn.swap.html
+//! [`mem::forget`]: ../mem/fn.forget.html
 //! [`Box<T>`]: ../../std/boxed/struct.Box.html
+//! [`Vec<T>`]: ../../std/vec/struct.Vec.html
 //! [`Vec::set_len`]: ../../std/vec/struct.Vec.html#method.set_len
-//! [`None`]: ../../std/option/enum.Option.html#variant.None
-//! [`Some(v)`]: ../../std/option/enum.Option.html#variant.Some
+//! [`Pin`]: struct.Pin.html
+//! [`Box`]: ../../std/boxed/struct.Box.html
+//! [Vec::pop]: ../../std/vec/struct.Vec.html#method.pop
+//! [Vec::push]: ../../std/vec/struct.Vec.html#method.push
+//! [`Rc`]: ../../std/rc/struct.Rc.html
+//! [`RefCell<T>`]: ../../std/cell/struct.RefCell.html
+//! [`Drop`]: ../../std/ops/trait.Drop.html
+//! [`drop`]: ../../std/ops/trait.Drop.html#tymethod.drop
+//! [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html
+//! [`Option<T>`]: ../../std/option/enum.Option.html
+//! [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html
+//! [`RefCell<T>`]: ../cell/struct.RefCell.html
+//! [`None`]: ../option/enum.Option.html#variant.None
+//! [`Some(v)`]: ../option/enum.Option.html#variant.Some
+//! [`ptr::write`]: ../ptr/fn.write.html
+//! [`Future`]: ../future/trait.Future.html
 //! [drop-impl]: #drop-implementation
 //! [drop-guarantee]: #drop-guarantee
+//! [`poll`]: ../../std/future/trait.Future.html#tymethod.poll
+//! [`Pin::get_unchecked_mut`]: struct.Pin.html#method.get_unchecked_mut
 
 #![stable(feature = "pin", since = "1.33.0")]
 
@@ -331,10 +440,7 @@ where
     }
 }
 
-impl<P: Deref> Pin<P>
-where
-    P::Target: Unpin,
-{
+impl<P: Deref<Target: Unpin>> Pin<P> {
     /// Construct a new `Pin<P>` around a pointer to some data of a type that
     /// implements [`Unpin`].
     ///
@@ -622,10 +728,7 @@ impl<P: Deref> Deref for Pin<P> {
 }
 
 #[stable(feature = "pin", since = "1.33.0")]
-impl<P: DerefMut> DerefMut for Pin<P>
-where
-    P::Target: Unpin
-{
+impl<P: DerefMut<Target: Unpin>> DerefMut for Pin<P> {
     fn deref_mut(&mut self) -> &mut P::Target {
         Pin::get_mut(Pin::as_mut(self))
     }
@@ -667,7 +770,7 @@ where
 {}
 
 #[stable(feature = "pin", since = "1.33.0")]
-impl<'a, P, U> DispatchFromDyn<Pin<U>> for Pin<P>
+impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P>
 where
     P: DispatchFromDyn<U>,
 {}
diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs
index 501a41d0d1c..7cc279a9ef2 100644
--- a/src/libcore/prelude/v1.rs
+++ b/src/libcore/prelude/v1.rs
@@ -44,3 +44,49 @@ pub use crate::option::Option::{self, Some, None};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use crate::result::Result::{self, Ok, Err};
+
+// Re-exported built-in macros
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(no_inline)]
+pub use crate::fmt::macros::Debug;
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(no_inline)]
+pub use crate::hash::macros::Hash;
+
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(no_inline)]
+pub use crate::{
+    asm,
+    assert,
+    cfg,
+    column,
+    compile_error,
+    concat,
+    concat_idents,
+    env,
+    file,
+    format_args,
+    format_args_nl,
+    global_asm,
+    include,
+    include_bytes,
+    include_str,
+    line,
+    log_syntax,
+    module_path,
+    option_env,
+    stringify,
+    trace_macros,
+};
+
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow(deprecated)]
+#[doc(no_inline)]
+pub use crate::macros::builtin::{
+    RustcDecodable,
+    RustcEncodable,
+    bench,
+    global_allocator,
+    test,
+    test_case,
+};
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr/mod.rs
index b6de9f57b01..f5fbd1a6b13 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr/mod.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 //! Manually manage memory through raw pointers.
 //!
 //! *[See also the pointer primitive types](../../std/primitive.pointer.html).*
@@ -65,14 +63,10 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use crate::convert::From;
 use crate::intrinsics;
-use crate::ops::{CoerceUnsized, DispatchFromDyn};
 use crate::fmt;
 use crate::hash;
-use crate::marker::{PhantomData, Unsize};
 use crate::mem::{self, MaybeUninit};
-
 use crate::cmp::Ordering::{self, Less, Equal, Greater};
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -84,6 +78,14 @@ pub use crate::intrinsics::copy;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use crate::intrinsics::write_bytes;
 
+mod non_null;
+#[stable(feature = "nonnull", since = "1.25.0")]
+pub use non_null::NonNull;
+
+mod unique;
+#[unstable(feature = "ptr_internals", issue = "0")]
+pub use unique::Unique;
+
 /// Executes the destructor (if any) of the pointed-to value.
 ///
 /// This is semantically equivalent to calling [`ptr::read`] and discarding
@@ -98,7 +100,11 @@ pub use crate::intrinsics::write_bytes;
 ///   as the compiler doesn't need to prove that it's sound to elide the
 ///   copy.
 ///
+/// Unaligned values cannot be dropped in place, they must be copied to an aligned
+/// location first using [`ptr::read_unaligned`].
+///
 /// [`ptr::read`]: ../ptr/fn.read.html
+/// [`ptr::read_unaligned`]: ../ptr/fn.read_unaligned.html
 ///
 /// # Safety
 ///
@@ -106,8 +112,7 @@ pub use crate::intrinsics::write_bytes;
 ///
 /// * `to_drop` must be [valid] for reads.
 ///
-/// * `to_drop` must be properly aligned. See the example below for how to drop
-///   an unaligned pointer.
+/// * `to_drop` must be properly aligned.
 ///
 /// Additionally, if `T` is not [`Copy`], using the pointed-to value after
 /// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
@@ -151,31 +156,6 @@ pub use crate::intrinsics::write_bytes;
 /// assert!(weak.upgrade().is_none());
 /// ```
 ///
-/// Unaligned values cannot be dropped in place, they must be copied to an aligned
-/// location first:
-/// ```
-/// use std::ptr;
-/// use std::mem;
-///
-/// unsafe fn drop_after_copy<T>(to_drop: *mut T) {
-///     let mut copy: T = mem::uninitialized();
-///     ptr::copy(to_drop, &mut copy, 1);
-///     drop(copy);
-/// }
-///
-/// #[repr(packed, C)]
-/// struct Packed {
-///     _padding: u8,
-///     unaligned: Vec<i32>,
-/// }
-///
-/// let mut p = Packed { _padding: 0, unaligned: vec![42] };
-/// unsafe {
-///     drop_after_copy(&mut p.unaligned as *mut _);
-///     mem::forget(p);
-/// }
-/// ```
-///
 /// Notice that the compiler performs this copy automatically when dropping packed structs,
 /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place`
 /// manually.
@@ -228,6 +208,53 @@ pub const fn null<T>() -> *const T { 0 as *const T }
 #[rustc_promotable]
 pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
 
+#[repr(C)]
+pub(crate) union Repr<T> {
+    pub(crate) rust: *const [T],
+    rust_mut: *mut [T],
+    pub(crate) raw: FatPtr<T>,
+}
+
+#[repr(C)]
+pub(crate) struct FatPtr<T> {
+    data: *const T,
+    pub(crate) len: usize,
+}
+
+/// Forms a slice from a pointer and a length.
+///
+/// The `len` argument is the number of **elements**, not the number of bytes.
+///
+/// # Examples
+///
+/// ```rust
+/// #![feature(slice_from_raw_parts)]
+/// use std::ptr;
+///
+/// // create a slice pointer when starting out with a pointer to the first element
+/// let mut x = [5, 6, 7];
+/// let ptr = &mut x[0] as *mut _;
+/// let slice = ptr::slice_from_raw_parts_mut(ptr, 3);
+/// assert_eq!(unsafe { &*slice }[2], 7);
+/// ```
+#[inline]
+#[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")]
+pub fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    unsafe { Repr { raw: FatPtr { data, len } }.rust }
+}
+
+/// Performs the same functionality as [`from_raw_parts`], except that a
+/// mutable slice is returned.
+///
+/// See the documentation of [`from_raw_parts`] for more details.
+///
+/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
+#[inline]
+#[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")]
+pub fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
+    unsafe { Repr { raw: FatPtr { data, len } }.rust_mut }
+}
+
 /// Swaps the values at two mutable locations of the same type, without
 /// deinitializing either.
 ///
@@ -598,41 +625,65 @@ pub unsafe fn read<T>(src: *const T) -> T {
 /// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value
 /// [valid]: ../ptr/index.html#safety
 ///
-/// # Examples
+/// ## On `packed` structs
 ///
-/// Access members of a packed struct by reference:
+/// It is currently impossible to create raw pointers to unaligned fields
+/// of a packed struct.
 ///
-/// ```
-/// use std::ptr;
+/// Attempting to create a raw pointer to an `unaligned` struct field with
+/// an expression such as `&packed.unaligned as *const FieldType` creates an
+/// intermediate unaligned reference before converting that to a raw pointer.
+/// That this reference is temporary and immediately cast is inconsequential
+/// as the compiler always expects references to be properly aligned.
+/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
+/// *undefined behavior* in your program.
 ///
+/// An example of what not to do and how this relates to `read_unaligned` is:
+///
+/// ```no_run
 /// #[repr(packed, C)]
 /// struct Packed {
 ///     _padding: u8,
 ///     unaligned: u32,
 /// }
 ///
-/// let x = Packed {
+/// let packed = Packed {
 ///     _padding: 0x00,
 ///     unaligned: 0x01020304,
 /// };
 ///
 /// let v = unsafe {
-///     // Take the address of a 32-bit integer which is not aligned.
-///     // This must be done as a raw pointer; unaligned references are invalid.
-///     let unaligned = &x.unaligned as *const u32;
-///
-///     // Dereferencing normally will emit an aligned load instruction,
-///     // causing undefined behavior.
-///     // let v = *unaligned; // ERROR
+///     // Here we attempt to take the address of a 32-bit integer which is not aligned.
+///     let unaligned =
+///         // A temporary unaligned reference is created here which results in
+///         // undefined behavior regardless of whether the reference is used or not.
+///         &packed.unaligned
+///         // Casting to a raw pointer doesn't help; the mistake already happened.
+///         as *const u32;
 ///
-///     // Instead, use `read_unaligned` to read improperly aligned values.
-///     let v = ptr::read_unaligned(unaligned);
+///     let v = std::ptr::read_unaligned(unaligned);
 ///
 ///     v
 /// };
+/// ```
+///
+/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
+// FIXME: Update docs based on outcome of RFC #2582 and friends.
+///
+/// # Examples
+///
+/// Read an usize value from a byte buffer:
 ///
-/// // Accessing unaligned values directly is safe.
-/// assert!(x.unaligned == v);
+/// ```
+/// use std::mem;
+///
+/// fn read_usize(x: &[u8]) -> usize {
+///     assert!(x.len() >= mem::size_of::<usize>());
+///
+///     let ptr = x.as_ptr() as *const usize;
+///
+///     unsafe { ptr.read_unaligned() }
+/// }
 /// ```
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
@@ -762,37 +813,63 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
 ///
 /// [valid]: ../ptr/index.html#safety
 ///
-/// # Examples
+/// ## On `packed` structs
 ///
-/// Access fields in a packed struct:
+/// It is currently impossible to create raw pointers to unaligned fields
+/// of a packed struct.
 ///
-/// ```
-/// use std::{mem, ptr};
+/// Attempting to create a raw pointer to an `unaligned` struct field with
+/// an expression such as `&packed.unaligned as *const FieldType` creates an
+/// intermediate unaligned reference before converting that to a raw pointer.
+/// That this reference is temporary and immediately cast is inconsequential
+/// as the compiler always expects references to be properly aligned.
+/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
+/// *undefined behavior* in your program.
 ///
+/// An example of what not to do and how this relates to `write_unaligned` is:
+///
+/// ```no_run
 /// #[repr(packed, C)]
-/// #[derive(Default)]
 /// struct Packed {
 ///     _padding: u8,
 ///     unaligned: u32,
 /// }
 ///
 /// let v = 0x01020304;
-/// let mut x: Packed = unsafe { mem::zeroed() };
+/// let mut packed: Packed = unsafe { std::mem::zeroed() };
 ///
-/// unsafe {
-///     // Take a reference to a 32-bit integer which is not aligned.
-///     let unaligned = &mut x.unaligned as *mut u32;
+/// let v = unsafe {
+///     // Here we attempt to take the address of a 32-bit integer which is not aligned.
+///     let unaligned =
+///         // A temporary unaligned reference is created here which results in
+///         // undefined behavior regardless of whether the reference is used or not.
+///         &mut packed.unaligned
+///         // Casting to a raw pointer doesn't help; the mistake already happened.
+///         as *mut u32;
 ///
-///     // Dereferencing normally will emit an aligned store instruction,
-///     // causing undefined behavior because the pointer is not aligned.
-///     // *unaligned = v; // ERROR
+///     std::ptr::write_unaligned(unaligned, v);
 ///
-///     // Instead, use `write_unaligned` to write improperly aligned values.
-///     ptr::write_unaligned(unaligned, v);
-/// }
+///     v
+/// };
+/// ```
+///
+/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
+// FIXME: Update docs based on outcome of RFC #2582 and friends.
 ///
-/// // Accessing unaligned values directly is safe.
-/// assert!(x.unaligned == v);
+/// # Examples
+///
+/// Write an usize value to a byte buffer:
+///
+/// ```
+/// use std::mem;
+///
+/// fn write_usize(x: &mut [u8], val: usize) {
+///     assert!(x.len() >= mem::size_of::<usize>());
+///
+///     let ptr = x.as_mut_ptr() as *mut usize;
+///
+///     unsafe { ptr.write_unaligned(val) }
+/// }
 /// ```
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
@@ -810,9 +887,6 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
 /// to not be elided or reordered by the compiler across other volatile
 /// operations.
 ///
-/// Memory accessed with `read_volatile` or [`write_volatile`] should not be
-/// accessed with non-volatile operations.
-///
 /// [`write_volatile`]: ./fn.write_volatile.html
 ///
 /// # Notes
@@ -837,7 +911,7 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
 ///
 /// * `src` must be properly aligned.
 ///
-/// Like [`read`], `read_unaligned` creates a bitwise copy of `T`, regardless of
+/// Like [`read`], `read_volatile` creates a bitwise copy of `T`, regardless of
 /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned
 /// value and the value at `*src` can [violate memory safety][read-ownership].
 /// However, storing non-[`Copy`] types in volatile memory is almost certainly
@@ -881,9 +955,6 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
 /// to not be elided or reordered by the compiler across other volatile
 /// operations.
 ///
-/// Memory accessed with [`read_volatile`] or `write_volatile` should not be
-/// accessed with non-volatile operations.
-///
 /// `write_volatile` does not drop the contents of `dst`. This is safe, but it
 /// could leak allocations or resources, so care should be taken not to overwrite
 /// an object that should be dropped.
@@ -972,7 +1043,7 @@ impl<T: ?Sized> *const T {
     }
 
     /// Cast to a pointer to a different type
-    #[unstable(feature = "ptr_cast", issue = "60602")]
+    #[stable(feature = "ptr_cast", since = "1.38.0")]
     #[inline]
     pub const fn cast<U>(self) -> *const U {
         self as _
@@ -988,8 +1059,17 @@ impl<T: ?Sized> *const T {
     /// operation because the returned value could be pointing to invalid
     /// memory.
     ///
+    /// When calling this method, you have to ensure that if the pointer is
+    /// non-NULL, then it is properly aligned, dereferencable (for the whole
+    /// size of `T`) and points to an initialized instance of `T`. This applies
+    /// even if the result of this method is unused!
+    /// (The part about being initialized is not yet fully decided, but until
+    /// it is, the only safe approach is to ensure that they are indeed initialized.)
+    ///
     /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
-    /// not necessarily reflect the actual lifetime of the data.
+    /// not necessarily reflect the actual lifetime of the data. It is up to the
+    /// caller to ensure that for the duration of this lifetime, the memory this
+    /// pointer points to does not get written to outside of `UnsafeCell<U>`.
     ///
     /// # Examples
     ///
@@ -1040,7 +1120,8 @@ impl<T: ?Sized> *const T {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of the same allocated object.
+    ///   byte past the end of the same allocated object. Note that in Rust,
+    ///   every (stack-allocated) variable is considered a separate allocated object.
     ///
     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
@@ -1060,10 +1141,12 @@ impl<T: ?Sized> *const T {
     /// Extension. As such, memory acquired directly from allocators or memory
     /// mapped files *may* be too large to handle with this function.
     ///
-    /// Consider using `wrapping_offset` instead if these constraints are
+    /// Consider using [`wrapping_offset`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
     /// enables more aggressive compiler optimizations.
     ///
+    /// [`wrapping_offset`]: #method.wrapping_offset
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -1092,15 +1175,26 @@ impl<T: ?Sized> *const T {
     ///
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
-    /// In particular, the resulting pointer may *not* be used to access a
-    /// different allocated object than the one `self` points to. In other
-    /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
+    ///
+    /// In particular, the resulting pointer remains attached to the same allocated
+    /// object that `self` points to. It may *not* be used to access a
+    /// different allocated object. Note that in Rust,
+    /// every (stack-allocated) variable is considered a separate allocated object.
+    ///
+    /// In other words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
     /// *not* the same as `y`, and dereferencing it is undefined behavior
     /// unless `x` and `y` point into the same allocated object.
     ///
-    /// Always use `.offset(count)` instead when possible, because `offset`
-    /// allows the compiler to optimize better. If you need to cross object
-    /// boundaries, cast the pointer to an integer and do the arithmetic there.
+    /// Compared to [`offset`], this method basically delays the requirement of staying
+    /// within the same allocated object: [`offset`] is immediate Undefined Behavior when
+    /// crossing object boundaries; `wrapping_offset` produces a pointer but still leads
+    /// to Undefined Behavior if that pointer is dereferenced. [`offset`] can be optimized
+    /// better and is thus preferrable in performance-sensitive code.
+    ///
+    /// If you need to cross object boundaries, cast the pointer to an integer and
+    /// do the arithmetic there.
+    ///
+    /// [`offset`]: #method.offset
     ///
     /// # Examples
     ///
@@ -1143,7 +1237,8 @@ impl<T: ?Sized> *const T {
     /// Behavior:
     ///
     /// * Both the starting and other pointer must be either in bounds or one
-    ///   byte past the end of the same allocated object.
+    ///   byte past the end of the same allocated object. Note that in Rust,
+    ///   every (stack-allocated) variable is considered a separate allocated object.
     ///
     /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
     ///
@@ -1258,7 +1353,8 @@ impl<T: ?Sized> *const T {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of the same allocated object.
+    ///   byte past the end of the same allocated object. Note that in Rust,
+    ///   every (stack-allocated) variable is considered a separate allocated object.
     ///
     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
@@ -1278,10 +1374,12 @@ impl<T: ?Sized> *const T {
     /// Extension. As such, memory acquired directly from allocators or memory
     /// mapped files *may* be too large to handle with this function.
     ///
-    /// Consider using `wrapping_offset` instead if these constraints are
+    /// Consider using [`wrapping_add`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
     /// enables more aggressive compiler optimizations.
     ///
+    /// [`wrapping_add`]: #method.wrapping_add
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -1315,7 +1413,8 @@ impl<T: ?Sized> *const T {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of the same allocated object.
+    ///   byte past the end of the same allocated object. Note that in Rust,
+    ///   every (stack-allocated) variable is considered a separate allocated object.
     ///
     /// * The computed offset cannot exceed `isize::MAX` **bytes**.
     ///
@@ -1335,10 +1434,12 @@ impl<T: ?Sized> *const T {
     /// Extension. As such, memory acquired directly from allocators or memory
     /// mapped files *may* be too large to handle with this function.
     ///
-    /// Consider using `wrapping_offset` instead if these constraints are
+    /// Consider using [`wrapping_sub`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
     /// enables more aggressive compiler optimizations.
     ///
+    /// [`wrapping_sub`]: #method.wrapping_sub
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -1371,8 +1472,21 @@ impl<T: ?Sized> *const T {
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
     ///
-    /// Always use `.add(count)` instead when possible, because `add`
-    /// allows the compiler to optimize better.
+    /// In particular, the resulting pointer remains attached to the same allocated
+    /// object that `self` points to. It may *not* be used to access a
+    /// different allocated object. Note that in Rust,
+    /// every (stack-allocated) variable is considered a separate allocated object.
+    ///
+    /// Compared to [`add`], this method basically delays the requirement of staying
+    /// within the same allocated object: [`add`] is immediate Undefined Behavior when
+    /// crossing object boundaries; `wrapping_add` produces a pointer but still leads
+    /// to Undefined Behavior if that pointer is dereferenced. [`add`] can be optimized
+    /// better and is thus preferrable in performance-sensitive code.
+    ///
+    /// If you need to cross object boundaries, cast the pointer to an integer and
+    /// do the arithmetic there.
+    ///
+    /// [`add`]: #method.add
     ///
     /// # Examples
     ///
@@ -1412,8 +1526,21 @@ impl<T: ?Sized> *const T {
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
     ///
-    /// Always use `.sub(count)` instead when possible, because `sub`
-    /// allows the compiler to optimize better.
+    /// In particular, the resulting pointer remains attached to the same allocated
+    /// object that `self` points to. It may *not* be used to access a
+    /// different allocated object. Note that in Rust,
+    /// every (stack-allocated) variable is considered a separate allocated object.
+    ///
+    /// Compared to [`sub`], this method basically delays the requirement of staying
+    /// within the same allocated object: [`sub`] is immediate Undefined Behavior when
+    /// crossing object boundaries; `wrapping_sub` produces a pointer but still leads
+    /// to Undefined Behavior if that pointer is dereferenced. [`sub`] can be optimized
+    /// better and is thus preferrable in performance-sensitive code.
+    ///
+    /// If you need to cross object boundaries, cast the pointer to an integer and
+    /// do the arithmetic there.
+    ///
+    /// [`sub`]: #method.sub
     ///
     /// # Examples
     ///
@@ -1526,12 +1653,14 @@ impl<T: ?Sized> *const T {
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::max_value()`.
+    /// `usize::max_value()`. It is permissible for the implementation to *always*
+    /// return `usize::max_value()`. Only your algorithm's performance can depend
+    /// on getting a usable offset here, not its correctness.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
-    /// used with the `offset` or `offset_to` methods.
+    /// used with the `wrapping_add` method.
     ///
-    /// There are no guarantees whatsover that offsetting the pointer will not overflow or go
+    /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
     /// the returned offset is correct in all terms other than alignment.
     ///
@@ -1598,7 +1727,7 @@ impl<T: ?Sized> *mut T {
     }
 
     /// Cast to a pointer to a different type
-    #[unstable(feature = "ptr_cast", issue = "60602")]
+    #[stable(feature = "ptr_cast", since = "1.38.0")]
     #[inline]
     pub const fn cast<U>(self) -> *mut U {
         self as _
@@ -1614,8 +1743,17 @@ impl<T: ?Sized> *mut T {
     /// operation because the returned value could be pointing to invalid
     /// memory.
     ///
+    /// When calling this method, you have to ensure that if the pointer is
+    /// non-NULL, then it is properly aligned, dereferencable (for the whole
+    /// size of `T`) and points to an initialized instance of `T`. This applies
+    /// even if the result of this method is unused!
+    /// (The part about being initialized is not yet fully decided, but until
+    /// it is, the only safe approach is to ensure that they are indeed initialized.)
+    ///
     /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
-    /// not necessarily reflect the actual lifetime of the data.
+    /// not necessarily reflect the actual lifetime of the data. It is up to the
+    /// caller to ensure that for the duration of this lifetime, the memory this
+    /// pointer points to does not get written to outside of `UnsafeCell<U>`.
     ///
     /// # Examples
     ///
@@ -1666,7 +1804,8 @@ impl<T: ?Sized> *mut T {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of the same allocated object.
+    ///   byte past the end of the same allocated object. Note that in Rust,
+    ///   every (stack-allocated) variable is considered a separate allocated object.
     ///
     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
@@ -1686,10 +1825,12 @@ impl<T: ?Sized> *mut T {
     /// Extension. As such, memory acquired directly from allocators or memory
     /// mapped files *may* be too large to handle with this function.
     ///
-    /// Consider using `wrapping_offset` instead if these constraints are
+    /// Consider using [`wrapping_offset`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
     /// enables more aggressive compiler optimizations.
     ///
+    /// [`wrapping_offset`]: #method.wrapping_offset
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -1717,15 +1858,26 @@ impl<T: ?Sized> *mut T {
     ///
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
-    /// In particular, the resulting pointer may *not* be used to access a
-    /// different allocated object than the one `self` points to. In other
-    /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
+    ///
+    /// In particular, the resulting pointer remains attached to the same allocated
+    /// object that `self` points to. It may *not* be used to access a
+    /// different allocated object. Note that in Rust,
+    /// every (stack-allocated) variable is considered a separate allocated object.
+    ///
+    /// In other words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
     /// *not* the same as `y`, and dereferencing it is undefined behavior
     /// unless `x` and `y` point into the same allocated object.
     ///
-    /// Always use `.offset(count)` instead when possible, because `offset`
-    /// allows the compiler to optimize better. If you need to cross object
-    /// boundaries, cast the pointer to an integer and do the arithmetic there.
+    /// Compared to [`offset`], this method basically delays the requirement of staying
+    /// within the same allocated object: [`offset`] is immediate Undefined Behavior when
+    /// crossing object boundaries; `wrapping_offset` produces a pointer but still leads
+    /// to Undefined Behavior if that pointer is dereferenced. [`offset`] can be optimized
+    /// better and is thus preferrable in performance-sensitive code.
+    ///
+    /// If you need to cross object boundaries, cast the pointer to an integer and
+    /// do the arithmetic there.
+    ///
+    /// [`offset`]: #method.offset
     ///
     /// # Examples
     ///
@@ -1759,10 +1911,24 @@ impl<T: ?Sized> *mut T {
     ///
     /// # Safety
     ///
-    /// As with `as_ref`, this is unsafe because it cannot verify the validity
+    /// As with [`as_ref`], this is unsafe because it cannot verify the validity
     /// of the returned pointer, nor can it ensure that the lifetime `'a`
     /// returned is indeed a valid lifetime for the contained data.
     ///
+    /// When calling this method, you have to ensure that if the pointer is
+    /// non-NULL, then it is properly aligned, dereferencable (for the whole
+    /// size of `T`) and points to an initialized instance of `T`. This applies
+    /// even if the result of this method is unused!
+    /// (The part about being initialized is not yet fully decided, but until
+    /// it is the only safe approach is to ensure that they are indeed initialized.)
+    ///
+    /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
+    /// not necessarily reflect the actual lifetime of the data. It is up to the
+    /// caller to ensure that for the duration of this lifetime, the memory this
+    /// pointer points to does not get accessed through any other pointer.
+    ///
+    /// [`as_ref`]: #method.as_ref
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -1798,7 +1964,8 @@ impl<T: ?Sized> *mut T {
     /// Behavior:
     ///
     /// * Both the starting and other pointer must be either in bounds or one
-    ///   byte past the end of the same allocated object.
+    ///   byte past the end of the same allocated object. Note that in Rust,
+    ///   every (stack-allocated) variable is considered a separate allocated object.
     ///
     /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
     ///
@@ -1902,7 +2069,8 @@ impl<T: ?Sized> *mut T {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of the same allocated object.
+    ///   byte past the end of the same allocated object. Note that in Rust,
+    ///   every (stack-allocated) variable is considered a separate allocated object.
     ///
     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
@@ -1922,10 +2090,12 @@ impl<T: ?Sized> *mut T {
     /// Extension. As such, memory acquired directly from allocators or memory
     /// mapped files *may* be too large to handle with this function.
     ///
-    /// Consider using `wrapping_offset` instead if these constraints are
+    /// Consider using [`wrapping_add`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
     /// enables more aggressive compiler optimizations.
     ///
+    /// [`wrapping_add`]: #method.wrapping_add
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -1959,7 +2129,8 @@ impl<T: ?Sized> *mut T {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of the same allocated object.
+    ///   byte past the end of the same allocated object. Note that in Rust,
+    ///   every (stack-allocated) variable is considered a separate allocated object.
     ///
     /// * The computed offset cannot exceed `isize::MAX` **bytes**.
     ///
@@ -1979,10 +2150,12 @@ impl<T: ?Sized> *mut T {
     /// Extension. As such, memory acquired directly from allocators or memory
     /// mapped files *may* be too large to handle with this function.
     ///
-    /// Consider using `wrapping_offset` instead if these constraints are
+    /// Consider using [`wrapping_sub`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
     /// enables more aggressive compiler optimizations.
     ///
+    /// [`wrapping_sub`]: #method.wrapping_sub
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -2015,8 +2188,21 @@ impl<T: ?Sized> *mut T {
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
     ///
-    /// Always use `.add(count)` instead when possible, because `add`
-    /// allows the compiler to optimize better.
+    /// In particular, the resulting pointer remains attached to the same allocated
+    /// object that `self` points to. It may *not* be used to access a
+    /// different allocated object. Note that in Rust,
+    /// every (stack-allocated) variable is considered a separate allocated object.
+    ///
+    /// Compared to [`add`], this method basically delays the requirement of staying
+    /// within the same allocated object: [`add`] is immediate Undefined Behavior when
+    /// crossing object boundaries; `wrapping_add` produces a pointer but still leads
+    /// to Undefined Behavior if that pointer is dereferenced. [`add`] can be optimized
+    /// better and is thus preferrable in performance-sensitive code.
+    ///
+    /// If you need to cross object boundaries, cast the pointer to an integer and
+    /// do the arithmetic there.
+    ///
+    /// [`add`]: #method.add
     ///
     /// # Examples
     ///
@@ -2056,8 +2242,21 @@ impl<T: ?Sized> *mut T {
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
     ///
-    /// Always use `.sub(count)` instead when possible, because `sub`
-    /// allows the compiler to optimize better.
+    /// In particular, the resulting pointer remains attached to the same allocated
+    /// object that `self` points to. It may *not* be used to access a
+    /// different allocated object. Note that in Rust,
+    /// every (stack-allocated) variable is considered a separate allocated object.
+    ///
+    /// Compared to [`sub`], this method basically delays the requirement of staying
+    /// within the same allocated object: [`sub`] is immediate Undefined Behavior when
+    /// crossing object boundaries; `wrapping_sub` produces a pointer but still leads
+    /// to Undefined Behavior if that pointer is dereferenced. [`sub`] can be optimized
+    /// better and is thus preferrable in performance-sensitive code.
+    ///
+    /// If you need to cross object boundaries, cast the pointer to an integer and
+    /// do the arithmetic there.
+    ///
+    /// [`sub`]: #method.sub
     ///
     /// # Examples
     ///
@@ -2304,12 +2503,14 @@ impl<T: ?Sized> *mut T {
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::max_value()`.
+    /// `usize::max_value()`. It is permissible for the implementation to *always*
+    /// return `usize::max_value()`. Only your algorithm's performance can depend
+    /// on getting a usable offset here, not its correctness.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
-    /// used with the `offset` or `offset_to` methods.
+    /// used with the `wrapping_add` method.
     ///
-    /// There are no guarantees whatsover that offsetting the pointer will not overflow or go
+    /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
     /// the returned offset is correct in all terms other than alignment.
     ///
@@ -2650,12 +2851,12 @@ macro_rules! fnptr_impls_safety_abi {
 
 macro_rules! fnptr_impls_args {
     ($($Arg: ident),+) => {
-        fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { extern "C" fn($($Arg),*) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),*) -> Ret, $($Arg),* }
-        fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* }
+        fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { extern "C" fn($($Arg),+) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+) -> Ret, $($Arg),+ }
+        fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ }
     };
     () => {
         // No variadic functions with 0 parameters
@@ -2748,383 +2949,3 @@ impl<T: ?Sized> PartialOrd for *mut T {
     #[inline]
     fn ge(&self, other: &*mut T) -> bool { *self >= *other }
 }
-
-/// A wrapper around a raw non-null `*mut T` that indicates that the possessor
-/// of this wrapper owns the referent. Useful for building abstractions like
-/// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
-///
-/// Unlike `*mut T`, `Unique<T>` behaves "as if" it were an instance of `T`.
-/// It implements `Send`/`Sync` if `T` is `Send`/`Sync`. It also implies
-/// the kind of strong aliasing guarantees an instance of `T` can expect:
-/// the referent of the pointer should not be modified without a unique path to
-/// its owning Unique.
-///
-/// If you're uncertain of whether it's correct to use `Unique` for your purposes,
-/// consider using `NonNull`, which has weaker semantics.
-///
-/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
-/// is never dereferenced. This is so that enums may use this forbidden value
-/// as a discriminant -- `Option<Unique<T>>` has the same size as `Unique<T>`.
-/// However the pointer may still dangle if it isn't dereferenced.
-///
-/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
-/// for any type which upholds Unique's aliasing requirements.
-#[unstable(feature = "ptr_internals", issue = "0",
-           reason = "use NonNull instead and consider PhantomData<T> \
-                     (if you also use #[may_dangle]), Send, and/or Sync")]
-#[doc(hidden)]
-#[repr(transparent)]
-#[rustc_layout_scalar_valid_range_start(1)]
-pub struct Unique<T: ?Sized> {
-    pointer: *const T,
-    // NOTE: this marker has no consequences for variance, but is necessary
-    // for dropck to understand that we logically own a `T`.
-    //
-    // For details, see:
-    // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data
-    _marker: PhantomData<T>,
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> fmt::Debug for Unique<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Pointer::fmt(&self.as_ptr(), f)
-    }
-}
-
-/// `Unique` pointers are `Send` if `T` is `Send` because the data they
-/// reference is unaliased. Note that this aliasing invariant is
-/// unenforced by the type system; the abstraction using the
-/// `Unique` must enforce it.
-#[unstable(feature = "ptr_internals", issue = "0")]
-unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
-
-/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
-/// reference is unaliased. Note that this aliasing invariant is
-/// unenforced by the type system; the abstraction using the
-/// `Unique` must enforce it.
-#[unstable(feature = "ptr_internals", issue = "0")]
-unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: Sized> Unique<T> {
-    /// Creates a new `Unique` that is dangling, but well-aligned.
-    ///
-    /// This is useful for initializing types which lazily allocate, like
-    /// `Vec::new` does.
-    ///
-    /// Note that the pointer value may potentially represent a valid pointer to
-    /// a `T`, which means this must not be used as a "not yet initialized"
-    /// sentinel value. Types that lazily allocate must track initialization by
-    /// some other means.
-    // FIXME: rename to dangling() to match NonNull?
-    pub const fn empty() -> Self {
-        unsafe {
-            Unique::new_unchecked(mem::align_of::<T>() as *mut T)
-        }
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> Unique<T> {
-    /// Creates a new `Unique`.
-    ///
-    /// # Safety
-    ///
-    /// `ptr` must be non-null.
-    pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
-        Unique { pointer: ptr as _, _marker: PhantomData }
-    }
-
-    /// Creates a new `Unique` if `ptr` is non-null.
-    pub fn new(ptr: *mut T) -> Option<Self> {
-        if !ptr.is_null() {
-            Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
-        } else {
-            None
-        }
-    }
-
-    /// Acquires the underlying `*mut` pointer.
-    pub const fn as_ptr(self) -> *mut T {
-        self.pointer as *mut T
-    }
-
-    /// Dereferences the content.
-    ///
-    /// The resulting lifetime is bound to self so this behaves "as if"
-    /// it were actually an instance of T that is getting borrowed. If a longer
-    /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
-    pub unsafe fn as_ref(&self) -> &T {
-        &*self.as_ptr()
-    }
-
-    /// Mutably dereferences the content.
-    ///
-    /// The resulting lifetime is bound to self so this behaves "as if"
-    /// it were actually an instance of T that is getting borrowed. If a longer
-    /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
-    pub unsafe fn as_mut(&mut self) -> &mut T {
-        &mut *self.as_ptr()
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> Clone for Unique<T> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> Copy for Unique<T> { }
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { }
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> { }
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> fmt::Pointer for Unique<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Pointer::fmt(&self.as_ptr(), f)
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> From<&mut T> for Unique<T> {
-    fn from(reference: &mut T) -> Self {
-        unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> From<&T> for Unique<T> {
-    fn from(reference: &T) -> Self {
-        unsafe { Unique { pointer: reference as *const T, _marker: PhantomData } }
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
-    fn from(p: NonNull<T>) -> Self {
-        unsafe { Unique { pointer: p.pointer, _marker: PhantomData } }
-    }
-}
-
-/// `*mut T` but non-zero and covariant.
-///
-/// This is often the correct thing to use when building data structures using
-/// raw pointers, but is ultimately more dangerous to use because of its additional
-/// properties. If you're not sure if you should use `NonNull<T>`, just use `*mut T`!
-///
-/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
-/// is never dereferenced. This is so that enums may use this forbidden value
-/// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`.
-/// However the pointer may still dangle if it isn't dereferenced.
-///
-/// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect
-/// for your use case, you should include some [`PhantomData`] in your type to
-/// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
-/// Usually this won't be necessary; covariance is correct for most safe abstractions,
-/// such as `Box`, `Rc`, `Arc`, `Vec`, and `LinkedList`. This is the case because they
-/// provide a public API that follows the normal shared XOR mutable rules of Rust.
-///
-/// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does
-/// not change the fact that mutating through a (pointer derived from a) shared
-/// reference is undefined behavior unless the mutation happens inside an
-/// [`UnsafeCell<T>`]. The same goes for creating a mutable reference from a shared
-/// reference. When using this `From` instance without an `UnsafeCell<T>`,
-/// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
-/// is never used for mutation.
-///
-/// [`PhantomData`]: ../marker/struct.PhantomData.html
-/// [`UnsafeCell<T>`]: ../cell/struct.UnsafeCell.html
-#[stable(feature = "nonnull", since = "1.25.0")]
-#[repr(transparent)]
-#[rustc_layout_scalar_valid_range_start(1)]
-pub struct NonNull<T: ?Sized> {
-    pointer: *const T,
-}
-
-/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
-// N.B., this impl is unnecessary, but should provide better error messages.
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> !Send for NonNull<T> { }
-
-/// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
-// N.B., this impl is unnecessary, but should provide better error messages.
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> !Sync for NonNull<T> { }
-
-impl<T: Sized> NonNull<T> {
-    /// Creates a new `NonNull` that is dangling, but well-aligned.
-    ///
-    /// This is useful for initializing types which lazily allocate, like
-    /// `Vec::new` does.
-    ///
-    /// Note that the pointer value may potentially represent a valid pointer to
-    /// a `T`, which means this must not be used as a "not yet initialized"
-    /// sentinel value. Types that lazily allocate must track initialization by
-    /// some other means.
-    #[stable(feature = "nonnull", since = "1.25.0")]
-    #[inline]
-    pub const fn dangling() -> Self {
-        unsafe {
-            let ptr = mem::align_of::<T>() as *mut T;
-            NonNull::new_unchecked(ptr)
-        }
-    }
-}
-
-impl<T: ?Sized> NonNull<T> {
-    /// Creates a new `NonNull`.
-    ///
-    /// # Safety
-    ///
-    /// `ptr` must be non-null.
-    #[stable(feature = "nonnull", since = "1.25.0")]
-    #[inline]
-    pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
-        NonNull { pointer: ptr as _ }
-    }
-
-    /// Creates a new `NonNull` if `ptr` is non-null.
-    #[stable(feature = "nonnull", since = "1.25.0")]
-    #[inline]
-    pub fn new(ptr: *mut T) -> Option<Self> {
-        if !ptr.is_null() {
-            Some(unsafe { Self::new_unchecked(ptr) })
-        } else {
-            None
-        }
-    }
-
-    /// Acquires the underlying `*mut` pointer.
-    #[stable(feature = "nonnull", since = "1.25.0")]
-    #[inline]
-    pub const fn as_ptr(self) -> *mut T {
-        self.pointer as *mut T
-    }
-
-    /// Dereferences the content.
-    ///
-    /// The resulting lifetime is bound to self so this behaves "as if"
-    /// it were actually an instance of T that is getting borrowed. If a longer
-    /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
-    #[stable(feature = "nonnull", since = "1.25.0")]
-    #[inline]
-    pub unsafe fn as_ref(&self) -> &T {
-        &*self.as_ptr()
-    }
-
-    /// Mutably dereferences the content.
-    ///
-    /// The resulting lifetime is bound to self so this behaves "as if"
-    /// it were actually an instance of T that is getting borrowed. If a longer
-    /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
-    #[stable(feature = "nonnull", since = "1.25.0")]
-    #[inline]
-    pub unsafe fn as_mut(&mut self) -> &mut T {
-        &mut *self.as_ptr()
-    }
-
-    /// Cast to a pointer of another type
-    #[stable(feature = "nonnull_cast", since = "1.27.0")]
-    #[inline]
-    pub const fn cast<U>(self) -> NonNull<U> {
-        unsafe {
-            NonNull::new_unchecked(self.as_ptr() as *mut U)
-        }
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> Clone for NonNull<T> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> Copy for NonNull<T> { }
-
-#[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
-
-#[unstable(feature = "dispatch_from_dyn", issue = "0")]
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> fmt::Debug for NonNull<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Pointer::fmt(&self.as_ptr(), f)
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> fmt::Pointer for NonNull<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Pointer::fmt(&self.as_ptr(), f)
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> Eq for NonNull<T> {}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> PartialEq for NonNull<T> {
-    #[inline]
-    fn eq(&self, other: &Self) -> bool {
-        self.as_ptr() == other.as_ptr()
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> Ord for NonNull<T> {
-    #[inline]
-    fn cmp(&self, other: &Self) -> Ordering {
-        self.as_ptr().cmp(&other.as_ptr())
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> PartialOrd for NonNull<T> {
-    #[inline]
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        self.as_ptr().partial_cmp(&other.as_ptr())
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> hash::Hash for NonNull<T> {
-    #[inline]
-    fn hash<H: hash::Hasher>(&self, state: &mut H) {
-        self.as_ptr().hash(state)
-    }
-}
-
-#[unstable(feature = "ptr_internals", issue = "0")]
-impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
-    #[inline]
-    fn from(unique: Unique<T>) -> Self {
-        unsafe { NonNull { pointer: unique.pointer } }
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> From<&mut T> for NonNull<T> {
-    #[inline]
-    fn from(reference: &mut T) -> Self {
-        unsafe { NonNull { pointer: reference as *mut T } }
-    }
-}
-
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: ?Sized> From<&T> for NonNull<T> {
-    #[inline]
-    fn from(reference: &T) -> Self {
-        unsafe { NonNull { pointer: reference as *const T } }
-    }
-}
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
new file mode 100644
index 00000000000..ad3d1ce396a
--- /dev/null
+++ b/src/libcore/ptr/non_null.rs
@@ -0,0 +1,226 @@
+use crate::convert::From;
+use crate::ops::{CoerceUnsized, DispatchFromDyn};
+use crate::fmt;
+use crate::hash;
+use crate::marker::Unsize;
+use crate::mem;
+use crate::ptr::Unique;
+use crate::cmp::Ordering;
+
+/// `*mut T` but non-zero and covariant.
+///
+/// This is often the correct thing to use when building data structures using
+/// raw pointers, but is ultimately more dangerous to use because of its additional
+/// properties. If you're not sure if you should use `NonNull<T>`, just use `*mut T`!
+///
+/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
+/// is never dereferenced. This is so that enums may use this forbidden value
+/// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`.
+/// However the pointer may still dangle if it isn't dereferenced.
+///
+/// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect
+/// for your use case, you should include some [`PhantomData`] in your type to
+/// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
+/// Usually this won't be necessary; covariance is correct for most safe abstractions,
+/// such as `Box`, `Rc`, `Arc`, `Vec`, and `LinkedList`. This is the case because they
+/// provide a public API that follows the normal shared XOR mutable rules of Rust.
+///
+/// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does
+/// not change the fact that mutating through a (pointer derived from a) shared
+/// reference is undefined behavior unless the mutation happens inside an
+/// [`UnsafeCell<T>`]. The same goes for creating a mutable reference from a shared
+/// reference. When using this `From` instance without an `UnsafeCell<T>`,
+/// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
+/// is never used for mutation.
+///
+/// [`PhantomData`]: ../marker/struct.PhantomData.html
+/// [`UnsafeCell<T>`]: ../cell/struct.UnsafeCell.html
+#[stable(feature = "nonnull", since = "1.25.0")]
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_start(1)]
+#[rustc_nonnull_optimization_guaranteed]
+pub struct NonNull<T: ?Sized> {
+    pointer: *const T,
+}
+
+/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
+// N.B., this impl is unnecessary, but should provide better error messages.
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> !Send for NonNull<T> { }
+
+/// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
+// N.B., this impl is unnecessary, but should provide better error messages.
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> !Sync for NonNull<T> { }
+
+impl<T: Sized> NonNull<T> {
+    /// Creates a new `NonNull` that is dangling, but well-aligned.
+    ///
+    /// This is useful for initializing types which lazily allocate, like
+    /// `Vec::new` does.
+    ///
+    /// Note that the pointer value may potentially represent a valid pointer to
+    /// a `T`, which means this must not be used as a "not yet initialized"
+    /// sentinel value. Types that lazily allocate must track initialization by
+    /// some other means.
+    #[stable(feature = "nonnull", since = "1.25.0")]
+    #[inline]
+    pub const fn dangling() -> Self {
+        unsafe {
+            let ptr = mem::align_of::<T>() as *mut T;
+            NonNull::new_unchecked(ptr)
+        }
+    }
+}
+
+impl<T: ?Sized> NonNull<T> {
+    /// Creates a new `NonNull`.
+    ///
+    /// # Safety
+    ///
+    /// `ptr` must be non-null.
+    #[stable(feature = "nonnull", since = "1.25.0")]
+    #[inline]
+    pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
+        NonNull { pointer: ptr as _ }
+    }
+
+    /// Creates a new `NonNull` if `ptr` is non-null.
+    #[stable(feature = "nonnull", since = "1.25.0")]
+    #[inline]
+    pub fn new(ptr: *mut T) -> Option<Self> {
+        if !ptr.is_null() {
+            Some(unsafe { Self::new_unchecked(ptr) })
+        } else {
+            None
+        }
+    }
+
+    /// Acquires the underlying `*mut` pointer.
+    #[stable(feature = "nonnull", since = "1.25.0")]
+    #[inline]
+    pub const fn as_ptr(self) -> *mut T {
+        self.pointer as *mut T
+    }
+
+    /// Dereferences the content.
+    ///
+    /// The resulting lifetime is bound to self so this behaves "as if"
+    /// it were actually an instance of T that is getting borrowed. If a longer
+    /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
+    #[stable(feature = "nonnull", since = "1.25.0")]
+    #[inline]
+    pub unsafe fn as_ref(&self) -> &T {
+        &*self.as_ptr()
+    }
+
+    /// Mutably dereferences the content.
+    ///
+    /// The resulting lifetime is bound to self so this behaves "as if"
+    /// it were actually an instance of T that is getting borrowed. If a longer
+    /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
+    #[stable(feature = "nonnull", since = "1.25.0")]
+    #[inline]
+    pub unsafe fn as_mut(&mut self) -> &mut T {
+        &mut *self.as_ptr()
+    }
+
+    /// Cast to a pointer of another type
+    #[stable(feature = "nonnull_cast", since = "1.27.0")]
+    #[inline]
+    pub const fn cast<U>(self) -> NonNull<U> {
+        unsafe {
+            NonNull::new_unchecked(self.as_ptr() as *mut U)
+        }
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Clone for NonNull<T> {
+    #[inline]
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Copy for NonNull<T> { }
+
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
+
+#[unstable(feature = "dispatch_from_dyn", issue = "0")]
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> fmt::Debug for NonNull<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Pointer::fmt(&self.as_ptr(), f)
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> fmt::Pointer for NonNull<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Pointer::fmt(&self.as_ptr(), f)
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Eq for NonNull<T> {}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> PartialEq for NonNull<T> {
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        self.as_ptr() == other.as_ptr()
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> Ord for NonNull<T> {
+    #[inline]
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.as_ptr().cmp(&other.as_ptr())
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> PartialOrd for NonNull<T> {
+    #[inline]
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        self.as_ptr().partial_cmp(&other.as_ptr())
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> hash::Hash for NonNull<T> {
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.as_ptr().hash(state)
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
+    #[inline]
+    fn from(unique: Unique<T>) -> Self {
+        unsafe { NonNull::new_unchecked(unique.as_ptr()) }
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> From<&mut T> for NonNull<T> {
+    #[inline]
+    fn from(reference: &mut T) -> Self {
+        unsafe { NonNull { pointer: reference as *mut T } }
+    }
+}
+
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: ?Sized> From<&T> for NonNull<T> {
+    #[inline]
+    fn from(reference: &T) -> Self {
+        unsafe { NonNull { pointer: reference as *const T } }
+    }
+}
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
new file mode 100644
index 00000000000..3521dd79979
--- /dev/null
+++ b/src/libcore/ptr/unique.rs
@@ -0,0 +1,188 @@
+use crate::convert::From;
+use crate::ops::{CoerceUnsized, DispatchFromDyn};
+use crate::fmt;
+use crate::marker::{PhantomData, Unsize};
+use crate::mem;
+use crate::ptr::NonNull;
+
+/// A wrapper around a raw non-null `*mut T` that indicates that the possessor
+/// of this wrapper owns the referent. Useful for building abstractions like
+/// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
+///
+/// Unlike `*mut T`, `Unique<T>` behaves "as if" it were an instance of `T`.
+/// It implements `Send`/`Sync` if `T` is `Send`/`Sync`. It also implies
+/// the kind of strong aliasing guarantees an instance of `T` can expect:
+/// the referent of the pointer should not be modified without a unique path to
+/// its owning Unique.
+///
+/// If you're uncertain of whether it's correct to use `Unique` for your purposes,
+/// consider using `NonNull`, which has weaker semantics.
+///
+/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
+/// is never dereferenced. This is so that enums may use this forbidden value
+/// as a discriminant -- `Option<Unique<T>>` has the same size as `Unique<T>`.
+/// However the pointer may still dangle if it isn't dereferenced.
+///
+/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
+/// for any type which upholds Unique's aliasing requirements.
+#[unstable(feature = "ptr_internals", issue = "0",
+           reason = "use `NonNull` instead and consider `PhantomData<T>` \
+                     (if you also use `#[may_dangle]`), `Send`, and/or `Sync`")]
+#[doc(hidden)]
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_start(1)]
+pub struct Unique<T: ?Sized> {
+    pointer: *const T,
+    // NOTE: this marker has no consequences for variance, but is necessary
+    // for dropck to understand that we logically own a `T`.
+    //
+    // For details, see:
+    // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data
+    _marker: PhantomData<T>,
+}
+
+/// `Unique` pointers are `Send` if `T` is `Send` because the data they
+/// reference is unaliased. Note that this aliasing invariant is
+/// unenforced by the type system; the abstraction using the
+/// `Unique` must enforce it.
+#[unstable(feature = "ptr_internals", issue = "0")]
+unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
+
+/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
+/// reference is unaliased. Note that this aliasing invariant is
+/// unenforced by the type system; the abstraction using the
+/// `Unique` must enforce it.
+#[unstable(feature = "ptr_internals", issue = "0")]
+unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: Sized> Unique<T> {
+    /// Creates a new `Unique` that is dangling, but well-aligned.
+    ///
+    /// This is useful for initializing types which lazily allocate, like
+    /// `Vec::new` does.
+    ///
+    /// Note that the pointer value may potentially represent a valid pointer to
+    /// a `T`, which means this must not be used as a "not yet initialized"
+    /// sentinel value. Types that lazily allocate must track initialization by
+    /// some other means.
+    // FIXME: rename to dangling() to match NonNull?
+    #[inline]
+    pub const fn empty() -> Self {
+        unsafe {
+            Unique::new_unchecked(mem::align_of::<T>() as *mut T)
+        }
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> Unique<T> {
+    /// Creates a new `Unique`.
+    ///
+    /// # Safety
+    ///
+    /// `ptr` must be non-null.
+    #[inline]
+    pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
+        Unique { pointer: ptr as _, _marker: PhantomData }
+    }
+
+    /// Creates a new `Unique` if `ptr` is non-null.
+    #[inline]
+    pub fn new(ptr: *mut T) -> Option<Self> {
+        if !ptr.is_null() {
+            Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
+        } else {
+            None
+        }
+    }
+
+    /// Acquires the underlying `*mut` pointer.
+    #[inline]
+    pub const fn as_ptr(self) -> *mut T {
+        self.pointer as *mut T
+    }
+
+    /// Dereferences the content.
+    ///
+    /// The resulting lifetime is bound to self so this behaves "as if"
+    /// it were actually an instance of T that is getting borrowed. If a longer
+    /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
+    #[inline]
+    pub unsafe fn as_ref(&self) -> &T {
+        &*self.as_ptr()
+    }
+
+    /// Mutably dereferences the content.
+    ///
+    /// The resulting lifetime is bound to self so this behaves "as if"
+    /// it were actually an instance of T that is getting borrowed. If a longer
+    /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
+    #[inline]
+    pub unsafe fn as_mut(&mut self) -> &mut T {
+        &mut *self.as_ptr()
+    }
+
+    /// Casts to a pointer of another type.
+    #[inline]
+    pub const fn cast<U>(self) -> Unique<U> {
+        unsafe {
+            Unique::new_unchecked(self.as_ptr() as *mut U)
+        }
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> Clone for Unique<T> {
+    #[inline]
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> Copy for Unique<T> { }
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { }
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> { }
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> fmt::Debug for Unique<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Pointer::fmt(&self.as_ptr(), f)
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> fmt::Pointer for Unique<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Pointer::fmt(&self.as_ptr(), f)
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> From<&mut T> for Unique<T> {
+    #[inline]
+    fn from(reference: &mut T) -> Self {
+        unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> From<&T> for Unique<T> {
+    #[inline]
+    fn from(reference: &T) -> Self {
+        unsafe { Unique { pointer: reference as *const T, _marker: PhantomData } }
+    }
+}
+
+#[unstable(feature = "ptr_internals", issue = "0")]
+impl<T: ?Sized> From<NonNull<T>> for Unique<T> {
+    #[inline]
+    fn from(p: NonNull<T>) -> Self {
+        unsafe { Unique::new_unchecked(p.as_ptr()) }
+    }
+}
diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs
index 155429b0e4f..75c329a7d6c 100644
--- a/src/libcore/raw.rs
+++ b/src/libcore/raw.rs
@@ -53,7 +53,7 @@
 /// let value: i32 = 123;
 ///
 /// // let the compiler make a trait object
-/// let object: &Foo = &value;
+/// let object: &dyn Foo = &value;
 ///
 /// // look at the raw representation
 /// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) };
@@ -65,7 +65,7 @@
 ///
 /// // construct a new object, pointing to a different `i32`, being
 /// // careful to use the `i32` vtable from `object`
-/// let synthesized: &Foo = unsafe {
+/// let synthesized: &dyn Foo = unsafe {
 ///      mem::transmute(raw::TraitObject {
 ///          data: &other_value as *const _ as *mut (),
 ///          vtable: raw_object.vtable,
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index bf8fd63b644..8c60a9c1b50 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -231,8 +231,8 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::fmt;
-use crate::iter::{FromIterator, FusedIterator, TrustedLen};
-use crate::ops::{self, Deref};
+use crate::iter::{self, FromIterator, FusedIterator, TrustedLen};
+use crate::ops::{self, Deref, DerefMut};
 
 /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).
 ///
@@ -240,7 +240,7 @@ use crate::ops::{self, Deref};
 ///
 /// [`Ok`]: enum.Result.html#variant.Ok
 /// [`Err`]: enum.Result.html#variant.Err
-#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
+#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
 #[must_use = "this `Result` may be an `Err` variant, which should be handled"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Result<T, E> {
@@ -277,7 +277,7 @@ impl<T, E> Result<T, E> {
     /// let x: Result<i32, &str> = Err("Some error message");
     /// assert_eq!(x.is_ok(), false);
     /// ```
-    #[must_use]
+    #[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_ok(&self) -> bool {
@@ -302,13 +302,65 @@ impl<T, E> Result<T, E> {
     /// let x: Result<i32, &str> = Err("Some error message");
     /// assert_eq!(x.is_err(), true);
     /// ```
-    #[must_use]
+    #[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_err(&self) -> bool {
         !self.is_ok()
     }
 
+    /// Returns `true` if the result is an [`Ok`] value containing the given value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(option_result_contains)]
+    ///
+    /// let x: Result<u32, &str> = Ok(2);
+    /// assert_eq!(x.contains(&2), true);
+    ///
+    /// let x: Result<u32, &str> = Ok(3);
+    /// assert_eq!(x.contains(&2), false);
+    ///
+    /// let x: Result<u32, &str> = Err("Some error message");
+    /// assert_eq!(x.contains(&2), false);
+    /// ```
+    #[must_use]
+    #[inline]
+    #[unstable(feature = "option_result_contains", issue = "62358")]
+    pub fn contains<U>(&self, x: &U) -> bool where U: PartialEq<T> {
+        match self {
+            Ok(y) => x == y,
+            Err(_) => false
+        }
+    }
+
+    /// Returns `true` if the result is an [`Err`] value containing the given value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_contains_err)]
+    ///
+    /// let x: Result<u32, &str> = Ok(2);
+    /// assert_eq!(x.contains_err(&"Some error message"), false);
+    ///
+    /// let x: Result<u32, &str> = Err("Some error message");
+    /// assert_eq!(x.contains_err(&"Some error message"), true);
+    ///
+    /// let x: Result<u32, &str> = Err("Some other error message");
+    /// assert_eq!(x.contains_err(&"Some error message"), false);
+    /// ```
+    #[must_use]
+    #[inline]
+    #[unstable(feature = "result_contains_err", issue = "62358")]
+    pub fn contains_err<F>(&self, f: &F) -> bool where F: PartialEq<E> {
+        match self {
+            Ok(_) => false,
+            Err(e) => f == e
+        }
+    }
+
     /////////////////////////////////////////////////////////////////////////
     // Adapter for each variant
     /////////////////////////////////////////////////////////////////////////
@@ -797,7 +849,7 @@ impl<T, E: fmt::Debug> Result<T, E> {
     pub fn unwrap(self) -> T {
         match self {
             Ok(t) => t,
-            Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", e),
+            Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", &e),
         }
     }
 
@@ -824,7 +876,7 @@ impl<T, E: fmt::Debug> Result<T, E> {
     pub fn expect(self, msg: &str) -> T {
         match self {
             Ok(t) => t,
-            Err(e) => unwrap_failed(msg, e),
+            Err(e) => unwrap_failed(msg, &e),
         }
     }
 }
@@ -856,7 +908,7 @@ impl<T: fmt::Debug, E> Result<T, E> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn unwrap_err(self) -> E {
         match self {
-            Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", t),
+            Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", &t),
             Err(e) => e,
         }
     }
@@ -883,7 +935,7 @@ impl<T: fmt::Debug, E> Result<T, E> {
     #[stable(feature = "result_expect_err", since = "1.17.0")]
     pub fn expect_err(self, msg: &str) -> E {
         match self {
-            Ok(t) => unwrap_failed(msg, t),
+            Ok(t) => unwrap_failed(msg, &t),
             Err(e) => e,
         }
     }
@@ -929,24 +981,22 @@ impl<T: Default, E> Result<T, E> {
 
 #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T: Deref, E> Result<T, E> {
-    /// Converts from `&Result<T, E>` to `Result<&T::Target, &E>`.
+    /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T::Target, &E>`.
     ///
-    /// Leaves the original Result in-place, creating a new one with a reference
-    /// to the original one, additionally coercing the `Ok` arm of the Result via
-    /// `Deref`.
-    pub fn deref_ok(&self) -> Result<&T::Target, &E> {
+    /// Leaves the original `Result` in-place, creating a new one containing a reference to the
+    /// `Ok` type's `Deref::Target` type.
+    pub fn as_deref_ok(&self) -> Result<&T::Target, &E> {
         self.as_ref().map(|t| t.deref())
     }
 }
 
 #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T, E: Deref> Result<T, E> {
-    /// Converts from `&Result<T, E>` to `Result<&T, &E::Target>`.
+    /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T, &E::Target>`.
     ///
-    /// Leaves the original Result in-place, creating a new one with a reference
-    /// to the original one, additionally coercing the `Err` arm of the Result via
-    /// `Deref`.
-    pub fn deref_err(&self) -> Result<&T, &E::Target>
+    /// Leaves the original `Result` in-place, creating a new one containing a reference to the
+    /// `Err` type's `Deref::Target` type.
+    pub fn as_deref_err(&self) -> Result<&T, &E::Target>
     {
         self.as_ref().map_err(|e| e.deref())
     }
@@ -954,17 +1004,52 @@ impl<T, E: Deref> Result<T, E> {
 
 #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T: Deref, E: Deref> Result<T, E> {
-    /// Converts from `&Result<T, E>` to `Result<&T::Target, &E::Target>`.
+    /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T::Target, &E::Target>`.
     ///
-    /// Leaves the original Result in-place, creating a new one with a reference
-    /// to the original one, additionally coercing both the `Ok` and `Err` arms
-    /// of the Result via `Deref`.
-    pub fn deref(&self) -> Result<&T::Target, &E::Target>
+    /// Leaves the original `Result` in-place, creating a new one containing a reference to both
+    /// the `Ok` and `Err` types' `Deref::Target` types.
+    pub fn as_deref(&self) -> Result<&T::Target, &E::Target>
     {
         self.as_ref().map(|t| t.deref()).map_err(|e| e.deref())
     }
 }
 
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T: DerefMut, E> Result<T, E> {
+    /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T::Target, &mut E>`.
+    ///
+    /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
+    /// the `Ok` type's `Deref::Target` type.
+    pub fn as_deref_mut_ok(&mut self) -> Result<&mut T::Target, &mut E> {
+        self.as_mut().map(|t| t.deref_mut())
+    }
+}
+
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T, E: DerefMut> Result<T, E> {
+    /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T, &mut E::Target>`.
+    ///
+    /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
+    /// the `Err` type's `Deref::Target` type.
+    pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target>
+    {
+        self.as_mut().map_err(|e| e.deref_mut())
+    }
+}
+
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T: DerefMut, E: DerefMut> Result<T, E> {
+    /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to
+    /// `Result<&mut T::Target, &mut E::Target>`.
+    ///
+    /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
+    /// both the `Ok` and `Err` types' `Deref::Target` types.
+    pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E::Target>
+    {
+        self.as_mut().map(|t| t.deref_mut()).map_err(|e| e.deref_mut())
+    }
+}
+
 impl<T, E> Result<Option<T>, E> {
     /// Transposes a `Result` of an `Option` into an `Option` of a `Result`.
     ///
@@ -995,7 +1080,7 @@ impl<T, E> Result<Option<T>, E> {
 // This is a separate function to reduce the code size of the methods
 #[inline(never)]
 #[cold]
-fn unwrap_failed<E: fmt::Debug>(msg: &str, error: E) -> ! {
+fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! {
     panic!("{}: {:?}", msg, error)
 }
 
@@ -1004,6 +1089,27 @@ fn unwrap_failed<E: fmt::Debug>(msg: &str, error: E) -> ! {
 /////////////////////////////////////////////////////////////////////////////
 
 #[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Clone, E: Clone> Clone for Result<T, E> {
+    #[inline]
+    fn clone(&self) -> Self {
+        match self {
+            Ok(x) => Ok(x.clone()),
+            Err(x) => Err(x.clone()),
+        }
+    }
+
+    #[inline]
+    fn clone_from(&mut self, source: &Self) {
+        match (self, source) {
+            (Ok(to), Ok(from)) => to.clone_from(from),
+            (Err(to), Err(from)) => to.clone_from(from),
+            (to, from) => *to = from.clone(),
+        }
+    }
+}
+
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T, E> IntoIterator for Result<T, E> {
     type Item = T;
     type IntoIter = IntoIter<T>;
@@ -1237,39 +1343,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
         // FIXME(#11084): This could be replaced with Iterator::scan when this
         // performance bug is closed.
 
-        struct Adapter<Iter, E> {
-            iter: Iter,
-            err: Option<E>,
-        }
-
-        impl<T, E, Iter: Iterator<Item=Result<T, E>>> Iterator for Adapter<Iter, E> {
-            type Item = T;
-
-            #[inline]
-            fn next(&mut self) -> Option<T> {
-                match self.iter.next() {
-                    Some(Ok(value)) => Some(value),
-                    Some(Err(err)) => {
-                        self.err = Some(err);
-                        None
-                    }
-                    None => None,
-                }
-            }
-
-            fn size_hint(&self) -> (usize, Option<usize>) {
-                let (_min, max) = self.iter.size_hint();
-                (0, max)
-            }
-        }
-
-        let mut adapter = Adapter { iter: iter.into_iter(), err: None };
-        let v: V = FromIterator::from_iter(adapter.by_ref());
-
-        match adapter.err {
-            Some(err) => Err(err),
-            None => Ok(v),
-        }
+        iter::process_results(iter.into_iter(), |i| i.collect())
     }
 }
 
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index d06d107d32a..ce5af13d4ca 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -25,7 +25,7 @@
 use crate::cmp::Ordering::{self, Less, Equal, Greater};
 use crate::cmp;
 use crate::fmt;
-use crate::intrinsics::assume;
+use crate::intrinsics::{assume, exact_div, unchecked_sub, is_aligned_and_not_null};
 use crate::isize;
 use crate::iter::*;
 use crate::ops::{FnMut, Try, self};
@@ -45,19 +45,6 @@ pub mod memchr;
 mod rotate;
 mod sort;
 
-#[repr(C)]
-union Repr<'a, T: 'a> {
-    rust: &'a [T],
-    rust_mut: &'a mut [T],
-    raw: FatPtr<T>,
-}
-
-#[repr(C)]
-struct FatPtr<T> {
-    data: *const T,
-    len: usize,
-}
-
 //
 // Extension traits
 //
@@ -78,7 +65,7 @@ impl<T> [T] {
     #[rustc_const_unstable(feature = "const_slice_len")]
     pub const fn len(&self) -> usize {
         unsafe {
-            Repr { rust: self }.raw.len
+            crate::ptr::Repr { rust: self }.raw.len
         }
     }
 
@@ -305,10 +292,13 @@ impl<T> [T] {
     /// Returns a reference to an element or subslice, without doing bounds
     /// checking.
     ///
-    /// This is generally not recommended, use with caution! For a safe
-    /// alternative see [`get`].
+    /// This is generally not recommended, use with caution!
+    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
+    /// even if the resulting reference is not used.
+    /// For a safe alternative see [`get`].
     ///
     /// [`get`]: #method.get
+    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
     ///
     /// # Examples
     ///
@@ -330,10 +320,13 @@ impl<T> [T] {
     /// Returns a mutable reference to an element or subslice, without doing
     /// bounds checking.
     ///
-    /// This is generally not recommended, use with caution! For a safe
-    /// alternative see [`get_mut`].
+    /// This is generally not recommended, use with caution!
+    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
+    /// even if the resulting reference is not used.
+    /// For a safe alternative see [`get_mut`].
     ///
     /// [`get_mut`]: #method.get_mut
+    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
     ///
     /// # Examples
     ///
@@ -624,7 +617,7 @@ impl<T> [T] {
     ///
     /// See [`chunks_exact`] for a variant of this iterator that returns chunks of always exactly
     /// `chunk_size` elements, and [`rchunks`] for the same iterator but starting at the end of the
-    /// slice of the slice.
+    /// slice.
     ///
     /// # Panics
     ///
@@ -658,7 +651,7 @@ impl<T> [T] {
     ///
     /// See [`chunks_exact_mut`] for a variant of this iterator that returns chunks of always
     /// exactly `chunk_size` elements, and [`rchunks_mut`] for the same iterator but starting at
-    /// the end of the slice of the slice.
+    /// the end of the slice.
     ///
     /// # Panics
     ///
@@ -740,7 +733,7 @@ impl<T> [T] {
     ///
     /// See [`chunks_mut`] for a variant of this iterator that also returns the remainder as a
     /// smaller chunk, and [`rchunks_exact_mut`] for the same iterator but starting at the end of
-    /// the slice of the slice.
+    /// the slice.
     ///
     /// # Panics
     ///
@@ -1276,6 +1269,15 @@ impl<T> [T] {
     /// assert!(v.contains(&30));
     /// assert!(!v.contains(&50));
     /// ```
+    ///
+    /// If you do not have an `&T`, but just an `&U` such that `T: Borrow<U>`
+    /// (e.g. `String: Borrow<str>`), you can use `iter().any`:
+    ///
+    /// ```
+    /// let v = [String::from("hello"), String::from("world")]; // slice of `String`
+    /// assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+    /// assert!(!v.iter().any(|e| e == "hi"));
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains(&self, x: &T) -> bool
         where T: PartialEq
@@ -1362,6 +1364,17 @@ impl<T> [T] {
     /// let r = s.binary_search(&1);
     /// assert!(match r { Ok(1..=4) => true, _ => false, });
     /// ```
+    ///
+    /// If you want to insert an item to a sorted vector, while maintaining
+    /// sort order:
+    ///
+    /// ```
+    /// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+    /// let num = 42;
+    /// let idx = s.binary_search(&num).unwrap_or_else(|x| x);
+    /// s.insert(idx, num);
+    /// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn binary_search(&self, x: &T) -> Result<usize, usize>
         where T: Ord
@@ -2146,14 +2159,13 @@ impl<T> [T] {
     /// Copying four bytes within a slice:
     ///
     /// ```
-    /// # #![feature(copy_within)]
     /// let mut bytes = *b"Hello, World!";
     ///
     /// bytes.copy_within(1..5, 8);
     ///
     /// assert_eq!(&bytes, b"Hello, Wello!");
     /// ```
-    #[unstable(feature = "copy_within", issue = "54236")]
+    #[stable(feature = "copy_within", since = "1.37.0")]
     pub fn copy_within<R: ops::RangeBounds<usize>>(&mut self, src: R, dest: usize)
     where
         T: Copy,
@@ -2178,8 +2190,8 @@ impl<T> [T] {
         assert!(dest <= self.len() - count, "dest is out of bounds");
         unsafe {
             ptr::copy(
-                self.get_unchecked(src_start),
-                self.get_unchecked_mut(dest),
+                self.as_ptr().add(src_start),
+                self.as_mut_ptr().add(dest),
                 count,
             );
         }
@@ -2307,9 +2319,10 @@ impl<T> [T] {
     /// maintained.
     ///
     /// This method splits the slice into three distinct slices: prefix, correctly aligned middle
-    /// slice of a new type, and the suffix slice. The method does a best effort to make the
-    /// middle slice the greatest length possible for a given type and input slice, but only
-    /// your algorithm's performance should depend on that, not its correctness.
+    /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
+    /// length possible for a given type and input slice, but only your algorithm's performance
+    /// should depend on that, not its correctness. It is permissible for all of the input data to
+    /// be returned as the prefix or suffix slice.
     ///
     /// This method has no purpose when either input element `T` or output element `U` are
     /// zero-sized and will return the original slice without splitting anything.
@@ -2360,9 +2373,10 @@ impl<T> [T] {
     /// maintained.
     ///
     /// This method splits the slice into three distinct slices: prefix, correctly aligned middle
-    /// slice of a new type, and the suffix slice. The method does a best effort to make the
-    /// middle slice the greatest length possible for a given type and input slice, but only
-    /// your algorithm's performance should depend on that, not its correctness.
+    /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
+    /// length possible for a given type and input slice, but only your algorithm's performance
+    /// should depend on that, not its correctness. It is permissible for all of the input data to
+    /// be returned as the prefix or suffix slice.
     ///
     /// This method has no purpose when either input element `T` or output element `U` are
     /// zero-sized and will return the original slice without splitting anything.
@@ -2473,12 +2487,12 @@ impl<T> [T] {
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
-    pub fn is_sorted_by_key<F, K>(&self, mut f: F) -> bool
+    pub fn is_sorted_by_key<F, K>(&self, f: F) -> bool
     where
         F: FnMut(&T) -> K,
         K: PartialOrd
     {
-        self.is_sorted_by(|a, b| f(a).partial_cmp(&f(b)))
+        self.iter().is_sorted_by_key(f)
     }
 }
 
@@ -2634,11 +2648,17 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
 
     /// Returns a shared reference to the output at this location, without
     /// performing any bounds checking.
+    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
+    /// even if the resulting reference is not used.
+    /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
     #[unstable(feature = "slice_index_methods", issue = "0")]
     unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
 
     /// Returns a mutable reference to the output at this location, without
     /// performing any bounds checking.
+    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
+    /// even if the resulting reference is not used.
+    /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
     #[unstable(feature = "slice_index_methods", issue = "0")]
     unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
 
@@ -2999,14 +3019,27 @@ macro_rules! is_empty {
 // unexpected way. (Tested by `codegen/slice-position-bounds-check`.)
 macro_rules! len {
     ($self: ident) => {{
+        #![allow(unused_unsafe)] // we're sometimes used within an unsafe block
+
         let start = $self.ptr;
-        let diff = ($self.end as usize).wrapping_sub(start as usize);
         let size = size_from_ptr(start);
         if size == 0 {
+            // This _cannot_ use `unchecked_sub` because we depend on wrapping
+            // to represent the length of long ZST slice iterators.
+            let diff = ($self.end as usize).wrapping_sub(start as usize);
             diff
         } else {
-            // Using division instead of `offset_from` helps LLVM remove bounds checks
-            diff / size
+            // We know that `start <= end`, so can do better than `offset_from`,
+            // which needs to deal in signed.  By setting appropriate flags here
+            // we can tell LLVM this, which helps it remove bounds checks.
+            // SAFETY: By the type invariant, `start <= end`
+            let diff = unsafe { unchecked_sub($self.end as usize, start as usize) };
+            // By also telling LLVM that the pointers are apart by an exact
+            // multiple of the type size, it can optimize `len() == 0` down to
+            // `start == end` instead of `(end - start) < size`.
+            // SAFETY: By the type invariant, the pointers are aligned so the
+            //         distance between them must be a multiple of pointee size
+            unsafe { exact_div(diff, size) }
         }
     }}
 }
@@ -3020,6 +3053,28 @@ macro_rules! iterator {
         {$( $mut_:tt )*},
         {$($extra:tt)*}
     ) => {
+        // Returns the first element and moves the start of the iterator forwards by 1.
+        // Greatly improves performance compared to an inlined function. The iterator
+        // must not be empty.
+        macro_rules! next_unchecked {
+            ($self: ident) => {& $( $mut_ )* *$self.post_inc_start(1)}
+        }
+
+        // Returns the last element and moves the end of the iterator backwards by 1.
+        // Greatly improves performance compared to an inlined function. The iterator
+        // must not be empty.
+        macro_rules! next_back_unchecked {
+            ($self: ident) => {& $( $mut_ )* *$self.pre_dec_end(1)}
+        }
+
+        // Shrinks the iterator when T is a ZST, by moving the end of the iterator
+        // backwards by `n`. `n` must not exceed `self.len()`.
+        macro_rules! zst_shrink {
+            ($self: ident, $n: ident) => {
+                $self.end = ($self.end as * $raw_mut u8).wrapping_offset(-$n) as * $raw_mut T;
+            }
+        }
+
         impl<'a, T> $name<'a, T> {
             // Helper function for creating a slice from the iterator.
             #[inline(always)]
@@ -3029,12 +3084,11 @@ macro_rules! iterator {
 
             // Helper function for moving the start of the iterator forwards by `offset` elements,
             // returning the old start.
-            // Unsafe because the offset must be in-bounds or one-past-the-end.
+            // Unsafe because the offset must not exceed `self.len()`.
             #[inline(always)]
             unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
                 if mem::size_of::<T>() == 0 {
-                    // This is *reducing* the length.  `ptr` never changes with ZST.
-                    self.end = (self.end as * $raw_mut u8).wrapping_offset(-offset) as * $raw_mut T;
+                    zst_shrink!(self, offset);
                     self.ptr
                 } else {
                     let old = self.ptr;
@@ -3045,11 +3099,11 @@ macro_rules! iterator {
 
             // Helper function for moving the end of the iterator backwards by `offset` elements,
             // returning the new end.
-            // Unsafe because the offset must be in-bounds or one-past-the-end.
+            // Unsafe because the offset must not exceed `self.len()`.
             #[inline(always)]
             unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
                 if mem::size_of::<T>() == 0 {
-                    self.end = (self.end as * $raw_mut u8).wrapping_offset(-offset) as * $raw_mut T;
+                    zst_shrink!(self, offset);
                     self.ptr
                 } else {
                     self.end = self.end.offset(-offset);
@@ -3086,7 +3140,7 @@ macro_rules! iterator {
                     if is_empty!(self) {
                         None
                     } else {
-                        Some(& $( $mut_ )* *self.post_inc_start(1))
+                        Some(next_unchecked!(self))
                     }
                 }
             }
@@ -3115,11 +3169,10 @@ macro_rules! iterator {
                     }
                     return None;
                 }
-                // We are in bounds. `offset` does the right thing even for ZSTs.
+                // We are in bounds. `post_inc_start` does the right thing even for ZSTs.
                 unsafe {
-                    let elem = Some(& $( $mut_ )* *self.ptr.add(n));
-                    self.post_inc_start((n as isize).wrapping_add(1));
-                    elem
+                    self.post_inc_start(n as isize);
+                    Some(next_unchecked!(self))
                 }
             }
 
@@ -3136,13 +3189,13 @@ macro_rules! iterator {
                 let mut accum = init;
                 unsafe {
                     while len!(self) >= 4 {
-                        accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?;
-                        accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?;
-                        accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?;
-                        accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?;
+                        accum = f(accum, next_unchecked!(self))?;
+                        accum = f(accum, next_unchecked!(self))?;
+                        accum = f(accum, next_unchecked!(self))?;
+                        accum = f(accum, next_unchecked!(self))?;
                     }
                     while !is_empty!(self) {
-                        accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?;
+                        accum = f(accum, next_unchecked!(self))?;
                     }
                 }
                 Try::from_ok(accum)
@@ -3213,12 +3266,26 @@ macro_rules! iterator {
                     if is_empty!(self) {
                         None
                     } else {
-                        Some(& $( $mut_ )* *self.pre_dec_end(1))
+                        Some(next_back_unchecked!(self))
                     }
                 }
             }
 
             #[inline]
+            fn nth_back(&mut self, n: usize) -> Option<$elem> {
+                if n >= len!(self) {
+                    // This iterator is now empty.
+                    self.end = self.ptr;
+                    return None;
+                }
+                // We are in bounds. `pre_dec_end` does the right thing even for ZSTs.
+                unsafe {
+                    self.pre_dec_end(n as isize);
+                    Some(next_back_unchecked!(self))
+                }
+            }
+
+            #[inline]
             fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
                 Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
             {
@@ -3226,14 +3293,14 @@ macro_rules! iterator {
                 let mut accum = init;
                 unsafe {
                     while len!(self) >= 4 {
-                        accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?;
-                        accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?;
-                        accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?;
-                        accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?;
+                        accum = f(accum, next_back_unchecked!(self))?;
+                        accum = f(accum, next_back_unchecked!(self))?;
+                        accum = f(accum, next_back_unchecked!(self))?;
+                        accum = f(accum, next_back_unchecked!(self))?;
                     }
                     // inlining is_empty everywhere makes a huge performance difference
                     while !is_empty!(self) {
-                        accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?;
+                        accum = f(accum, next_back_unchecked!(self))?;
                     }
                 }
                 Try::from_ok(accum)
@@ -3547,11 +3614,6 @@ impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool {
             (1, Some(self.v.len() + 1))
         }
     }
-
-    #[inline]
-    fn last(mut self) -> Option<Self::Item> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -3650,11 +3712,6 @@ impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {
             (1, Some(self.v.len() + 1))
         }
     }
-
-    #[inline]
-    fn last(mut self) -> Option<Self::Item> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -3720,11 +3777,6 @@ impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
-
-    #[inline]
-    fn last(mut self) -> Option<Self::Item> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
@@ -3789,11 +3841,6 @@ impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.inner.size_hint()
     }
-
-    #[inline]
-    fn last(mut self) -> Option<Self::Item> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
@@ -4178,6 +4225,24 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
             Some(snd)
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.len();
+        if n >= len {
+            self.v = &[];
+            None
+        } else {
+            let start = (len - 1 - n) * self.chunk_size;
+            let end = match start.checked_add(self.chunk_size) {
+                Some(res) => cmp::min(res, self.v.len()),
+                None => self.v.len(),
+            };
+            let nth_back = &self.v[start..end];
+            self.v = &self.v[..start];
+            Some(nth_back)
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -4299,6 +4364,25 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
             Some(tail)
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.len();
+        if n >= len {
+            self.v = &mut [];
+            None
+        } else {
+            let start = (len - 1 - n) * self.chunk_size;
+            let end = match start.checked_add(self.chunk_size) {
+                Some(res) => cmp::min(res, self.v.len()),
+                None => self.v.len(),
+            };
+            let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
+            let (head, nth_back) = temp.split_at_mut(start);
+            self.v = head;
+            Some(nth_back)
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -4422,6 +4506,21 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
             Some(snd)
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.len();
+        if n >= len {
+            self.v = &[];
+            None
+        } else {
+            let start = (len - 1 - n) * self.chunk_size;
+            let end = start + self.chunk_size;
+            let nth_back = &self.v[start..end];
+            self.v = &self.v[..start];
+            Some(nth_back)
+        }
+    }
 }
 
 #[stable(feature = "chunks_exact", since = "1.31.0")]
@@ -4669,6 +4768,23 @@ impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
             Some(fst)
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.len();
+        if n >= len {
+            self.v = &[];
+            None
+        } else {
+            // can't underflow because `n < len`
+            let offset_from_end = (len - 1 - n) * self.chunk_size;
+            let end = self.v.len() - offset_from_end;
+            let start = end.saturating_sub(self.chunk_size);
+            let nth_back = &self.v[start..end];
+            self.v = &self.v[end..];
+            Some(nth_back)
+        }
+    }
 }
 
 #[stable(feature = "rchunks", since = "1.31.0")]
@@ -4794,6 +4910,24 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
             Some(head)
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.len();
+        if n >= len {
+            self.v = &mut [];
+            None
+        } else {
+            // can't underflow because `n < len`
+            let offset_from_end = (len - 1 - n) * self.chunk_size;
+            let end = self.v.len() - offset_from_end;
+            let start = end.saturating_sub(self.chunk_size);
+            let (tmp, tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
+            let (_, nth_back) = tmp.split_at_mut(start);
+            self.v = tail;
+            Some(nth_back)
+        }
+    }
 }
 
 #[stable(feature = "rchunks", since = "1.31.0")]
@@ -4918,6 +5052,24 @@ impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
             Some(fst)
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.len();
+        if n >= len {
+            self.v = &[];
+            None
+        } else {
+            // now that we know that `n` corresponds to a chunk,
+            // none of these operations can underflow/overflow
+            let offset = (len - n) * self.chunk_size;
+            let start = self.v.len() - offset;
+            let end = start + self.chunk_size;
+            let nth_back = &self.v[start..end];
+            self.v = &self.v[end..];
+            Some(nth_back)
+        }
+    }
 }
 
 #[stable(feature = "rchunks", since = "1.31.0")]
@@ -5036,6 +5188,25 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
             Some(head)
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.len();
+        if n >= len {
+            self.v = &mut [];
+            None
+        } else {
+            // now that we know that `n` corresponds to a chunk,
+            // none of these operations can underflow/overflow
+            let offset = (len - n) * self.chunk_size;
+            let start = self.v.len() - offset;
+            let end = start + self.chunk_size;
+            let (tmp, tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
+            let (_, nth_back) = tmp.split_at_mut(start);
+            self.v = tail;
+            Some(nth_back)
+        }
+    }
 }
 
 #[stable(feature = "rchunks", since = "1.31.0")]
@@ -5110,10 +5281,10 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
-    debug_assert!(data as usize % mem::align_of::<T>() == 0, "attempt to create unaligned slice");
+    debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
     debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
                   "attempt to create slice covering half the address space");
-    Repr { raw: FatPtr { data, len } }.rust
+    &*ptr::slice_from_raw_parts(data, len)
 }
 
 /// Performs the same functionality as [`from_raw_parts`], except that a
@@ -5131,10 +5302,10 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
-    debug_assert!(data as usize % mem::align_of::<T>() == 0, "attempt to create unaligned slice");
+    debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
     debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
                   "attempt to create slice covering half the address space");
-    Repr { raw: FatPtr { data, len } }.rust_mut
+    &mut *ptr::slice_from_raw_parts_mut(data, len)
 }
 
 /// Converts a reference to T into a slice of length 1 (without copying).
@@ -5224,13 +5395,24 @@ impl<A, B> SlicePartialEq<B> for [A]
             return false;
         }
 
-        for i in 0..self.len() {
-            if !self[i].eq(&other[i]) {
-                return false;
-            }
+        self.iter().zip(other.iter()).all(|(x, y)| x == y)
+    }
+}
+
+// Use an equal-pointer optimization when types are `Eq`
+impl<A> SlicePartialEq<A> for [A]
+    where A: PartialEq<A> + Eq
+{
+    default fn equal(&self, other: &[A]) -> bool {
+        if self.len() != other.len() {
+            return false;
+        }
+
+        if self.as_ptr() == other.as_ptr() {
+            return true;
         }
 
-        true
+        self.iter().zip(other.iter()).all(|(x, y)| x == y)
     }
 }
 
@@ -5339,7 +5521,7 @@ impl SliceOrd<u8> for [u8] {
 #[doc(hidden)]
 /// Trait implemented for types that can be compared for equality using
 /// their bytewise representation
-trait BytewiseEquality { }
+trait BytewiseEquality: Eq + Copy { }
 
 macro_rules! impl_marker_for {
     ($traitname:ident, $($ty:ty)*) => {
@@ -5350,7 +5532,7 @@ macro_rules! impl_marker_for {
 }
 
 impl_marker_for!(BytewiseEquality,
-                 u8 i8 u16 i16 u32 i32 u64 i64 usize isize char bool);
+                 u8 i8 u16 i16 u32 i32 u64 i64 u128 i128 usize isize char bool);
 
 #[doc(hidden)]
 unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
diff --git a/src/libcore/slice/rotate.rs b/src/libcore/slice/rotate.rs
index f69b219715a..f73e14f27e0 100644
--- a/src/libcore/slice/rotate.rs
+++ b/src/libcore/slice/rotate.rs
@@ -2,32 +2,9 @@ use crate::cmp;
 use crate::mem::{self, MaybeUninit};
 use crate::ptr;
 
-/// Rotation is much faster if it has access to a little bit of memory. This
-/// union provides a RawVec-like interface, but to a fixed-size stack buffer.
-#[allow(unions_with_drop_fields)]
-union RawArray<T> {
-    /// Ensure this is appropriately aligned for T, and is big
-    /// enough for two elements even if T is enormous.
-    typed: [T; 2],
-    /// For normally-sized types, especially things like u8, having more
-    /// than 2 in the buffer is necessary for usefulness, so pad it out
-    /// enough to be helpful, but not so big as to risk overflow.
-    _extra: [usize; 32],
-}
-
-impl<T> RawArray<T> {
-    fn cap() -> usize {
-        if mem::size_of::<T>() == 0 {
-            usize::max_value()
-        } else {
-            mem::size_of::<Self>() / mem::size_of::<T>()
-        }
-    }
-}
-
-/// Rotates the range `[mid-left, mid+right)` such that the element at `mid`
-/// becomes the first element. Equivalently, rotates the range `left`
-/// elements to the left or `right` elements to the right.
+/// Rotates the range `[mid-left, mid+right)` such that the element at `mid` becomes the first
+/// element. Equivalently, rotates the range `left` elements to the left or `right` elements to the
+/// right.
 ///
 /// # Safety
 ///
@@ -35,55 +12,161 @@ impl<T> RawArray<T> {
 ///
 /// # Algorithm
 ///
-/// For longer rotations, swap the left-most `delta = min(left, right)`
-/// elements with the right-most `delta` elements. LLVM vectorizes this,
-/// which is profitable as we only reach this step for a "large enough"
-/// rotation. Doing this puts `delta` elements on the larger side into the
-/// correct position, leaving a smaller rotate problem. Demonstration:
-///
+/// Algorithm 1 is used for small values of `left + right` or for large `T`. The elements are moved
+/// into their final positions one at a time starting at `mid - left` and advancing by `right` steps
+/// modulo `left + right`, such that only one temporary is needed. Eventually, we arrive back at
+/// `mid - left`. However, if `gcd(left + right, right)` is not 1, the above steps skipped over
+/// elements. For example:
 /// ```text
-/// [ 6 7 8 9 10 11 12 13 . 1 2 3 4 5 ]
-/// 1 2 3 4 5 [ 11 12 13 . 6 7 8 9 10 ]
-/// 1 2 3 4 5 [ 8 9 10 . 6 7 ] 11 12 13
-/// 1 2 3 4 5 6 7 [ 10 . 8 9 ] 11 12 13
-/// 1 2 3 4 5 6 7 [ 9 . 8 ] 10 11 12 13
-/// 1 2 3 4 5 6 7 8 [ . ] 9 10 11 12 13
+/// left = 10, right = 6
+/// the `^` indicates an element in its final place
+/// 6 7 8 9 10 11 12 13 14 15 . 0 1 2 3 4 5
+/// after using one step of the above algorithm (The X will be overwritten at the end of the round,
+/// and 12 is stored in a temporary):
+/// X 7 8 9 10 11 6 13 14 15 . 0 1 2 3 4 5
+///               ^
+/// after using another step (now 2 is in the temporary):
+/// X 7 8 9 10 11 6 13 14 15 . 0 1 12 3 4 5
+///               ^                 ^
+/// after the third step (the steps wrap around, and 8 is in the temporary):
+/// X 7 2 9 10 11 6 13 14 15 . 0 1 12 3 4 5
+///     ^         ^                 ^
+/// after 7 more steps, the round ends with the temporary 0 getting put in the X:
+/// 0 7 2 9 4 11 6 13 8 15 . 10 1 12 3 14 5
+/// ^   ^   ^    ^    ^       ^    ^    ^
 /// ```
+/// Fortunately, the number of skipped over elements between finalized elements is always equal, so
+/// we can just offset our starting position and do more rounds (the total number of rounds is the
+/// `gcd(left + right, right)` value). The end result is that all elements are finalized once and
+/// only once.
+///
+/// Algorithm 2 is used if `left + right` is large but `min(left, right)` is small enough to
+/// fit onto a stack buffer. The `min(left, right)` elements are copied onto the buffer, `memmove`
+/// is applied to the others, and the ones on the buffer are moved back into the hole on the
+/// opposite side of where they originated.
+///
+/// Algorithms that can be vectorized outperform the above once `left + right` becomes large enough.
+/// Algorithm 1 can be vectorized by chunking and performing many rounds at once, but there are too
+/// few rounds on average until `left + right` is enormous, and the worst case of a single
+/// round is always there. Instead, algorithm 3 utilizes repeated swapping of
+/// `min(left, right)` elements until a smaller rotate problem is left.
 ///
-/// Once the rotation is small enough, copy some elements into a stack
-/// buffer, `memmove` the others, and move the ones back from the buffer.
-pub unsafe fn ptr_rotate<T>(mut left: usize, mid: *mut T, mut right: usize) {
+/// ```text
+/// left = 11, right = 4
+/// [4 5 6 7 8 9 10 11 12 13 14 . 0 1 2 3]
+///                  ^  ^  ^  ^   ^ ^ ^ ^ swapping the right most elements with elements to the left
+/// [4 5 6 7 8 9 10 . 0 1 2 3] 11 12 13 14
+///        ^ ^ ^  ^   ^ ^ ^ ^ swapping these
+/// [4 5 6 . 0 1 2 3] 7 8 9 10 11 12 13 14
+/// we cannot swap any more, but a smaller rotation problem is left to solve
+/// ```
+/// when `left < right` the swapping happens from the left instead.
+pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize) {
+    type BufType = [usize; 32];
+    if mem::size_of::<T>() == 0 {
+        return;
+    }
     loop {
-        let delta = cmp::min(left, right);
-        if delta <= RawArray::<T>::cap() {
-            // We will always hit this immediately for ZST.
-            break;
+        // N.B. the below algorithms can fail if these cases are not checked
+        if (right == 0) || (left == 0) {
+            return;
         }
-
-        ptr::swap_nonoverlapping(
-            mid.sub(left),
-            mid.add(right - delta),
-            delta);
-
-        if left <= right {
-            right -= delta;
+        if (left + right < 24) || (mem::size_of::<T>() > mem::size_of::<[usize; 4]>()) {
+            // Algorithm 1
+            // Microbenchmarks indicate that the average performance for random shifts is better all
+            // the way until about `left + right == 32`, but the worst case performance breaks even
+            // around 16. 24 was chosen as middle ground. If the size of `T` is larger than 4
+            // `usize`s, this algorithm also outperforms other algorithms.
+            let x = mid.sub(left);
+            // beginning of first round
+            let mut tmp: T = x.read();
+            let mut i = right;
+            // `gcd` can be found before hand by calculating `gcd(left + right, right)`,
+            // but it is faster to do one loop which calculates the gcd as a side effect, then
+            // doing the rest of the chunk
+            let mut gcd = right;
+            // benchmarks reveal that it is faster to swap temporaries all the way through instead
+            // of reading one temporary once, copying backwards, and then writing that temporary at
+            // the very end. This is possibly due to the fact that swapping or replacing temporaries
+            // uses only one memory address in the loop instead of needing to manage two.
+            loop {
+                tmp = x.add(i).replace(tmp);
+                // instead of incrementing `i` and then checking if it is outside the bounds, we
+                // check if `i` will go outside the bounds on the next increment. This prevents
+                // any wrapping of pointers or `usize`.
+                if i >= left {
+                    i -= left;
+                    if i == 0 {
+                        // end of first round
+                        x.write(tmp);
+                        break;
+                    }
+                    // this conditional must be here if `left + right >= 15`
+                    if i < gcd {
+                        gcd = i;
+                    }
+                } else {
+                    i += right;
+                }
+            }
+            // finish the chunk with more rounds
+            for start in 1..gcd {
+                tmp = x.add(start).read();
+                i = start + right;
+                loop {
+                    tmp = x.add(i).replace(tmp);
+                    if i >= left {
+                        i -= left;
+                        if i == start {
+                            x.add(start).write(tmp);
+                            break;
+                        }
+                    } else {
+                        i += right;
+                    }
+                }
+            }
+            return;
+        // `T` is not a zero-sized type, so it's okay to divide by its size.
+        } else if cmp::min(left, right) <= mem::size_of::<BufType>() / mem::size_of::<T>() {
+            // Algorithm 2
+            // The `[T; 0]` here is to ensure this is appropriately aligned for T
+            let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit();
+            let buf = rawarray.as_mut_ptr() as *mut T;
+            let dim = mid.sub(left).add(right);
+            if left <= right {
+                ptr::copy_nonoverlapping(mid.sub(left), buf, left);
+                ptr::copy(mid, mid.sub(left), right);
+                ptr::copy_nonoverlapping(buf, dim, left);
+            } else {
+                ptr::copy_nonoverlapping(mid, buf, right);
+                ptr::copy(mid.sub(left), dim, left);
+                ptr::copy_nonoverlapping(buf, mid.sub(left), right);
+            }
+            return;
+        } else if left >= right {
+            // Algorithm 3
+            // There is an alternate way of swapping that involves finding where the last swap
+            // of this algorithm would be, and swapping using that last chunk instead of swapping
+            // adjacent chunks like this algorithm is doing, but this way is still faster.
+            loop {
+                ptr::swap_nonoverlapping(mid.sub(right), mid, right);
+                mid = mid.sub(right);
+                left -= right;
+                if left < right {
+                    break;
+                }
+            }
         } else {
-            left -= delta;
+            // Algorithm 3, `left < right`
+            loop {
+                ptr::swap_nonoverlapping(mid.sub(left), mid, left);
+                mid = mid.add(left);
+                right -= left;
+                if right < left {
+                    break;
+                }
+            }
         }
     }
-
-    let mut rawarray = MaybeUninit::<RawArray<T>>::uninit();
-    let buf = &mut (*rawarray.as_mut_ptr()).typed as *mut [T; 2] as *mut T;
-
-    let dim = mid.sub(left).add(right);
-    if left <= right {
-        ptr::copy_nonoverlapping(mid.sub(left), buf, left);
-        ptr::copy(mid, mid.sub(left), right);
-        ptr::copy_nonoverlapping(buf, dim, left);
-    }
-    else {
-        ptr::copy_nonoverlapping(mid, buf, right);
-        ptr::copy(mid.sub(left), dim, left);
-        ptr::copy_nonoverlapping(buf, mid.sub(left), right);
-    }
 }
diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs
index c293b190018..2f2170f7ff1 100644
--- a/src/libcore/slice/sort.rs
+++ b/src/libcore/slice/sort.rs
@@ -216,14 +216,14 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
     let mut block_l = BLOCK;
     let mut start_l = ptr::null_mut();
     let mut end_l = ptr::null_mut();
-    let mut offsets_l: [MaybeUninit<u8>; BLOCK] = uninitialized_array![u8; BLOCK];
+    let mut offsets_l = [MaybeUninit::<u8>::uninit(); BLOCK];
 
     // The current block on the right side (from `r.sub(block_r)` to `r`).
     let mut r = unsafe { l.add(v.len()) };
     let mut block_r = BLOCK;
     let mut start_r = ptr::null_mut();
     let mut end_r = ptr::null_mut();
-    let mut offsets_r: [MaybeUninit<u8>; BLOCK] = uninitialized_array![u8; BLOCK];
+    let mut offsets_r = [MaybeUninit::<u8>::uninit(); BLOCK];
 
     // FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather
     // than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient.
diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs
index b291579553a..e8f747f1a67 100644
--- a/src/libcore/str/lossy.rs
+++ b/src/libcore/str/lossy.rs
@@ -46,7 +46,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {
     type Item = Utf8LossyChunk<'a>;
 
     fn next(&mut self) -> Option<Utf8LossyChunk<'a>> {
-        if self.source.len() == 0 {
+        if self.source.is_empty() {
             return None;
         }
 
@@ -141,7 +141,7 @@ impl fmt::Display for Utf8Lossy {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // If we're the empty string then our iterator won't actually yield
         // anything, so perform the formatting manually
-        if self.bytes.len() == 0 {
+        if self.bytes.is_empty() {
             return "".fmt(f)
         }
 
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 0e8a2da3c11..f20cb7bfbc3 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -464,7 +464,7 @@ Section: Iterators
 ///
 /// [`chars`]: ../../std/primitive.str.html#method.chars
 /// [`str`]: ../../std/primitive.str.html
-#[derive(Clone, Debug)]
+#[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Chars<'a> {
     iter: slice::Iter<'a, u8>
@@ -600,6 +600,16 @@ impl<'a> Iterator for Chars<'a> {
     }
 }
 
+#[stable(feature = "chars_debug_impl", since = "1.38.0")]
+impl fmt::Debug for Chars<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "Chars(")?;
+        f.debug_list().entries(self.clone()).finish()?;
+        write!(f, ")")?;
+        Ok(())
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> DoubleEndedIterator for Chars<'a> {
     #[inline]
@@ -841,8 +851,9 @@ unsafe impl TrustedRandomAccess for Bytes<'_> {
 /// wrapper types of the form X<'a, P>
 macro_rules! derive_pattern_clone {
     (clone $t:ident with |$s:ident| $e:expr) => {
-        impl<'a, P: Pattern<'a>> Clone for $t<'a, P>
-            where P::Searcher: Clone
+        impl<'a, P> Clone for $t<'a, P>
+        where
+            P: Pattern<'a, Searcher: Clone>,
         {
             fn clone(&self) -> Self {
                 let $s = self;
@@ -918,8 +929,9 @@ macro_rules! generate_pattern_iterators {
         pub struct $forward_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>);
 
         $(#[$common_stability_attribute])*
-        impl<'a, P: Pattern<'a>> fmt::Debug for $forward_iterator<'a, P>
-            where P::Searcher: fmt::Debug
+        impl<'a, P> fmt::Debug for $forward_iterator<'a, P>
+        where
+            P: Pattern<'a, Searcher: fmt::Debug>,
         {
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 f.debug_tuple(stringify!($forward_iterator))
@@ -939,8 +951,9 @@ macro_rules! generate_pattern_iterators {
         }
 
         $(#[$common_stability_attribute])*
-        impl<'a, P: Pattern<'a>> Clone for $forward_iterator<'a, P>
-            where P::Searcher: Clone
+        impl<'a, P> Clone for $forward_iterator<'a, P>
+        where
+            P: Pattern<'a, Searcher: Clone>,
         {
             fn clone(&self) -> Self {
                 $forward_iterator(self.0.clone())
@@ -952,8 +965,9 @@ macro_rules! generate_pattern_iterators {
         pub struct $reverse_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>);
 
         $(#[$common_stability_attribute])*
-        impl<'a, P: Pattern<'a>> fmt::Debug for $reverse_iterator<'a, P>
-            where P::Searcher: fmt::Debug
+        impl<'a, P> fmt::Debug for $reverse_iterator<'a, P>
+        where
+            P: Pattern<'a, Searcher: fmt::Debug>,
         {
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 f.debug_tuple(stringify!($reverse_iterator))
@@ -963,8 +977,9 @@ macro_rules! generate_pattern_iterators {
         }
 
         $(#[$common_stability_attribute])*
-        impl<'a, P: Pattern<'a>> Iterator for $reverse_iterator<'a, P>
-            where P::Searcher: ReverseSearcher<'a>
+        impl<'a, P> Iterator for $reverse_iterator<'a, P>
+        where
+            P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
         {
             type Item = $iterty;
 
@@ -975,8 +990,9 @@ macro_rules! generate_pattern_iterators {
         }
 
         $(#[$common_stability_attribute])*
-        impl<'a, P: Pattern<'a>> Clone for $reverse_iterator<'a, P>
-            where P::Searcher: Clone
+        impl<'a, P> Clone for $reverse_iterator<'a, P>
+        where
+            P: Pattern<'a, Searcher: Clone>,
         {
             fn clone(&self) -> Self {
                 $reverse_iterator(self.0.clone())
@@ -987,8 +1003,10 @@ macro_rules! generate_pattern_iterators {
         impl<'a, P: Pattern<'a>> FusedIterator for $forward_iterator<'a, P> {}
 
         #[stable(feature = "fused", since = "1.26.0")]
-        impl<'a, P: Pattern<'a>> FusedIterator for $reverse_iterator<'a, P>
-            where P::Searcher: ReverseSearcher<'a> {}
+        impl<'a, P> FusedIterator for $reverse_iterator<'a, P>
+        where
+            P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+        {}
 
         generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*,
                                                 $forward_iterator,
@@ -1000,8 +1018,9 @@ macro_rules! generate_pattern_iterators {
                            $reverse_iterator:ident, $iterty:ty
     } => {
         $(#[$common_stability_attribute])*
-        impl<'a, P: Pattern<'a>> DoubleEndedIterator for $forward_iterator<'a, P>
-            where P::Searcher: DoubleEndedSearcher<'a>
+        impl<'a, P> DoubleEndedIterator for $forward_iterator<'a, P>
+        where
+            P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
         {
             #[inline]
             fn next_back(&mut self) -> Option<$iterty> {
@@ -1010,8 +1029,9 @@ macro_rules! generate_pattern_iterators {
         }
 
         $(#[$common_stability_attribute])*
-        impl<'a, P: Pattern<'a>> DoubleEndedIterator for $reverse_iterator<'a, P>
-            where P::Searcher: DoubleEndedSearcher<'a>
+        impl<'a, P> DoubleEndedIterator for $reverse_iterator<'a, P>
+        where
+            P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
         {
             #[inline]
             fn next_back(&mut self) -> Option<$iterty> {
@@ -1039,7 +1059,10 @@ struct SplitInternal<'a, P: Pattern<'a>> {
     finished: bool,
 }
 
-impl<'a, P: Pattern<'a>> fmt::Debug for SplitInternal<'a, P> where P::Searcher: fmt::Debug {
+impl<'a, P> fmt::Debug for SplitInternal<'a, P>
+where
+    P: Pattern<'a, Searcher: fmt::Debug>,
+{
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SplitInternal")
             .field("start", &self.start)
@@ -1156,7 +1179,10 @@ struct SplitNInternal<'a, P: Pattern<'a>> {
     count: usize,
 }
 
-impl<'a, P: Pattern<'a>> fmt::Debug for SplitNInternal<'a, P> where P::Searcher: fmt::Debug {
+impl<'a, P> fmt::Debug for SplitNInternal<'a, P>
+where
+    P: Pattern<'a, Searcher: fmt::Debug>,
+{
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SplitNInternal")
             .field("iter", &self.iter)
@@ -1212,7 +1238,10 @@ derive_pattern_clone!{
 
 struct MatchIndicesInternal<'a, P: Pattern<'a>>(P::Searcher);
 
-impl<'a, P: Pattern<'a>> fmt::Debug for MatchIndicesInternal<'a, P> where P::Searcher: fmt::Debug {
+impl<'a, P> fmt::Debug for MatchIndicesInternal<'a, P>
+where
+    P: Pattern<'a, Searcher: fmt::Debug>,
+{
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("MatchIndicesInternal")
             .field(&self.0)
@@ -1263,7 +1292,10 @@ derive_pattern_clone!{
 
 struct MatchesInternal<'a, P: Pattern<'a>>(P::Searcher);
 
-impl<'a, P: Pattern<'a>> fmt::Debug for MatchesInternal<'a, P> where P::Searcher: fmt::Debug {
+impl<'a, P> fmt::Debug for MatchesInternal<'a, P>
+where
+    P: Pattern<'a, Searcher: fmt::Debug>,
+{
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("MatchesInternal")
             .field(&self.0)
@@ -1335,7 +1367,7 @@ impl<'a> Iterator for Lines<'a> {
     }
 
     #[inline]
-    fn last(mut self) -> Option<Self::Item> {
+    fn last(mut self) -> Option<&'a str> {
         self.next_back()
     }
 }
@@ -1384,11 +1416,6 @@ impl<'a> Iterator for LinesAny<'a> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.0.size_hint()
     }
-
-    #[inline]
-    fn last(mut self) -> Option<Self::Item> {
-        self.next_back()
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1427,6 +1454,7 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
     let usize_bytes = mem::size_of::<usize>();
     let ascii_block_size = 2 * usize_bytes;
     let blocks_end = if len >= ascii_block_size { len - ascii_block_size + 1 } else { 0 };
+    let align = v.as_ptr().align_offset(usize_bytes);
 
     while index < len {
         let old_offset = index;
@@ -1506,12 +1534,8 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
             // Ascii case, try to skip forward quickly.
             // When the pointer is aligned, read 2 words of data per iteration
             // until we find a word containing a non-ascii byte.
-            let ptr = v.as_ptr();
-            let align = unsafe {
-                // the offset is safe, because `index` is guaranteed inbounds
-                ptr.add(index).align_offset(usize_bytes)
-            };
-            if align == 0 {
+            if align != usize::max_value() && align.wrapping_sub(index) % usize_bytes == 0 {
+                let ptr = v.as_ptr();
                 while index < blocks_end {
                     unsafe {
                         let block = ptr.add(index) as *const usize;
@@ -2880,8 +2904,9 @@ impl str {
     /// assert!(!bananas.ends_with("nana"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
-        where P::Searcher: ReverseSearcher<'a>
+    pub fn ends_with<'a, P>(&'a self, pat: P) -> bool
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         pat.is_suffix_of(self)
     }
@@ -2973,8 +2998,9 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
-        where P::Searcher: ReverseSearcher<'a>
+    pub fn rfind<'a, P>(&'a self, pat: P) -> Option<usize>
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         pat.into_searcher(self).next_match_back().map(|(i, _)| i)
     }
@@ -3140,8 +3166,9 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
+    pub fn rsplit<'a, P>(&'a self, pat: P) -> RSplit<'a, P>
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         RSplit(self.split(pat).0)
     }
@@ -3231,8 +3258,9 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
+    pub fn rsplit_terminator<'a, P>(&'a self, pat: P) -> RSplitTerminator<'a, P>
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         RSplitTerminator(self.split_terminator(pat).0)
     }
@@ -3331,8 +3359,9 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
+    pub fn rsplitn<'a, P>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         RSplitN(self.splitn(n, pat).0)
     }
@@ -3404,8 +3433,9 @@ impl str {
     /// ```
     #[stable(feature = "str_matches", since = "1.2.0")]
     #[inline]
-    pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
+    pub fn rmatches<'a, P>(&'a self, pat: P) -> RMatches<'a, P>
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         RMatches(self.matches(pat).0)
     }
@@ -3489,8 +3519,9 @@ impl str {
     /// ```
     #[stable(feature = "str_match_indices", since = "1.5.0")]
     #[inline]
-    pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
+    pub fn rmatch_indices<'a, P>(&'a self, pat: P) -> RMatchIndices<'a, P>
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         RMatchIndices(self.match_indices(pat).0)
     }
@@ -3698,8 +3729,9 @@ impl str {
     #[must_use = "this returns the trimmed string as a new slice, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
-        where P::Searcher: DoubleEndedSearcher<'a>
+    pub fn trim_matches<'a, P>(&'a self, pat: P) -> &'a str
+    where
+        P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,
     {
         let mut i = 0;
         let mut j = 0;
@@ -3726,10 +3758,10 @@ impl str {
     ///
     /// # Text directionality
     ///
-    /// A string is a sequence of bytes. 'Left' in this context means the first
-    /// position of that byte string; for a language like Arabic or Hebrew
-    /// which are 'right to left' rather than 'left to right', this will be
-    /// the _right_ side, not the left.
+    /// A string is a sequence of bytes. `start` in this context means the first
+    /// position of that byte string; for a left-to-right language like English or
+    /// Russian, this will be left side, and for right-to-left languages like
+    /// like Arabic or Hebrew, this will be the right side.
     ///
     /// # Examples
     ///
@@ -3765,10 +3797,10 @@ impl str {
     ///
     /// # Text directionality
     ///
-    /// A string is a sequence of bytes. 'Right' in this context means the last
-    /// position of that byte string; for a language like Arabic or Hebrew
-    /// which are 'right to left' rather than 'left to right', this will be
-    /// the _left_ side, not the right.
+    /// A string is a sequence of bytes. `end` in this context means the last
+    /// position of that byte string; for a left-to-right language like English or
+    /// Russian, this will be right side, and for right-to-left languages like
+    /// like Arabic or Hebrew, this will be the left side.
     ///
     /// # Examples
     ///
@@ -3790,8 +3822,9 @@ impl str {
     #[must_use = "this returns the trimmed string as a new slice, \
                   without modifying the original"]
     #[stable(feature = "trim_direction", since = "1.30.0")]
-    pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
-        where P::Searcher: ReverseSearcher<'a>
+    pub fn trim_end_matches<'a, P>(&'a self, pat: P) -> &'a str
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         let mut j = 0;
         let mut matcher = pat.into_searcher(self);
@@ -3814,10 +3847,10 @@ impl str {
     ///
     /// # Text directionality
     ///
-    /// A string is a sequence of bytes. `start` in this context means the first
-    /// position of that byte string; for a left-to-right language like English or
-    /// Russian, this will be left side, and for right-to-left languages like
-    /// like Arabic or Hebrew, this will be the right side.
+    /// A string is a sequence of bytes. 'Left' in this context means the first
+    /// position of that byte string; for a language like Arabic or Hebrew
+    /// which are 'right to left' rather than 'left to right', this will be
+    /// the _right_ side, not the left.
     ///
     /// # Examples
     ///
@@ -3850,10 +3883,10 @@ impl str {
     ///
     /// # Text directionality
     ///
-    /// A string is a sequence of bytes. `end` in this context means the last
-    /// position of that byte string; for a left-to-right language like English or
-    /// Russian, this will be right side, and for right-to-left languages like
-    /// like Arabic or Hebrew, this will be the left side.
+    /// A string is a sequence of bytes. 'Right' in this context means the last
+    /// position of that byte string; for a language like Arabic or Hebrew
+    /// which are 'right to left' rather than 'left to right', this will be
+    /// the _left_ side, not the right.
     ///
     /// # Examples
     ///
@@ -3878,8 +3911,9 @@ impl str {
         reason = "superseded by `trim_end_matches`",
         suggestion = "trim_end_matches",
     )]
-    pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
-        where P::Searcher: ReverseSearcher<'a>
+    pub fn trim_right_matches<'a, P>(&'a self, pat: P) -> &'a str
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         self.trim_end_matches(pat)
     }
@@ -3981,6 +4015,16 @@ impl str {
     /// [`to_ascii_uppercase`].
     ///
     /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut s = String::from("Grüße, Jürgen ❤");
+    ///
+    /// s.make_ascii_uppercase();
+    ///
+    /// assert_eq!("GRüßE, JüRGEN ❤", s);
+    /// ```
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     pub fn make_ascii_uppercase(&mut self) {
         let me = unsafe { self.as_bytes_mut() };
@@ -3996,6 +4040,16 @@ impl str {
     /// [`to_ascii_lowercase`].
     ///
     /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut s = String::from("GRÜßE, JÜRGEN ❤");
+    ///
+    /// s.make_ascii_lowercase();
+    ///
+    /// assert_eq!("grÜße, jÜrgen ❤", s);
+    /// ```
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     pub fn make_ascii_lowercase(&mut self) {
         let me = unsafe { self.as_bytes_mut() };
@@ -4233,7 +4287,7 @@ impl<'a> Iterator for SplitWhitespace<'a> {
     }
 
     #[inline]
-    fn last(mut self) -> Option<Self::Item> {
+    fn last(mut self) -> Option<&'a str> {
         self.next_back()
     }
 }
@@ -4264,7 +4318,7 @@ impl<'a> Iterator for SplitAsciiWhitespace<'a> {
     }
 
     #[inline]
-    fn last(mut self) -> Option<Self::Item> {
+    fn last(mut self) -> Option<&'a str> {
         self.next_back()
     }
 }
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 12414980d76..8dfb19fa032 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -1899,7 +1899,7 @@ atomic_int! {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "i8", "../../../std/primitive.i8.html",
-    "#![feature(integer_atomics)]\n\n",
+    "",
     atomic_min, atomic_max,
     1,
     "AtomicI8::new(0)",
@@ -1915,7 +1915,7 @@ atomic_int! {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "u8", "../../../std/primitive.u8.html",
-    "#![feature(integer_atomics)]\n\n",
+    "",
     atomic_umin, atomic_umax,
     1,
     "AtomicU8::new(0)",
@@ -1931,7 +1931,7 @@ atomic_int! {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "i16", "../../../std/primitive.i16.html",
-    "#![feature(integer_atomics)]\n\n",
+    "",
     atomic_min, atomic_max,
     2,
     "AtomicI16::new(0)",
@@ -1947,7 +1947,7 @@ atomic_int! {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "u16", "../../../std/primitive.u16.html",
-    "#![feature(integer_atomics)]\n\n",
+    "",
     atomic_umin, atomic_umax,
     2,
     "AtomicU16::new(0)",
@@ -1963,7 +1963,7 @@ atomic_int! {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "i32", "../../../std/primitive.i32.html",
-    "#![feature(integer_atomics)]\n\n",
+    "",
     atomic_min, atomic_max,
     4,
     "AtomicI32::new(0)",
@@ -1979,7 +1979,7 @@ atomic_int! {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "u32", "../../../std/primitive.u32.html",
-    "#![feature(integer_atomics)]\n\n",
+    "",
     atomic_umin, atomic_umax,
     4,
     "AtomicU32::new(0)",
@@ -1995,7 +1995,7 @@ atomic_int! {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "i64", "../../../std/primitive.i64.html",
-    "#![feature(integer_atomics)]\n\n",
+    "",
     atomic_min, atomic_max,
     8,
     "AtomicI64::new(0)",
@@ -2011,7 +2011,7 @@ atomic_int! {
     stable(feature = "integer_atomics_stable", since = "1.34.0"),
     unstable(feature = "integer_atomics", issue = "32976"),
     "u64", "../../../std/primitive.u64.html",
-    "#![feature(integer_atomics)]\n\n",
+    "",
     atomic_umin, atomic_umax,
     8,
     "AtomicU64::new(0)",
diff --git a/src/libcore/task/poll.rs b/src/libcore/task/poll.rs
index 3db70d5e764..fec17c4d1a4 100644
--- a/src/libcore/task/poll.rs
+++ b/src/libcore/task/poll.rs
@@ -81,6 +81,34 @@ impl<T, E> Poll<Result<T, E>> {
     }
 }
 
+impl<T, E> Poll<Option<Result<T, E>>> {
+    /// Changes the success value of this `Poll` with the closure provided.
+    #[unstable(feature = "poll_map", issue = "63514")]
+    pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
+        where F: FnOnce(T) -> U
+    {
+        match self {
+            Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))),
+            Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
+            Poll::Ready(None) => Poll::Ready(None),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+
+    /// Changes the error value of this `Poll` with the closure provided.
+    #[unstable(feature = "poll_map", issue = "63514")]
+    pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
+        where F: FnOnce(E) -> U
+    {
+        match self {
+            Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))),
+            Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))),
+            Poll::Ready(None) => Poll::Ready(None),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+}
+
 #[stable(feature = "futures_api", since = "1.36.0")]
 impl<T> From<T> for Poll<T> {
     fn from(t: T) -> Poll<T> {
diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs
index b4e91249832..65e29364287 100644
--- a/src/libcore/task/wake.rs
+++ b/src/libcore/task/wake.rs
@@ -10,6 +10,8 @@ use crate::marker::{PhantomData, Unpin};
 ///
 /// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that
 /// customizes the behavior of the `RawWaker`.
+///
+/// [`Waker`]: struct.Waker.html
 #[derive(PartialEq, Debug)]
 #[stable(feature = "futures_api", since = "1.36.0")]
 pub struct RawWaker {
@@ -29,7 +31,7 @@ impl RawWaker {
     /// The `data` pointer can be used to store arbitrary data as required
     /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
     /// that is associated with the task.
-    /// The value of this poiner will get passed to all functions that are part
+    /// The value of this pointer will get passed to all functions that are part
     /// of the `vtable` as the first parameter.
     ///
     /// The `vtable` customizes the behavior of a `Waker` which gets created
@@ -55,6 +57,8 @@ impl RawWaker {
 /// pointer of a properly constructed [`RawWaker`] object from inside the
 /// [`RawWaker`] implementation. Calling one of the contained functions using
 /// any other `data` pointer will cause undefined behavior.
+///
+/// [`RawWaker`]: struct.RawWaker.html
 #[stable(feature = "futures_api", since = "1.36.0")]
 #[derive(PartialEq, Copy, Clone, Debug)]
 pub struct RawWakerVTable {
@@ -65,6 +69,9 @@ pub struct RawWakerVTable {
     /// required for this additional instance of a [`RawWaker`] and associated
     /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
     /// of the same task that would have been awoken by the original [`RawWaker`].
+    ///
+    /// [`Waker`]: struct.Waker.html
+    /// [`RawWaker`]: struct.RawWaker.html
     clone: unsafe fn(*const ()) -> RawWaker,
 
     /// This function will be called when `wake` is called on the [`Waker`].
@@ -73,6 +80,9 @@ pub struct RawWakerVTable {
     /// The implementation of this function must make sure to release any
     /// resources that are associated with this instance of a [`RawWaker`] and
     /// associated task.
+    ///
+    /// [`Waker`]: struct.Waker.html
+    /// [`RawWaker`]: struct.RawWaker.html
     wake: unsafe fn(*const ()),
 
     /// This function will be called when `wake_by_ref` is called on the [`Waker`].
@@ -80,6 +90,9 @@ pub struct RawWakerVTable {
     ///
     /// This function is similar to `wake`, but must not consume the provided data
     /// pointer.
+    ///
+    /// [`Waker`]: struct.Waker.html
+    /// [`RawWaker`]: struct.RawWaker.html
     wake_by_ref: unsafe fn(*const ()),
 
     /// This function gets called when a [`RawWaker`] gets dropped.
@@ -87,6 +100,8 @@ pub struct RawWakerVTable {
     /// The implementation of this function must make sure to release any
     /// resources that are associated with this instance of a [`RawWaker`] and
     /// associated task.
+    ///
+    /// [`RawWaker`]: struct.RawWaker.html
     drop: unsafe fn(*const ()),
 }
 
@@ -128,15 +143,17 @@ impl RawWakerVTable {
     /// The implementation of this function must make sure to release any
     /// resources that are associated with this instance of a [`RawWaker`] and
     /// associated task.
+    ///
+    /// [`Waker`]: struct.Waker.html
+    /// [`RawWaker`]: struct.RawWaker.html
     #[rustc_promotable]
-    #[cfg_attr(stage0, unstable(feature = "futures_api_const_fn_ptr", issue = "50547"))]
-    #[cfg_attr(not(stage0), stable(feature = "futures_api", since = "1.36.0"))]
+    #[stable(feature = "futures_api", since = "1.36.0")]
     // `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else
     // without first consulting with T-Lang.
     //
     // FIXME: remove whenever we have a stable way to accept fn pointers from const fn
     // (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062)
-    #[cfg_attr(not(stage0), rustc_allow_const_fn_ptr)]
+    #[rustc_allow_const_fn_ptr]
     pub const fn new(
         clone: unsafe fn(*const ()) -> RawWaker,
         wake: unsafe fn(*const ()),
@@ -200,7 +217,9 @@ impl fmt::Debug for Context<'_> {
 /// This handle encapsulates a [`RawWaker`] instance, which defines the
 /// executor-specific wakeup behavior.
 ///
-/// Implements [`Clone`], [`Send`], and [`Sync`].
+/// Implements [`Clone`], [`trait@Send`], and [`trait@Sync`].
+///
+/// [`RawWaker`]: struct.RawWaker.html
 #[repr(transparent)]
 #[stable(feature = "futures_api", since = "1.36.0")]
 pub struct Waker {
@@ -266,6 +285,9 @@ impl Waker {
     /// The behavior of the returned `Waker` is undefined if the contract defined
     /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
     /// Therefore this method is unsafe.
+    ///
+    /// [`RawWaker`]: struct.RawWaker.html
+    /// [`RawWakerVTable`]: struct.RawWakerVTable.html
     #[inline]
     #[stable(feature = "futures_api", since = "1.36.0")]
     pub unsafe fn from_raw(waker: RawWaker) -> Waker {
diff --git a/src/libcore/tests/alloc.rs b/src/libcore/tests/alloc.rs
new file mode 100644
index 00000000000..63537ba23d8
--- /dev/null
+++ b/src/libcore/tests/alloc.rs
@@ -0,0 +1,10 @@
+use core::alloc::Layout;
+
+#[test]
+fn const_unchecked_layout() {
+    const SIZE: usize = 0x2000;
+    const ALIGN: usize = 0x1000;
+    const LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(SIZE, ALIGN) };
+    assert_eq!(LAYOUT.size(), SIZE);
+    assert_eq!(LAYOUT.align(), ALIGN);
+}
diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs
index ec98e0464c9..439ed0c81c8 100644
--- a/src/libcore/tests/ascii.rs
+++ b/src/libcore/tests/ascii.rs
@@ -151,7 +151,7 @@ macro_rules! assert_none {
                            stringify!($what), b);
                 }
             }
-        )*
+        )+
     }};
     ($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+))
 }
diff --git a/src/libcore/tests/fmt/builders.rs b/src/libcore/tests/fmt/builders.rs
index 62fe09c5eb3..200659b91bb 100644
--- a/src/libcore/tests/fmt/builders.rs
+++ b/src/libcore/tests/fmt/builders.rs
@@ -211,9 +211,9 @@ mod debug_map {
 
     #[test]
     fn test_single() {
-        struct Foo;
+        struct Entry;
 
-        impl fmt::Debug for Foo {
+        impl fmt::Debug for Entry {
             fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
                 fmt.debug_map()
                     .entry(&"bar", &true)
@@ -221,19 +221,32 @@ mod debug_map {
             }
         }
 
-        assert_eq!("{\"bar\": true}", format!("{:?}", Foo));
+        struct KeyValue;
+
+        impl fmt::Debug for KeyValue {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map()
+                    .key(&"bar").value(&true)
+                    .finish()
+            }
+        }
+
+        assert_eq!(format!("{:?}", Entry), format!("{:?}", KeyValue));
+        assert_eq!(format!("{:#?}", Entry), format!("{:#?}", KeyValue));
+
+        assert_eq!("{\"bar\": true}", format!("{:?}", Entry));
         assert_eq!(
 "{
     \"bar\": true,
 }",
-                   format!("{:#?}", Foo));
+                   format!("{:#?}", Entry));
     }
 
     #[test]
     fn test_multiple() {
-        struct Foo;
+        struct Entry;
 
-        impl fmt::Debug for Foo {
+        impl fmt::Debug for Entry {
             fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
                 fmt.debug_map()
                     .entry(&"bar", &true)
@@ -242,13 +255,27 @@ mod debug_map {
             }
         }
 
-        assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Foo));
+        struct KeyValue;
+
+        impl fmt::Debug for KeyValue {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map()
+                    .key(&"bar").value(&true)
+                    .key(&10).value(&format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        assert_eq!(format!("{:?}", Entry), format!("{:?}", KeyValue));
+        assert_eq!(format!("{:#?}", Entry), format!("{:#?}", KeyValue));
+
+        assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Entry));
         assert_eq!(
 "{
     \"bar\": true,
     10: 10/20,
 }",
-                   format!("{:#?}", Foo));
+                   format!("{:#?}", Entry));
     }
 
     #[test]
@@ -291,6 +318,56 @@ mod debug_map {
 }",
                    format!("{:#?}", Bar));
     }
+
+    #[test]
+    #[should_panic]
+    fn test_invalid_key_when_entry_is_incomplete() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map()
+                    .key(&"bar")
+                    .key(&"invalid")
+                    .finish()
+            }
+        }
+
+        format!("{:?}", Foo);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_invalid_finish_incomplete_entry() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map()
+                    .key(&"bar")
+                    .finish()
+            }
+        }
+
+        format!("{:?}", Foo);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_invalid_value_before_key() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+                fmt.debug_map()
+                    .value(&"invalid")
+                    .key(&"bar")
+                    .finish()
+            }
+        }
+
+        format!("{:?}", Foo);
+    }
 }
 
 mod debug_set {
diff --git a/src/libcore/tests/fmt/mod.rs b/src/libcore/tests/fmt/mod.rs
index df1deeaeb97..d86e21cf40b 100644
--- a/src/libcore/tests/fmt/mod.rs
+++ b/src/libcore/tests/fmt/mod.rs
@@ -3,7 +3,6 @@ mod float;
 mod num;
 
 #[test]
-#[cfg(not(miri))] // Miri cannot print pointers
 fn test_format_flags() {
     // No residual flags left by pointer formatting
     let p = "".as_ptr();
@@ -13,7 +12,6 @@ fn test_format_flags() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot print pointers
 fn test_pointer_formats_data_pointer() {
     let b: &[u8] = b"";
     let s: &str = "";
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 7dfb1adad9e..a1a27e1d538 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -104,6 +104,22 @@ fn test_iterator_chain_nth() {
 }
 
 #[test]
+fn test_iterator_chain_nth_back() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [30, 40, 50, 60];
+    let zs = [];
+    let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
+    for (i, x) in expected.iter().rev().enumerate() {
+        assert_eq!(Some(x), xs.iter().chain(&ys).nth_back(i));
+    }
+    assert_eq!(zs.iter().chain(&xs).nth_back(0), Some(&5));
+
+    let mut it = xs.iter().chain(&zs);
+    assert_eq!(it.nth_back(5), Some(&0));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
 fn test_iterator_chain_last() {
     let xs = [0, 1, 2, 3, 4, 5];
     let ys = [30, 40, 50, 60];
@@ -188,6 +204,19 @@ fn test_iterator_step_by() {
     assert_eq!(it.next(), Some(6));
     assert_eq!(it.next(), Some(9));
     assert_eq!(it.next(), None);
+
+    let mut it = (0..3).step_by(1);
+    assert_eq!(it.next_back(), Some(2));
+    assert_eq!(it.next_back(), Some(1));
+    assert_eq!(it.next_back(), Some(0));
+    assert_eq!(it.next_back(), None);
+
+    let mut it = (0..11).step_by(3);
+    assert_eq!(it.next_back(), Some(9));
+    assert_eq!(it.next_back(), Some(6));
+    assert_eq!(it.next_back(), Some(3));
+    assert_eq!(it.next_back(), Some(0));
+    assert_eq!(it.next_back(), None);
 }
 
 #[test]
@@ -253,6 +282,31 @@ fn test_iterator_step_by_nth_overflow() {
 }
 
 #[test]
+fn test_iterator_step_by_nth_back() {
+    let mut it = (0..16).step_by(5);
+    assert_eq!(it.nth_back(0), Some(15));
+    assert_eq!(it.nth_back(0), Some(10));
+    assert_eq!(it.nth_back(0), Some(5));
+    assert_eq!(it.nth_back(0), Some(0));
+    assert_eq!(it.nth_back(0), None);
+
+    let mut it = (0..16).step_by(5);
+    assert_eq!(it.next(), Some(0)); // to set `first_take` to `false`
+    assert_eq!(it.nth_back(0), Some(15));
+    assert_eq!(it.nth_back(0), Some(10));
+    assert_eq!(it.nth_back(0), Some(5));
+    assert_eq!(it.nth_back(0), None);
+
+    let it = || (0..18).step_by(5);
+    assert_eq!(it().nth_back(0), Some(15));
+    assert_eq!(it().nth_back(1), Some(10));
+    assert_eq!(it().nth_back(2), Some(5));
+    assert_eq!(it().nth_back(3), Some(0));
+    assert_eq!(it().nth_back(4), None);
+    assert_eq!(it().nth_back(42), None);
+}
+
+#[test]
 #[should_panic]
 fn test_iterator_step_by_zero() {
     let mut it = (0..).step_by(0);
@@ -465,8 +519,8 @@ fn test_iterator_filter_fold() {
 #[test]
 fn test_iterator_peekable() {
     let xs = vec![0, 1, 2, 3, 4, 5];
-    let mut it = xs.iter().cloned().peekable();
 
+    let mut it = xs.iter().cloned().peekable();
     assert_eq!(it.len(), 6);
     assert_eq!(it.peek().unwrap(), &0);
     assert_eq!(it.len(), 6);
@@ -492,6 +546,33 @@ fn test_iterator_peekable() {
     assert_eq!(it.len(), 0);
     assert!(it.next().is_none());
     assert_eq!(it.len(), 0);
+
+    let mut it = xs.iter().cloned().peekable();
+    assert_eq!(it.len(), 6);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 6);
+    assert_eq!(it.next_back().unwrap(), 5);
+    assert_eq!(it.len(), 5);
+    assert_eq!(it.next_back().unwrap(), 4);
+    assert_eq!(it.len(), 4);
+    assert_eq!(it.next_back().unwrap(), 3);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.next_back().unwrap(), 2);
+    assert_eq!(it.len(), 2);
+    assert_eq!(it.next_back().unwrap(), 1);
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.next_back().unwrap(), 0);
+    assert_eq!(it.len(), 0);
+    assert!(it.peek().is_none());
+    assert_eq!(it.len(), 0);
+    assert!(it.next_back().is_none());
+    assert_eq!(it.len(), 0);
 }
 
 #[test]
@@ -564,6 +645,18 @@ fn test_iterator_peekable_fold() {
     assert_eq!(i, xs.len());
 }
 
+#[test]
+fn test_iterator_peekable_rfold() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let mut it = xs.iter().peekable();
+    assert_eq!(it.peek(), Some(&&0));
+    let i = it.rfold(0, |i, &x| {
+        assert_eq!(x, xs[xs.len() - 1 - i]);
+        i + 1
+    });
+    assert_eq!(i, xs.len());
+}
+
 /// This is an iterator that follows the Iterator contract,
 /// but it is not fused. After having returned None once, it will start
 /// producing elements if .next() is called again.
@@ -812,13 +905,25 @@ fn test_iterator_skip_fold() {
 fn test_iterator_take() {
     let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
     let ys = [0, 1, 2, 3, 5];
-    let mut it = xs.iter().take(5);
+
+    let mut it = xs.iter().take(ys.len());
     let mut i = 0;
-    assert_eq!(it.len(), 5);
+    assert_eq!(it.len(), ys.len());
     while let Some(&x) = it.next() {
         assert_eq!(x, ys[i]);
         i += 1;
-        assert_eq!(it.len(), 5-i);
+        assert_eq!(it.len(), ys.len() - i);
+    }
+    assert_eq!(i, ys.len());
+    assert_eq!(it.len(), 0);
+
+    let mut it = xs.iter().take(ys.len());
+    let mut i = 0;
+    assert_eq!(it.len(), ys.len());
+    while let Some(&x) = it.next_back() {
+        i += 1;
+        assert_eq!(x, ys[ys.len() - i]);
+        assert_eq!(it.len(), ys.len() - i);
     }
     assert_eq!(i, ys.len());
     assert_eq!(it.len(), 0);
@@ -849,18 +954,50 @@ fn test_iterator_take_nth() {
 }
 
 #[test]
+fn test_iterator_take_nth_back() {
+    let xs = [0, 1, 2, 4, 5];
+    let mut it = xs.iter();
+    {
+        let mut take = it.by_ref().take(3);
+        let mut i = 0;
+        while let Some(&x) = take.nth_back(0) {
+            i += 1;
+            assert_eq!(x, 3 - i);
+        }
+    }
+    assert_eq!(it.nth_back(0), None);
+
+    let xs = [0, 1, 2, 3, 4];
+    let mut it = xs.iter().take(7);
+    assert_eq!(it.nth_back(1), Some(&3));
+    assert_eq!(it.nth_back(1), Some(&1));
+    assert_eq!(it.nth_back(1), None);
+}
+
+#[test]
 fn test_iterator_take_short() {
     let xs = [0, 1, 2, 3];
-    let ys = [0, 1, 2, 3];
+
     let mut it = xs.iter().take(5);
     let mut i = 0;
-    assert_eq!(it.len(), 4);
+    assert_eq!(it.len(), xs.len());
     while let Some(&x) = it.next() {
-        assert_eq!(x, ys[i]);
+        assert_eq!(x, xs[i]);
         i += 1;
-        assert_eq!(it.len(), 4-i);
+        assert_eq!(it.len(), xs.len() - i);
     }
-    assert_eq!(i, ys.len());
+    assert_eq!(i, xs.len());
+    assert_eq!(it.len(), 0);
+
+    let mut it = xs.iter().take(5);
+    let mut i = 0;
+    assert_eq!(it.len(), xs.len());
+    while let Some(&x) = it.next_back() {
+        i += 1;
+        assert_eq!(x, xs[xs.len() - i]);
+        assert_eq!(it.len(), xs.len() - i);
+    }
+    assert_eq!(i, xs.len());
     assert_eq!(it.len(), 0);
 }
 
@@ -1015,6 +1152,18 @@ fn test_cycle() {
     assert_eq!(empty::<i32>().cycle().fold(0, |acc, x| acc + x), 0);
 
     assert_eq!(once(1).cycle().skip(1).take(4).fold(0, |acc, x| acc + x), 4);
+
+    assert_eq!((0..10).cycle().take(5).sum::<i32>(), 10);
+    assert_eq!((0..10).cycle().take(15).sum::<i32>(), 55);
+    assert_eq!((0..10).cycle().take(25).sum::<i32>(), 100);
+
+    let mut iter = (0..10).cycle();
+    iter.nth(14);
+    assert_eq!(iter.take(8).sum::<i32>(), 38);
+
+    let mut iter = (0..10).cycle();
+    iter.nth(9);
+    assert_eq!(iter.take(3).sum::<i32>(), 3);
 }
 
 #[test]
@@ -1082,6 +1231,31 @@ fn test_iterator_sum_result() {
     assert_eq!(v.iter().cloned().sum::<Result<i32, _>>(), Ok(10));
     let v: &[Result<i32, ()>] = &[Ok(1), Err(()), Ok(3), Ok(4)];
     assert_eq!(v.iter().cloned().sum::<Result<i32, _>>(), Err(()));
+
+    #[derive(PartialEq, Debug)]
+    struct S(Result<i32, ()>);
+
+    impl Sum<Result<i32, ()>> for S {
+        fn sum<I: Iterator<Item = Result<i32, ()>>>(mut iter: I) -> Self {
+            // takes the sum by repeatedly calling `next` on `iter`,
+            // thus testing that repeated calls to `ResultShunt::try_fold`
+            // produce the expected results
+            Self(iter.by_ref().sum())
+        }
+    }
+
+    let v: &[Result<i32, ()>] = &[Ok(1), Ok(2), Ok(3), Ok(4)];
+    assert_eq!(v.iter().cloned().sum::<S>(), S(Ok(10)));
+    let v: &[Result<i32, ()>] = &[Ok(1), Err(()), Ok(3), Ok(4)];
+    assert_eq!(v.iter().cloned().sum::<S>(), S(Err(())));
+}
+
+#[test]
+fn test_iterator_sum_option() {
+    let v: &[Option<i32>] = &[Some(1), Some(2), Some(3), Some(4)];
+    assert_eq!(v.iter().cloned().sum::<Option<i32>>(), Some(10));
+    let v: &[Option<i32>] = &[Some(1), None, Some(3), Some(4)];
+    assert_eq!(v.iter().cloned().sum::<Option<i32>>(), None);
 }
 
 #[test]
@@ -1127,6 +1301,14 @@ impl Ord for Mod3 {
 }
 
 #[test]
+fn test_iterator_product_option() {
+    let v: &[Option<i32>] = &[Some(1), Some(2), Some(3), Some(4)];
+    assert_eq!(v.iter().cloned().product::<Option<i32>>(), Some(24));
+    let v: &[Option<i32>] = &[Some(1), None, Some(3), Some(4)];
+    assert_eq!(v.iter().cloned().product::<Option<i32>>(), None);
+}
+
+#[test]
 fn test_iterator_max() {
     let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
     assert_eq!(v[..4].iter().cloned().max(), Some(3));
@@ -1642,6 +1824,23 @@ fn test_range_nth() {
 }
 
 #[test]
+fn test_range_nth_back() {
+    assert_eq!((10..15).nth_back(0), Some(14));
+    assert_eq!((10..15).nth_back(1), Some(13));
+    assert_eq!((10..15).nth_back(4), Some(10));
+    assert_eq!((10..15).nth_back(5), None);
+    assert_eq!((-120..80_i8).nth_back(199), Some(-120));
+
+    let mut r = 10..20;
+    assert_eq!(r.nth_back(2), Some(17));
+    assert_eq!(r, 10..17);
+    assert_eq!(r.nth_back(2), Some(14));
+    assert_eq!(r, 10..14);
+    assert_eq!(r.nth_back(10), None);
+    assert_eq!(r, 10..10);
+}
+
+#[test]
 fn test_range_from_nth() {
     assert_eq!((10..).nth(0), Some(10));
     assert_eq!((10..).nth(1), Some(11));
@@ -1699,6 +1898,26 @@ fn test_range_inclusive_nth() {
 }
 
 #[test]
+fn test_range_inclusive_nth_back() {
+    assert_eq!((10..=15).nth_back(0), Some(15));
+    assert_eq!((10..=15).nth_back(1), Some(14));
+    assert_eq!((10..=15).nth_back(5), Some(10));
+    assert_eq!((10..=15).nth_back(6), None);
+    assert_eq!((-120..=80_i8).nth_back(200), Some(-120));
+
+    let mut r = 10_u8..=20;
+    assert_eq!(r.nth_back(2), Some(18));
+    assert_eq!(r, 10..=17);
+    assert_eq!(r.nth_back(2), Some(15));
+    assert_eq!(r, 10..=14);
+    assert_eq!(r.is_empty(), false);
+    assert_eq!(ExactSizeIterator::is_empty(&r), false);
+    assert_eq!(r.nth_back(10), None);
+    assert_eq!(r.is_empty(), true);
+    assert_eq!(ExactSizeIterator::is_empty(&r), true);
+}
+
+#[test]
 fn test_range_step() {
     #![allow(deprecated)]
 
@@ -2225,17 +2444,50 @@ fn test_enumerate_try_folds() {
 }
 
 #[test]
-fn test_peek_try_fold() {
+fn test_peek_try_folds() {
     let f = &|acc, x| i32::checked_add(2*acc, x);
+
     assert_eq!((1..20).peekable().try_fold(7, f), (1..20).try_fold(7, f));
+    assert_eq!((1..20).peekable().try_rfold(7, f), (1..20).try_rfold(7, f));
+
     let mut iter = (1..20).peekable();
     assert_eq!(iter.peek(), Some(&1));
     assert_eq!(iter.try_fold(7, f), (1..20).try_fold(7, f));
 
+    let mut iter = (1..20).peekable();
+    assert_eq!(iter.peek(), Some(&1));
+    assert_eq!(iter.try_rfold(7, f), (1..20).try_rfold(7, f));
+
     let mut iter = [100, 20, 30, 40, 50, 60, 70].iter().cloned().peekable();
     assert_eq!(iter.peek(), Some(&100));
     assert_eq!(iter.try_fold(0, i8::checked_add), None);
     assert_eq!(iter.peek(), Some(&40));
+
+    let mut iter = [100, 20, 30, 40, 50, 60, 70].iter().cloned().peekable();
+    assert_eq!(iter.peek(), Some(&100));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.peek(), Some(&100));
+    assert_eq!(iter.next_back(), Some(50));
+
+    let mut iter = (2..5).peekable();
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_for_each(Err), Err(2));
+    assert_eq!(iter.peek(), Some(&3));
+    assert_eq!(iter.try_for_each(Err), Err(3));
+    assert_eq!(iter.peek(), Some(&4));
+    assert_eq!(iter.try_for_each(Err), Err(4));
+    assert_eq!(iter.peek(), None);
+    assert_eq!(iter.try_for_each(Err), Ok(()));
+
+    let mut iter = (2..5).peekable();
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(4));
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(3));
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(2));
+    assert_eq!(iter.peek(), None);
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Ok(()));
 }
 
 #[test]
@@ -2281,16 +2533,62 @@ fn test_skip_try_folds() {
 }
 
 #[test]
+fn test_skip_nth_back() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let mut it = xs.iter().skip(2);
+    assert_eq!(it.nth_back(0), Some(&5));
+    assert_eq!(it.nth_back(1), Some(&3));
+    assert_eq!(it.nth_back(0), Some(&2));
+    assert_eq!(it.nth_back(0), None);
+
+    let ys = [2, 3, 4, 5];
+    let mut ity = ys.iter();
+    let mut it = xs.iter().skip(2);
+    assert_eq!(it.nth_back(1), ity.nth_back(1));
+    assert_eq!(it.clone().nth(0), ity.clone().nth(0));
+    assert_eq!(it.nth_back(0), ity.nth_back(0));
+    assert_eq!(it.clone().nth(0), ity.clone().nth(0));
+    assert_eq!(it.nth_back(0), ity.nth_back(0));
+    assert_eq!(it.clone().nth(0), ity.clone().nth(0));
+    assert_eq!(it.nth_back(0), ity.nth_back(0));
+    assert_eq!(it.clone().nth(0), ity.clone().nth(0));
+
+    let mut it = xs.iter().skip(2);
+    assert_eq!(it.nth_back(4), None);
+    assert_eq!(it.nth_back(0), None);
+
+    let mut it = xs.iter();
+    it.by_ref().skip(2).nth_back(3);
+    assert_eq!(it.next_back(), Some(&1));
+
+    let mut it = xs.iter();
+    it.by_ref().skip(2).nth_back(10);
+    assert_eq!(it.next_back(), Some(&1));
+}
+
+#[test]
 fn test_take_try_folds() {
     let f = &|acc, x| i32::checked_add(2*acc, x);
     assert_eq!((10..30).take(10).try_fold(7, f), (10..20).try_fold(7, f));
-    //assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f));
+    assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f));
 
     let mut iter = (10..30).take(20);
     assert_eq!(iter.try_fold(0, i8::checked_add), None);
     assert_eq!(iter.next(), Some(20));
-    //assert_eq!(iter.try_rfold(0, i8::checked_add), None);
-    //assert_eq!(iter.next_back(), Some(24));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.next_back(), Some(24));
+
+    let mut iter = (2..20).take(3);
+    assert_eq!(iter.try_for_each(Err), Err(2));
+    assert_eq!(iter.try_for_each(Err), Err(3));
+    assert_eq!(iter.try_for_each(Err), Err(4));
+    assert_eq!(iter.try_for_each(Err), Ok(()));
+
+    let mut iter = (2..20).take(3).rev();
+    assert_eq!(iter.try_for_each(Err), Err(4));
+    assert_eq!(iter.try_for_each(Err), Err(3));
+    assert_eq!(iter.try_for_each(Err), Err(2));
+    assert_eq!(iter.try_for_each(Err), Ok(()));
 }
 
 #[test]
@@ -2373,3 +2671,39 @@ fn test_is_sorted() {
     assert!(!["c", "bb", "aaa"].iter().is_sorted());
     assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
 }
+
+#[test]
+fn test_partition() {
+    fn check(xs: &mut [i32], ref p: impl Fn(&i32) -> bool, expected: usize) {
+        let i = xs.iter_mut().partition_in_place(p);
+        assert_eq!(expected, i);
+        assert!(xs[..i].iter().all(p));
+        assert!(!xs[i..].iter().any(p));
+        assert!(xs.iter().is_partitioned(p));
+        if i == 0 || i == xs.len() {
+            assert!(xs.iter().rev().is_partitioned(p));
+        } else {
+            assert!(!xs.iter().rev().is_partitioned(p));
+        }
+    }
+
+    check(&mut [], |_| true, 0);
+    check(&mut [], |_| false, 0);
+
+    check(&mut [0], |_| true, 1);
+    check(&mut [0], |_| false, 0);
+
+    check(&mut [-1, 1], |&x| x > 0, 1);
+    check(&mut [-1, 1], |&x| x < 0, 1);
+
+    let ref mut xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+    check(xs, |_| true, 10);
+    check(xs, |_| false, 0);
+    check(xs, |&x| x % 2 == 0, 5); // evens
+    check(xs, |&x| x % 2 == 1, 5); // odds
+    check(xs, |&x| x % 3 == 0, 4); // multiple of 3
+    check(xs, |&x| x % 4 == 0, 3); // multiple of 4
+    check(xs, |&x| x % 5 == 0, 2); // multiple of 5
+    check(xs, |&x| x < 3, 3); // small
+    check(xs, |&x| x > 6, 3); // large
+}
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index b8075ef2942..a3b108b2e9c 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -1,16 +1,16 @@
+#![feature(bound_cloned)]
 #![feature(box_syntax)]
 #![feature(cell_update)]
 #![feature(core_private_bignum)]
 #![feature(core_private_diy_float)]
+#![feature(debug_map_key_value)]
 #![feature(dec2flt)]
-#![feature(euclidean_division)]
 #![feature(exact_size_is_empty)]
 #![feature(fixed_size_array)]
 #![feature(flt2dec)]
 #![feature(fmt_internals)]
 #![feature(hashmap_internals)]
 #![feature(is_sorted)]
-#![feature(iter_nth_back)]
 #![feature(iter_once_with)]
 #![feature(pattern)]
 #![feature(range_is_empty)]
@@ -25,16 +25,17 @@
 #![feature(test)]
 #![feature(trusted_len)]
 #![feature(try_trait)]
-#![feature(reverse_bits)]
 #![feature(inner_deref)]
 #![feature(slice_internals)]
 #![feature(slice_partition_dedup)]
-#![feature(copy_within)]
 #![feature(int_error_matching)]
-#![warn(rust_2018_idioms)]
+#![feature(const_fn)]
+#![feature(iter_partition_in_place)]
+#![feature(iter_is_partitioned)]
 
 extern crate test;
 
+mod alloc;
 mod any;
 mod array;
 mod ascii;
diff --git a/src/libcore/tests/num/dec2flt/mod.rs b/src/libcore/tests/num/dec2flt/mod.rs
index faeaabbf95a..46eacb4200a 100644
--- a/src/libcore/tests/num/dec2flt/mod.rs
+++ b/src/libcore/tests/num/dec2flt/mod.rs
@@ -31,6 +31,7 @@ fn ordinary() {
     test_literal!(0.1);
     test_literal!(12345.);
     test_literal!(0.9999999);
+    #[cfg(not(miri))] // Miri is too slow
     test_literal!(2.2250738585072014e-308);
 }
 
@@ -76,7 +77,9 @@ fn infinity() {
 fn zero() {
     test_literal!(0.0);
     test_literal!(1e-325);
+    #[cfg(not(miri))] // Miri is too slow
     test_literal!(1e-326);
+    #[cfg(not(miri))] // Miri is too slow
     test_literal!(1e-500);
 }
 
diff --git a/src/libcore/tests/num/flt2dec/estimator.rs b/src/libcore/tests/num/flt2dec/estimator.rs
index 2dbb8e3a5f0..c51451708f3 100644
--- a/src/libcore/tests/num/flt2dec/estimator.rs
+++ b/src/libcore/tests/num/flt2dec/estimator.rs
@@ -42,7 +42,12 @@ fn test_estimate_scaling_factor() {
     assert_almost_eq!(estimate_scaling_factor(1, -1074), -323);
     assert_almost_eq!(estimate_scaling_factor(0x1fffffffffffff, 971), 309);
 
-    for i in -1074..972 {
+    #[cfg(not(miri))] // Miri is too slow
+    let iter = -1074..972;
+    #[cfg(miri)]
+    let iter = (-1074..972).step_by(37);
+
+    for i in iter {
         let expected = super::ldexp_f64(1.0, i).log10().ceil();
         assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16);
     }
diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs
index f42f500c2df..c41d35efced 100644
--- a/src/libcore/tests/num/flt2dec/mod.rs
+++ b/src/libcore/tests/num/flt2dec/mod.rs
@@ -1,5 +1,3 @@
-#![cfg(not(miri))] // Miri does not implement ldexp, which most tests here need
-
 use std::prelude::v1::*;
 use std::{str, i16, f32, f64, fmt};
 
@@ -257,6 +255,7 @@ pub fn f32_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
     check_shortest!(f(minf32) => b"1", -44);
 }
 
+#[cfg(not(miri))] // Miri is too slow
 pub fn f32_exact_sanity_test<F>(mut f: F)
         where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
     let minf32 = ldexp_f32(1.0, -149);
@@ -362,6 +361,7 @@ pub fn f64_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8])
     check_shortest!(f(minf64) => b"5", -323);
 }
 
+#[cfg(not(miri))] // Miri is too slow
 pub fn f64_exact_sanity_test<F>(mut f: F)
         where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
     let minf64 = ldexp_f64(1.0, -1074);
@@ -553,6 +553,10 @@ pub fn to_shortest_str_test<F>(mut f_: F)
     assert_eq!(to_string(f, minf64, Minus, 324, false), format!("0.{:0>323}5", ""));
     assert_eq!(to_string(f, minf64, Minus, 325, false), format!("0.{:0>323}50", ""));
 
+    if cfg!(miri) { // Miri is too slow
+        return;
+    }
+
     // very large output
     assert_eq!(to_string(f, 1.1, Minus, 80000, false), format!("1.1{:0>79999}", ""));
 }
@@ -807,6 +811,10 @@ pub fn to_exact_exp_str_test<F>(mut f_: F)
                "1.401298464324817070923729583289916131280261941876515771757068283\
                  8897910826858606014866381883621215820312500000000000000000000000e-45");
 
+    if cfg!(miri) { // Miri is too slow
+        return;
+    }
+
     assert_eq!(to_string(f, f64::MAX, Minus,   1, false), "2e308");
     assert_eq!(to_string(f, f64::MAX, Minus,   2, false), "1.8e308");
     assert_eq!(to_string(f, f64::MAX, Minus,   4, false), "1.798e308");
@@ -1040,6 +1048,10 @@ pub fn to_exact_fixed_str_test<F>(mut f_: F)
     assert_eq!(to_string(f, f32::MAX, Minus, 2, false),
                "340282346638528859811704183484516925440.00");
 
+    if cfg!(miri) { // Miri is too slow
+        return;
+    }
+
     let minf32 = ldexp_f32(1.0, -149);
     assert_eq!(to_string(f, minf32, Minus,   0, false), "0");
     assert_eq!(to_string(f, minf32, Minus,   1, false), "0.0");
diff --git a/src/libcore/tests/num/flt2dec/random.rs b/src/libcore/tests/num/flt2dec/random.rs
index 35e3fbcbb78..d9543793397 100644
--- a/src/libcore/tests/num/flt2dec/random.rs
+++ b/src/libcore/tests/num/flt2dec/random.rs
@@ -8,8 +8,8 @@ use core::num::flt2dec::strategy::grisu::format_exact_opt;
 use core::num::flt2dec::strategy::grisu::format_shortest_opt;
 use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
 
-use rand::FromEntropy;
-use rand::rngs::SmallRng;
+use rand::SeedableRng;
+use rand::rngs::StdRng;
 use rand::distributions::{Distribution, Uniform};
 
 pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
@@ -65,7 +65,7 @@ pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
     if cfg!(target_os = "emscripten") {
         return // using rng pulls in i128 support, which doesn't work
     }
-    let mut rng = SmallRng::from_entropy();
+    let mut rng = StdRng::from_entropy();
     let f32_range = Uniform::new(0x0000_0001u32, 0x7f80_0000);
     iterate("f32_random_equivalence_test", k, n, f, g, |_| {
         let x = f32::from_bits(f32_range.sample(&mut rng));
@@ -79,7 +79,7 @@ pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
     if cfg!(target_os = "emscripten") {
         return // using rng pulls in i128 support, which doesn't work
     }
-    let mut rng = SmallRng::from_entropy();
+    let mut rng = StdRng::from_entropy();
     let f64_range = Uniform::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
     iterate("f64_random_equivalence_test", k, n, f, g, |_| {
         let x = f64::from_bits(f64_range.sample(&mut rng));
@@ -109,8 +109,13 @@ pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
 #[test]
 fn shortest_random_equivalence_test() {
     use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
-    f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
-    f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
+    #[cfg(not(miri))] // Miri is too slow
+    const N: usize = 10_000;
+    #[cfg(miri)]
+    const N: usize = 10;
+
+    f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
+    f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
 }
 
 #[test] #[ignore] // it is too expensive
@@ -138,17 +143,27 @@ fn shortest_f64_hard_random_equivalence_test() {
 #[test]
 fn exact_f32_random_equivalence_test() {
     use core::num::flt2dec::strategy::dragon::format_exact as fallback;
+    #[cfg(not(miri))] // Miri is too slow
+    const N: usize = 1_000;
+    #[cfg(miri)]
+    const N: usize = 3;
+
     for k in 1..21 {
         f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
-                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
+                                             |d, buf| fallback(d, buf, i16::MIN), k, N);
     }
 }
 
 #[test]
 fn exact_f64_random_equivalence_test() {
     use core::num::flt2dec::strategy::dragon::format_exact as fallback;
+    #[cfg(not(miri))] // Miri is too slow
+    const N: usize = 1_000;
+    #[cfg(miri)]
+    const N: usize = 3;
+
     for k in 1..21 {
         f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
-                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
+                                             |d, buf| fallback(d, buf, i16::MIN), k, N);
     }
 }
diff --git a/src/libcore/tests/num/flt2dec/strategy/dragon.rs b/src/libcore/tests/num/flt2dec/strategy/dragon.rs
index 5e4cc23d33c..dc4d78bfae1 100644
--- a/src/libcore/tests/num/flt2dec/strategy/dragon.rs
+++ b/src/libcore/tests/num/flt2dec/strategy/dragon.rs
@@ -23,6 +23,7 @@ fn shortest_sanity_test() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri is too slow
 fn exact_sanity_test() {
     // This test ends up running what I can only assume is some corner-ish case
     // of the `exp2` library function, defined in whatever C runtime we're
diff --git a/src/libcore/tests/num/flt2dec/strategy/grisu.rs b/src/libcore/tests/num/flt2dec/strategy/grisu.rs
index f1afd7d4bf8..f8bdddfe2e4 100644
--- a/src/libcore/tests/num/flt2dec/strategy/grisu.rs
+++ b/src/libcore/tests/num/flt2dec/strategy/grisu.rs
@@ -36,6 +36,7 @@ fn shortest_sanity_test() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri is too slow
 fn exact_sanity_test() {
     // See comments in dragon.rs's exact_sanity_test for why this test is
     // ignored on MSVC
diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs
index 78cf07119e7..48755ae4c16 100644
--- a/src/libcore/tests/ops.rs
+++ b/src/libcore/tests/ops.rs
@@ -1,4 +1,4 @@
-use core::ops::{Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
+use core::ops::{Bound, Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
 
 // Test the Range structs without the syntactic sugar.
 
@@ -82,3 +82,18 @@ fn test_range_is_empty() {
     assert!( (NAN ..= EPSILON).is_empty());
     assert!( (NAN ..= NAN).is_empty());
 }
+
+#[test]
+fn test_bound_cloned_unbounded() {
+    assert_eq!(Bound::<&u32>::Unbounded.cloned(), Bound::Unbounded);
+}
+
+#[test]
+fn test_bound_cloned_included() {
+    assert_eq!(Bound::Included(&3).cloned(), Bound::Included(3));
+}
+
+#[test]
+fn test_bound_cloned_excluded() {
+    assert_eq!(Bound::Excluded(&3).cloned(), Bound::Excluded(3));
+}
diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs
index b059b134868..ff43fc49f71 100644
--- a/src/libcore/tests/option.rs
+++ b/src/libcore/tests/option.rs
@@ -1,6 +1,8 @@
 use core::option::*;
 use core::mem;
 use core::clone::Clone;
+use core::array::FixedSizeArray;
+use core::ops::DerefMut;
 
 #[test]
 fn test_get_ptr() {
@@ -310,20 +312,38 @@ fn test_try() {
 }
 
 #[test]
-fn test_option_deref() {
+fn test_option_as_deref() {
     // Some: &Option<T: Deref>::Some(T) -> Option<&T::Deref::Target>::Some(&*T)
     let ref_option = &Some(&42);
-    assert_eq!(ref_option.deref(), Some(&42));
+    assert_eq!(ref_option.as_deref(), Some(&42));
 
     let ref_option = &Some(String::from("a result"));
-    assert_eq!(ref_option.deref(), Some("a result"));
+    assert_eq!(ref_option.as_deref(), Some("a result"));
 
     let ref_option = &Some(vec![1, 2, 3, 4, 5]);
-    assert_eq!(ref_option.deref(), Some(&[1, 2, 3, 4, 5][..]));
+    assert_eq!(ref_option.as_deref(), Some([1, 2, 3, 4, 5].as_slice()));
 
     // None: &Option<T: Deref>>::None -> None
     let ref_option: &Option<&i32> = &None;
-    assert_eq!(ref_option.deref(), None);
+    assert_eq!(ref_option.as_deref(), None);
+}
+
+#[test]
+fn test_option_as_deref_mut() {
+    // Some: &mut Option<T: Deref>::Some(T) -> Option<&mut T::Deref::Target>::Some(&mut *T)
+    let mut val = 42;
+    let ref_option = &mut Some(&mut val);
+    assert_eq!(ref_option.as_deref_mut(), Some(&mut 42));
+
+    let ref_option = &mut Some(String::from("a result"));
+    assert_eq!(ref_option.as_deref_mut(), Some(String::from("a result").deref_mut()));
+
+    let ref_option = &mut Some(vec![1, 2, 3, 4, 5]);
+    assert_eq!(ref_option.as_deref_mut(), Some([1, 2, 3, 4, 5].as_mut_slice()));
+
+    // None: &mut Option<T: Deref>>::None -> None
+    let ref_option: &mut Option<&mut i32> = &mut None;
+    assert_eq!(ref_option.as_deref_mut(), None);
 }
 
 #[test]
diff --git a/src/libcore/tests/pattern.rs b/src/libcore/tests/pattern.rs
index b78ed021077..06c3a78c169 100644
--- a/src/libcore/tests/pattern.rs
+++ b/src/libcore/tests/pattern.rs
@@ -5,7 +5,7 @@ use std::str::pattern::*;
 macro_rules! search_asserts {
     ($haystack:expr, $needle:expr, $testname:expr, [$($func:ident),*], $result:expr) => {
         let mut searcher = $needle.into_searcher($haystack);
-        let arr = [$( Step::from(searcher.$func()) ),+];
+        let arr = [$( Step::from(searcher.$func()) ),*];
         assert_eq!(&arr[..], &$result, $testname);
     }
 }
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
index 03fe1fe5a7c..1a6be3a9bbd 100644
--- a/src/libcore/tests/ptr.rs
+++ b/src/libcore/tests/ptr.rs
@@ -145,7 +145,6 @@ fn test_as_ref() {
 }
 
 #[test]
-#[cfg(not(miri))] // This test is UB according to Stacked Borrows
 fn test_as_mut() {
     unsafe {
         let p: *mut isize = null_mut();
@@ -164,7 +163,7 @@ fn test_as_mut() {
         // Pointers to unsized types -- slices
         let s: &mut [u8] = &mut [1, 2, 3];
         let ms: *mut [u8] = s;
-        assert_eq!(ms.as_mut(), Some(s));
+        assert_eq!(ms.as_mut(), Some(&mut [1, 2, 3][..]));
 
         let mz: *mut [u8] = &mut [];
         assert_eq!(mz.as_mut(), Some(&mut [][..]));
@@ -253,7 +252,6 @@ fn test_unsized_nonnull() {
 
 #[test]
 #[allow(warnings)]
-#[cfg(not(miri))] // Miri cannot hash pointers
 // Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
 // ABI, or even point to an actual executable code, because the function itself is never invoked.
 #[no_mangle]
@@ -293,7 +291,7 @@ fn write_unaligned_drop() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn align_offset_zst() {
     // For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at
     // all, because no amount of elements will align the pointer.
@@ -308,7 +306,7 @@ fn align_offset_zst() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn align_offset_stride1() {
     // For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
     // number of bytes.
diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs
index 1fab07526a0..163f8d0ab37 100644
--- a/src/libcore/tests/result.rs
+++ b/src/libcore/tests/result.rs
@@ -1,4 +1,6 @@
 use core::option::*;
+use core::array::FixedSizeArray;
+use core::ops::DerefMut;
 
 fn op1() -> Result<isize, &'static str> { Ok(666) }
 fn op2() -> Result<isize, &'static str> { Err("sadface") }
@@ -225,94 +227,213 @@ fn test_try() {
 }
 
 #[test]
-fn test_result_deref() {
-    // &Result<T: Deref, E>::Ok(T).deref_ok() ->
+fn test_result_as_deref() {
+    // &Result<T: Deref, E>::Ok(T).as_deref_ok() ->
     //      Result<&T::Deref::Target, &E>::Ok(&*T)
     let ref_ok = &Result::Ok::<&i32, u8>(&42);
     let expected_result = Result::Ok::<&i32, &u8>(&42);
-    assert_eq!(ref_ok.deref_ok(), expected_result);
+    assert_eq!(ref_ok.as_deref_ok(), expected_result);
 
     let ref_ok = &Result::Ok::<String, u32>(String::from("a result"));
     let expected_result = Result::Ok::<&str, &u32>("a result");
-    assert_eq!(ref_ok.deref_ok(), expected_result);
+    assert_eq!(ref_ok.as_deref_ok(), expected_result);
 
     let ref_ok = &Result::Ok::<Vec<i32>, u32>(vec![1, 2, 3, 4, 5]);
-    let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]);
-    assert_eq!(ref_ok.deref_ok(), expected_result);
+    let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
+    assert_eq!(ref_ok.as_deref_ok(), expected_result);
 
-    // &Result<T: Deref, E: Deref>::Ok(T).deref() ->
+    // &Result<T: Deref, E: Deref>::Ok(T).as_deref() ->
     //      Result<&T::Deref::Target, &E::Deref::Target>::Ok(&*T)
     let ref_ok = &Result::Ok::<&i32, &u8>(&42);
     let expected_result = Result::Ok::<&i32, &u8>(&42);
-    assert_eq!(ref_ok.deref(), expected_result);
+    assert_eq!(ref_ok.as_deref(), expected_result);
 
     let ref_ok = &Result::Ok::<String, &u32>(String::from("a result"));
     let expected_result = Result::Ok::<&str, &u32>("a result");
-    assert_eq!(ref_ok.deref(), expected_result);
+    assert_eq!(ref_ok.as_deref(), expected_result);
 
     let ref_ok = &Result::Ok::<Vec<i32>, &u32>(vec![1, 2, 3, 4, 5]);
-    let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]);
-    assert_eq!(ref_ok.deref(), expected_result);
+    let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
+    assert_eq!(ref_ok.as_deref(), expected_result);
 
-    // &Result<T, E: Deref>::Err(T).deref_err() ->
+    // &Result<T, E: Deref>::Err(T).as_deref_err() ->
     //      Result<&T, &E::Deref::Target>::Err(&*E)
     let ref_err = &Result::Err::<u8, &i32>(&41);
     let expected_result = Result::Err::<&u8, &i32>(&41);
-    assert_eq!(ref_err.deref_err(), expected_result);
+    assert_eq!(ref_err.as_deref_err(), expected_result);
 
     let ref_err = &Result::Err::<u32, String>(String::from("an error"));
     let expected_result = Result::Err::<&u32, &str>("an error");
-    assert_eq!(ref_err.deref_err(), expected_result);
+    assert_eq!(ref_err.as_deref_err(), expected_result);
 
     let ref_err = &Result::Err::<u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
-    let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]);
-    assert_eq!(ref_err.deref_err(), expected_result);
+    let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
+    assert_eq!(ref_err.as_deref_err(), expected_result);
 
-    // &Result<T: Deref, E: Deref>::Err(T).deref_err() ->
+    // &Result<T: Deref, E: Deref>::Err(T).as_deref_err() ->
     //      Result<&T, &E::Deref::Target>::Err(&*E)
     let ref_err = &Result::Err::<&u8, &i32>(&41);
     let expected_result = Result::Err::<&u8, &i32>(&41);
-    assert_eq!(ref_err.deref(), expected_result);
+    assert_eq!(ref_err.as_deref(), expected_result);
 
     let ref_err = &Result::Err::<&u32, String>(String::from("an error"));
     let expected_result = Result::Err::<&u32, &str>("an error");
-    assert_eq!(ref_err.deref(), expected_result);
+    assert_eq!(ref_err.as_deref(), expected_result);
 
     let ref_err = &Result::Err::<&u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
-    let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]);
-    assert_eq!(ref_err.deref(), expected_result);
+    let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
+    assert_eq!(ref_err.as_deref(), expected_result);
 
-    // The following cases test calling deref_* with the wrong variant (i.e.
-    // `deref_ok()` with a `Result::Err()`, or `deref_err()` with a `Result::Ok()`.
-    // While unusual, these cases are supported to ensure that an `inner_deref`
+    // The following cases test calling `as_deref_*` with the wrong variant (i.e.
+    // `as_deref_ok()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`.
+    // While uncommon, these cases are supported to ensure that an `as_deref_*`
     // call can still be made even when one of the Result types does not implement
     // `Deref` (for example, std::io::Error).
 
-    // &Result<T, E: Deref>::Ok(T).deref_err() ->
+    // &Result<T, E: Deref>::Ok(T).as_deref_err() ->
     //      Result<&T, &E::Deref::Target>::Ok(&T)
     let ref_ok = &Result::Ok::<i32, &u8>(42);
     let expected_result = Result::Ok::<&i32, &u8>(&42);
-    assert_eq!(ref_ok.deref_err(), expected_result);
+    assert_eq!(ref_ok.as_deref_err(), expected_result);
 
     let ref_ok = &Result::Ok::<&str, &u32>("a result");
     let expected_result = Result::Ok::<&&str, &u32>(&"a result");
-    assert_eq!(ref_ok.deref_err(), expected_result);
+    assert_eq!(ref_ok.as_deref_err(), expected_result);
 
     let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]);
     let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]);
-    assert_eq!(ref_ok.deref_err(), expected_result);
+    assert_eq!(ref_ok.as_deref_err(), expected_result);
 
-    // &Result<T: Deref, E>::Err(E).deref_ok() ->
+    // &Result<T: Deref, E>::Err(E).as_deref_ok() ->
     //      Result<&T::Deref::Target, &E>::Err(&E)
     let ref_err = &Result::Err::<&u8, i32>(41);
     let expected_result = Result::Err::<&u8, &i32>(&41);
-    assert_eq!(ref_err.deref_ok(), expected_result);
+    assert_eq!(ref_err.as_deref_ok(), expected_result);
 
     let ref_err = &Result::Err::<&u32, &str>("an error");
     let expected_result = Result::Err::<&u32, &&str>(&"an error");
-    assert_eq!(ref_err.deref_ok(), expected_result);
+    assert_eq!(ref_err.as_deref_ok(), expected_result);
 
     let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]);
     let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]);
-    assert_eq!(ref_err.deref_ok(), expected_result);
+    assert_eq!(ref_err.as_deref_ok(), expected_result);
+}
+
+#[test]
+fn test_result_as_deref_mut() {
+    // &mut Result<T: Deref, E>::Ok(T).as_deref_mut_ok() ->
+    //      Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T)
+    let mut val = 42;
+    let mut expected_val = 42;
+    let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val);
+    let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
+    assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);
+
+    let mut expected_string = String::from("a result");
+    let mut_ok = &mut Result::Ok::<String, u32>(expected_string.clone());
+    let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut());
+    assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);
+
+    let mut expected_vec = vec![1, 2, 3, 4, 5];
+    let mut_ok = &mut Result::Ok::<Vec<i32>, u32>(expected_vec.clone());
+    let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
+    assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);
+
+    // &mut Result<T: Deref, E: Deref>::Ok(T).as_deref_mut() ->
+    //      Result<&mut T::Deref::Target, &mut E::Deref::Target>::Ok(&mut *T)
+    let mut val = 42;
+    let mut expected_val = 42;
+    let mut_ok = &mut Result::Ok::<&mut i32, &mut u8>(&mut val);
+    let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
+    assert_eq!(mut_ok.as_deref_mut(), expected_result);
+
+    let mut expected_string = String::from("a result");
+    let mut_ok = &mut Result::Ok::<String, &mut u32>(expected_string.clone());
+    let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut());
+    assert_eq!(mut_ok.as_deref_mut(), expected_result);
+
+    let mut expected_vec = vec![1, 2, 3, 4, 5];
+    let mut_ok = &mut Result::Ok::<Vec<i32>, &mut u32>(expected_vec.clone());
+    let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
+    assert_eq!(mut_ok.as_deref_mut(), expected_result);
+
+    // &mut Result<T, E: Deref>::Err(T).as_deref_mut_err() ->
+    //      Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
+    let mut val = 41;
+    let mut expected_val = 41;
+    let mut_err = &mut Result::Err::<u8, &mut i32>(&mut val);
+    let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
+    assert_eq!(mut_err.as_deref_mut_err(), expected_result);
+
+    let mut expected_string = String::from("an error");
+    let mut_err = &mut Result::Err::<u32, String>(expected_string.clone());
+    let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.deref_mut());
+    assert_eq!(mut_err.as_deref_mut_err(), expected_result);
+
+    let mut expected_vec = vec![5, 4, 3, 2, 1];
+    let mut_err = &mut Result::Err::<u32, Vec<i32>>(expected_vec.clone());
+    let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
+    assert_eq!(mut_err.as_deref_mut_err(), expected_result);
+
+    // &mut Result<T: Deref, E: Deref>::Err(T).as_deref_mut_err() ->
+    //      Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
+    let mut val = 41;
+    let mut expected_val = 41;
+    let mut_err = &mut Result::Err::<&mut u8, &mut i32>(&mut val);
+    let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
+    assert_eq!(mut_err.as_deref_mut(), expected_result);
+
+    let mut expected_string = String::from("an error");
+    let mut_err = &mut Result::Err::<&mut u32, String>(expected_string.clone());
+    let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.as_mut_str());
+    assert_eq!(mut_err.as_deref_mut(), expected_result);
+
+    let mut expected_vec = vec![5, 4, 3, 2, 1];
+    let mut_err = &mut Result::Err::<&mut u32, Vec<i32>>(expected_vec.clone());
+    let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
+    assert_eq!(mut_err.as_deref_mut(), expected_result);
+
+    // The following cases test calling `as_deref_mut_*` with the wrong variant (i.e.
+    // `as_deref_mut_ok()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`.
+    // While uncommon, these cases are supported to ensure that an `as_deref_mut_*`
+    // call can still be made even when one of the Result types does not implement
+    // `Deref` (for example, std::io::Error).
+
+    // &mut Result<T, E: Deref>::Ok(T).as_deref_mut_err() ->
+    //      Result<&mut T, &mut E::Deref::Target>::Ok(&mut T)
+    let mut expected_val = 42;
+    let mut_ok = &mut Result::Ok::<i32, &mut u8>(expected_val.clone());
+    let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
+    assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
+
+    let string = String::from("a result");
+    let expected_string = string.clone();
+    let mut ref_str = expected_string.as_ref();
+    let mut_ok = &mut Result::Ok::<&str, &mut u32>(string.as_str());
+    let expected_result = Result::Ok::<&mut &str, &mut u32>(&mut ref_str);
+    assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
+
+    let mut expected_arr = [1, 2, 3, 4, 5];
+    let mut_ok = &mut Result::Ok::<[i32; 5], &mut u32>(expected_arr.clone());
+    let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr);
+    assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
+
+    // &mut Result<T: Deref, E>::Err(E).as_deref_mut_ok() ->
+    //      Result<&mut T::Deref::Target, &mut E>::Err(&mut E)
+    let mut expected_val = 41;
+    let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone());
+    let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
+    assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
+
+    let string = String::from("an error");
+    let expected_string = string.clone();
+    let mut ref_str = expected_string.as_ref();
+    let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str());
+    let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str);
+    assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
+
+    let mut expected_arr = [5, 4, 3, 2, 1];
+    let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone());
+    let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr);
+    assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
 }
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index acf6b03791f..4790152512a 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -3,19 +3,19 @@ use core::result::Result::{Ok, Err};
 #[test]
 fn test_position() {
     let b = [1, 2, 3, 5, 5];
-    assert!(b.iter().position(|&v| v == 9) == None);
-    assert!(b.iter().position(|&v| v == 5) == Some(3));
-    assert!(b.iter().position(|&v| v == 3) == Some(2));
-    assert!(b.iter().position(|&v| v == 0) == None);
+    assert_eq!(b.iter().position(|&v| v == 9), None);
+    assert_eq!(b.iter().position(|&v| v == 5), Some(3));
+    assert_eq!(b.iter().position(|&v| v == 3), Some(2));
+    assert_eq!(b.iter().position(|&v| v == 0), None);
 }
 
 #[test]
 fn test_rposition() {
     let b = [1, 2, 3, 5, 5];
-    assert!(b.iter().rposition(|&v| v == 9) == None);
-    assert!(b.iter().rposition(|&v| v == 5) == Some(4));
-    assert!(b.iter().rposition(|&v| v == 3) == Some(2));
-    assert!(b.iter().rposition(|&v| v == 0) == None);
+    assert_eq!(b.iter().rposition(|&v| v == 9), None);
+    assert_eq!(b.iter().rposition(|&v| v == 5), Some(4));
+    assert_eq!(b.iter().rposition(|&v| v == 3), Some(2));
+    assert_eq!(b.iter().rposition(|&v| v == 0), None);
 }
 
 #[test]
@@ -89,6 +89,19 @@ fn test_iterator_nth() {
 }
 
 #[test]
+fn test_iterator_nth_back() {
+    let v: &[_] = &[0, 1, 2, 3, 4];
+    for i in 0..v.len() {
+        assert_eq!(v.iter().nth_back(i).unwrap(), &v[v.len() - i - 1]);
+    }
+    assert_eq!(v.iter().nth_back(v.len()), None);
+
+    let mut iter = v.iter();
+    assert_eq!(iter.nth_back(2).unwrap(), &v[2]);
+    assert_eq!(iter.nth_back(1).unwrap(), &v[0]);
+}
+
+#[test]
 fn test_iterator_last() {
     let v: &[_] = &[0, 1, 2, 3, 4];
     assert_eq!(v.iter().last().unwrap(), &4);
@@ -135,6 +148,30 @@ fn test_chunks_nth() {
 }
 
 #[test]
+fn test_chunks_nth_back() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let mut c = v.chunks(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[0, 1]);
+    assert_eq!(c.next(), None);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let mut c2 = v2.chunks(3);
+    assert_eq!(c2.nth_back(1).unwrap(), &[0, 1, 2]);
+    assert_eq!(c2.next(), None);
+    assert_eq!(c2.next_back(), None);
+
+    let v3: &[i32] = &[0, 1, 2, 3, 4];
+    let mut c3 = v3.chunks(10);
+    assert_eq!(c3.nth_back(0).unwrap(), &[0, 1, 2, 3, 4]);
+    assert_eq!(c3.next(), None);
+
+    let v4: &[i32] = &[0, 1, 2];
+    let mut c4 = v4.chunks(10);
+    assert_eq!(c4.nth_back(1_000_000_000usize), None);
+}
+
+#[test]
 fn test_chunks_last() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5];
     let c = v.chunks(2);
@@ -186,6 +223,28 @@ fn test_chunks_mut_nth() {
 }
 
 #[test]
+fn test_chunks_mut_nth_back() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let mut c = v.chunks_mut(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[0, 1]);
+
+    let v1: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let mut c1 = v1.chunks_mut(3);
+    assert_eq!(c1.nth_back(1).unwrap(), &[0, 1, 2]);
+    assert_eq!(c1.next(), None);
+
+    let v3: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let mut c3 = v3.chunks_mut(10);
+    assert_eq!(c3.nth_back(0).unwrap(), &[0, 1, 2, 3, 4]);
+    assert_eq!(c3.next(), None);
+
+    let v4: &mut [i32] = &mut [0, 1, 2];
+    let mut c4 = v4.chunks_mut(10);
+    assert_eq!(c4.nth_back(1_000_000_000usize), None);
+}
+
+#[test]
 fn test_chunks_mut_last() {
     let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
     let c = v.chunks_mut(2);
@@ -239,6 +298,25 @@ fn test_chunks_exact_nth() {
 }
 
 #[test]
+fn test_chunks_exact_nth_back() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let mut c = v.chunks_exact(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[0, 1]);
+    assert_eq!(c.next(), None);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let mut c2 = v2.chunks_exact(3);
+    assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]);
+    assert_eq!(c2.next(), None);
+    assert_eq!(c2.next_back(), None);
+
+    let v3: &[i32] = &[0, 1, 2, 3, 4];
+    let mut c3 = v3.chunks_exact(10);
+    assert_eq!(c3.nth_back(0), None);
+}
+
+#[test]
 fn test_chunks_exact_last() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5];
     let c = v.chunks_exact(2);
@@ -357,6 +435,19 @@ fn test_rchunks_nth() {
 }
 
 #[test]
+fn test_rchunks_nth_back() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let mut c = v.rchunks(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next_back().unwrap(), &[4, 5]);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let mut c2 = v2.rchunks(3);
+    assert_eq!(c2.nth_back(1).unwrap(), &[2, 3, 4]);
+    assert_eq!(c2.next_back(), None);
+}
+
+#[test]
 fn test_rchunks_last() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5];
     let c = v.rchunks(2);
@@ -408,6 +499,19 @@ fn test_rchunks_mut_nth() {
 }
 
 #[test]
+fn test_rchunks_mut_nth_back() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let mut c = v.rchunks_mut(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next_back().unwrap(), &[4, 5]);
+
+    let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let mut c2 = v2.rchunks_mut(3);
+    assert_eq!(c2.nth_back(1).unwrap(), &[2, 3, 4]);
+    assert_eq!(c2.next_back(), None);
+}
+
+#[test]
 fn test_rchunks_mut_last() {
     let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
     let c = v.rchunks_mut(2);
@@ -461,6 +565,19 @@ fn test_rchunks_exact_nth() {
 }
 
 #[test]
+fn test_rchunks_exact_nth_back() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let mut c = v.rchunks_exact(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next_back().unwrap(), &[4, 5]);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6];
+    let mut c2 = v2.rchunks_exact(3);
+    assert_eq!(c2.nth_back(1).unwrap(), &[4, 5, 6]);
+    assert_eq!(c2.next(), None);
+}
+
+#[test]
 fn test_rchunks_exact_last() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5];
     let c = v.rchunks_exact(2);
@@ -519,6 +636,19 @@ fn test_rchunks_exact_mut_nth() {
 }
 
 #[test]
+fn test_rchunks_exact_mut_nth_back() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let mut c = v.rchunks_exact_mut(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next_back().unwrap(), &[4, 5]);
+
+    let v2: &mut [i32] = &mut [0, 1, 2, 3, 4, 5, 6];
+    let mut c2 = v2.rchunks_exact_mut(3);
+    assert_eq!(c2.nth_back(1).unwrap(), &[4, 5, 6]);
+    assert_eq!(c2.next(), None);
+}
+
+#[test]
 fn test_rchunks_exact_mut_last() {
     let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
     let c = v.rchunks_exact_mut(2);
@@ -1023,11 +1153,49 @@ fn test_rotate_right() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri is too slow
+fn brute_force_rotate_test_0() {
+    // In case of edge cases involving multiple algorithms
+    let n = 300;
+    for len in 0..n {
+        for s in 0..len {
+            let mut v = Vec::with_capacity(len);
+            for i in 0..len {
+                v.push(i);
+            }
+            v[..].rotate_right(s);
+            for i in 0..v.len() {
+                assert_eq!(v[i], v.len().wrapping_add(i.wrapping_sub(s)) % v.len());
+            }
+        }
+    }
+}
+
+#[test]
+fn brute_force_rotate_test_1() {
+    // `ptr_rotate` covers so many kinds of pointer usage, that this is just a good test for
+    // pointers in general. This uses a `[usize; 4]` to hit all algorithms without overwhelming miri
+    let n = 30;
+    for len in 0..n {
+        for s in 0..len {
+            let mut v: Vec<[usize; 4]> = Vec::with_capacity(len);
+            for i in 0..len {
+                v.push([i, 0, 0, 0]);
+            }
+            v[..].rotate_right(s);
+            for i in 0..v.len() {
+                assert_eq!(v[i][0], v.len().wrapping_add(i.wrapping_sub(s)) % v.len());
+            }
+        }
+    }
+}
+
+#[test]
 #[cfg(not(target_arch = "wasm32"))]
 fn sort_unstable() {
     use core::cmp::Ordering::{Equal, Greater, Less};
     use core::slice::heapsort;
-    use rand::{FromEntropy, Rng, rngs::SmallRng, seq::SliceRandom};
+    use rand::{SeedableRng, Rng, rngs::StdRng, seq::SliceRandom};
 
     #[cfg(not(miri))] // Miri is too slow
     let large_range = 500..510;
@@ -1041,7 +1209,7 @@ fn sort_unstable() {
 
     let mut v = [0; 600];
     let mut tmp = [0; 600];
-    let mut rng = SmallRng::from_entropy();
+    let mut rng = StdRng::from_entropy();
 
     for len in (2..25).chain(large_range) {
         let v = &mut v[0..len];
@@ -1107,11 +1275,11 @@ fn sort_unstable() {
 #[cfg(not(miri))] // Miri is too slow
 fn partition_at_index() {
     use core::cmp::Ordering::{Equal, Greater, Less};
-    use rand::rngs::SmallRng;
+    use rand::rngs::StdRng;
     use rand::seq::SliceRandom;
-    use rand::{FromEntropy, Rng};
+    use rand::{SeedableRng, Rng};
 
-    let mut rng = SmallRng::from_entropy();
+    let mut rng = StdRng::from_entropy();
 
     for len in (2..21).chain(500..501) {
         let mut orig = vec![0; len];
@@ -1307,7 +1475,7 @@ pub mod memchr {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn test_align_to_simple() {
     let bytes = [1u8, 2, 3, 4, 5, 6, 7];
     let (prefix, aligned, suffix) = unsafe { bytes.align_to::<u16>() };
@@ -1331,7 +1499,7 @@ fn test_align_to_zst() {
 }
 
 #[test]
-#[cfg(not(miri))] // Miri cannot compute actual alignment of an allocation
+#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
 fn test_align_to_non_trivial() {
     #[repr(align(8))] struct U64(u64, u64);
     #[repr(align(8))] struct U64U64U32(u64, u64, u32);
@@ -1436,6 +1604,13 @@ fn test_copy_within() {
     let mut bytes = *b"Hello, World!";
     bytes.copy_within(.., 0);
     assert_eq!(&bytes, b"Hello, World!");
+
+    // Ensure that copying at the end of slice won't cause UB.
+    let mut bytes = *b"Hello, World!";
+    bytes.copy_within(13..13, 5);
+    assert_eq!(&bytes, b"Hello, World!");
+    bytes.copy_within(5..5, 13);
+    assert_eq!(&bytes, b"Hello, World!");
 }
 
 #[test]
@@ -1460,6 +1635,13 @@ fn test_copy_within_panics_src_inverted() {
     // 2 is greater than 1, so this range is invalid.
     bytes.copy_within(2..1, 0);
 }
+#[test]
+#[should_panic(expected = "attempted to index slice up to maximum usize")]
+fn test_copy_within_panics_src_out_of_bounds() {
+    let mut bytes = *b"Hello, World!";
+    // an inclusive range ending at usize::max_value() would make src_end overflow
+    bytes.copy_within(usize::max_value()..=usize::max_value(), 0);
+}
 
 #[test]
 fn test_is_sorted() {
diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs
index 6efd22572dc..fac70c468c8 100644
--- a/src/libcore/tests/time.rs
+++ b/src/libcore/tests/time.rs
@@ -2,7 +2,7 @@ use core::time::Duration;
 
 #[test]
 fn creation() {
-    assert!(Duration::from_secs(1) != Duration::from_secs(0));
+    assert_ne!(Duration::from_secs(1), Duration::from_secs(0));
     assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
                Duration::from_secs(3));
     assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index 0f5f91f41a8..5a0e4388e03 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -505,15 +505,14 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
     /// use std::time::Duration;
     ///
     /// let dur = Duration::new(2, 700_000_000);
     /// assert_eq!(dur.as_secs_f64(), 2.7);
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[stable(feature = "duration_float", since = "1.38.0")]
     #[inline]
-    pub const fn as_secs_f64(&self) -> f64 {
+    pub fn as_secs_f64(&self) -> f64 {
         (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
     }
 
@@ -523,15 +522,14 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
     /// use std::time::Duration;
     ///
     /// let dur = Duration::new(2, 700_000_000);
     /// assert_eq!(dur.as_secs_f32(), 2.7);
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[stable(feature = "duration_float", since = "1.38.0")]
     #[inline]
-    pub const fn as_secs_f32(&self) -> f32 {
+    pub fn as_secs_f32(&self) -> f32 {
         (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
     }
 
@@ -543,13 +541,12 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
     /// use std::time::Duration;
     ///
     /// let dur = Duration::from_secs_f64(2.7);
     /// assert_eq!(dur, Duration::new(2, 700_000_000));
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[stable(feature = "duration_float", since = "1.38.0")]
     #[inline]
     pub fn from_secs_f64(secs: f64) -> Duration {
         const MAX_NANOS_F64: f64 =
@@ -579,13 +576,12 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
     /// use std::time::Duration;
     ///
     /// let dur = Duration::from_secs_f32(2.7);
     /// assert_eq!(dur, Duration::new(2, 700_000_000));
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[stable(feature = "duration_float", since = "1.38.0")]
     #[inline]
     pub fn from_secs_f32(secs: f32) -> Duration {
         const MAX_NANOS_F32: f32 =
@@ -614,14 +610,13 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
     /// use std::time::Duration;
     ///
     /// let dur = Duration::new(2, 700_000_000);
     /// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000));
     /// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[stable(feature = "duration_float", since = "1.38.0")]
     #[inline]
     pub fn mul_f64(self, rhs: f64) -> Duration {
         Duration::from_secs_f64(rhs * self.as_secs_f64())
@@ -634,7 +629,6 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
     /// use std::time::Duration;
     ///
     /// let dur = Duration::new(2, 700_000_000);
@@ -643,7 +637,7 @@ impl Duration {
     /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640));
     /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256));
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[stable(feature = "duration_float", since = "1.38.0")]
     #[inline]
     pub fn mul_f32(self, rhs: f32) -> Duration {
         Duration::from_secs_f32(rhs * self.as_secs_f32())
@@ -656,7 +650,6 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
     /// use std::time::Duration;
     ///
     /// let dur = Duration::new(2, 700_000_000);
@@ -664,7 +657,7 @@ impl Duration {
     /// // note that truncation is used, not rounding
     /// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598));
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[stable(feature = "duration_float", since = "1.38.0")]
     #[inline]
     pub fn div_f64(self, rhs: f64) -> Duration {
         Duration::from_secs_f64(self.as_secs_f64() / rhs)
@@ -677,7 +670,6 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
     /// use std::time::Duration;
     ///
     /// let dur = Duration::new(2, 700_000_000);
@@ -687,7 +679,7 @@ impl Duration {
     /// // note that truncation is used, not rounding
     /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[stable(feature = "duration_float", since = "1.38.0")]
     #[inline]
     pub fn div_f32(self, rhs: f32) -> Duration {
         Duration::from_secs_f32(self.as_secs_f32() / rhs)
@@ -697,14 +689,14 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
+    /// #![feature(div_duration)]
     /// use std::time::Duration;
     ///
     /// let dur1 = Duration::new(2, 700_000_000);
     /// let dur2 = Duration::new(5, 400_000_000);
     /// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[unstable(feature = "div_duration", issue = "63139")]
     #[inline]
     pub fn div_duration_f64(self, rhs: Duration) -> f64 {
         self.as_secs_f64() / rhs.as_secs_f64()
@@ -714,14 +706,14 @@ impl Duration {
     ///
     /// # Examples
     /// ```
-    /// #![feature(duration_float)]
+    /// #![feature(div_duration)]
     /// use std::time::Duration;
     ///
     /// let dur1 = Duration::new(2, 700_000_000);
     /// let dur2 = Duration::new(5, 400_000_000);
     /// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
     /// ```
-    #[unstable(feature = "duration_float", issue = "54361")]
+    #[unstable(feature = "div_duration", issue = "63139")]
     #[inline]
     pub fn div_duration_f32(self, rhs: Duration) -> f32 {
         self.as_secs_f32() / rhs.as_secs_f32()
diff --git a/src/libcore/unicode/printable.py b/src/libcore/unicode/printable.py
index 1288a784123..748917f1d34 100644
--- a/src/libcore/unicode/printable.py
+++ b/src/libcore/unicode/printable.py
@@ -111,17 +111,17 @@ def compress_normal(normal):
     return compressed
 
 def print_singletons(uppers, lowers, uppersname, lowersname):
-    print("const {}: &'static [(u8, u8)] = &[".format(uppersname))
+    print("const {}: &[(u8, u8)] = &[".format(uppersname))
     for u, c in uppers:
         print("    ({:#04x}, {}),".format(u, c))
     print("];")
-    print("const {}: &'static [u8] = &[".format(lowersname))
+    print("const {}: &[u8] = &[".format(lowersname))
     for i in range(0, len(lowers), 8):
         print("    {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8])))
     print("];")
 
 def print_normal(normal, normalname):
-    print("const {}: &'static [u8] = &[".format(normalname))
+    print("const {}: &[u8] = &[".format(normalname))
     for v in normal:
         print("    {}".format(" ".join("{:#04x},".format(i) for i in v)))
     print("];")
diff --git a/src/libcore/unicode/printable.rs b/src/libcore/unicode/printable.rs
index a950e82cba2..d411dda7dc1 100644
--- a/src/libcore/unicode/printable.rs
+++ b/src/libcore/unicode/printable.rs
@@ -82,7 +82,7 @@ const SINGLETONS0U: &[(u8, u8)] = &[
     (0x0b, 25),
     (0x0c, 20),
     (0x0d, 18),
-    (0x0e, 22),
+    (0x0e, 13),
     (0x0f, 4),
     (0x10, 3),
     (0x12, 18),
@@ -96,13 +96,14 @@ const SINGLETONS0U: &[(u8, u8)] = &[
     (0x1d, 1),
     (0x1f, 22),
     (0x20, 3),
-    (0x2b, 6),
+    (0x2b, 4),
     (0x2c, 2),
     (0x2d, 11),
     (0x2e, 1),
     (0x30, 3),
     (0x31, 2),
-    (0x32, 2),
+    (0x32, 1),
+    (0xa7, 2),
     (0xa9, 2),
     (0xaa, 4),
     (0xab, 8),
@@ -130,27 +131,26 @@ const SINGLETONS0L: &[u8] = &[
     0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x04,
     0x0d, 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x81,
     0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0,
-    0xf1, 0x83, 0x85, 0x86, 0x89, 0x8b, 0x8c, 0x98,
-    0xa0, 0xa4, 0xa6, 0xa8, 0xa9, 0xac, 0xba, 0xbe,
-    0xbf, 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb, 0x48,
-    0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e,
-    0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f,
-    0xb1, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7,
-    0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe,
-    0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e,
-    0x0f, 0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d,
-    0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, 0x17,
-    0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a,
-    0x5c, 0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5,
-    0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74,
-    0x75, 0x96, 0x97, 0xc9, 0xff, 0x2f, 0x5f, 0x26,
-    0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, 0xc7, 0xcf,
-    0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f,
-    0x1f, 0xff, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b,
-    0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef,
-    0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90,
-    0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9,
-    0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
+    0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf,
+    0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98,
+    0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e, 0x4f,
+    0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1,
+    0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11,
+    0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe, 0xff,
+    0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f,
+    0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e,
+    0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, 0x17, 0x1e,
+    0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c,
+    0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc,
+    0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75,
+    0x96, 0x97, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7,
+    0xaf, 0xb7, 0xbf, 0xc7, 0xcf, 0xd7, 0xdf, 0x9a,
+    0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0, 0xc1,
+    0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08,
+    0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef, 0x6e, 0x6f,
+    0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91, 0xfe,
+    0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1,
+    0xd8, 0xd9, 0xe7, 0xfe, 0xff,
 ];
 const SINGLETONS1U: &[(u8, u8)] = &[
     (0x00, 6),
@@ -168,7 +168,7 @@ const SINGLETONS1U: &[(u8, u8)] = &[
     (0x14, 2),
     (0x15, 2),
     (0x17, 2),
-    (0x1a, 2),
+    (0x19, 4),
     (0x1c, 5),
     (0x1d, 8),
     (0x24, 1),
@@ -182,10 +182,12 @@ const SINGLETONS1U: &[(u8, u8)] = &[
     (0xd7, 2),
     (0xda, 1),
     (0xe0, 5),
+    (0xe1, 2),
     (0xe8, 2),
     (0xee, 32),
     (0xf0, 4),
-    (0xf9, 4),
+    (0xf9, 6),
+    (0xfa, 2),
 ];
 const SINGLETONS1L: &[u8] = &[
     0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
@@ -195,19 +197,20 @@ const SINGLETONS1L: &[u8] = &[
     0x12, 0x87, 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e,
     0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, 0x45, 0x46,
     0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5a, 0x5c,
-    0xb6, 0xb7, 0x1b, 0x1c, 0x84, 0x85, 0x09, 0x37,
-    0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66,
-    0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a,
-    0x62, 0x9a, 0x9b, 0x27, 0x28, 0x55, 0x9d, 0xa0,
-    0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc,
-    0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f,
-    0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd, 0xa0, 0x07,
-    0x19, 0x1a, 0x22, 0x25, 0xc5, 0xc6, 0x04, 0x20,
-    0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48,
-    0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a,
-    0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, 0x6b, 0x73,
-    0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0,
-    0xc0, 0xd0, 0x3f, 0x71, 0x72, 0x7b,
+    0xb6, 0xb7, 0x1b, 0x1c, 0xa8, 0xa9, 0xd8, 0xd9,
+    0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b,
+    0x3e, 0x66, 0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee,
+    0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, 0x28, 0x55,
+    0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad,
+    0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d,
+    0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd,
+    0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f,
+    0xc5, 0xc6, 0x04, 0x20, 0x23, 0x25, 0x26, 0x28,
+    0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c, 0x50, 0x53,
+    0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63,
+    0x65, 0x66, 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a,
+    0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0, 0x0c, 0x72,
+    0xa3, 0xa4, 0xcb, 0xcc, 0x6e, 0x6f,
 ];
 const NORMAL0: &[u8] = &[
     0x00, 0x20,
@@ -246,8 +249,8 @@ const NORMAL0: &[u8] = &[
     0x3a, 0x03,
     0x11, 0x07,
     0x06, 0x05,
-    0x10, 0x08,
-    0x56, 0x07,
+    0x10, 0x07,
+    0x57, 0x07,
     0x02, 0x07,
     0x15, 0x0d,
     0x50, 0x04,
@@ -258,8 +261,7 @@ const NORMAL0: &[u8] = &[
     0x0f, 0x0c,
     0x3a, 0x04,
     0x1d, 0x25,
-    0x0d, 0x06,
-    0x4c, 0x20,
+    0x5f, 0x20,
     0x6d, 0x04,
     0x6a, 0x25,
     0x80, 0xc8, 0x05,
@@ -294,7 +296,7 @@ const NORMAL0: &[u8] = &[
     0x0f, 0x03,
     0x3c, 0x07,
     0x38, 0x08,
-    0x2a, 0x06,
+    0x2b, 0x05,
     0x82, 0xff, 0x11,
     0x18, 0x08,
     0x2f, 0x11,
@@ -309,7 +311,7 @@ const NORMAL0: &[u8] = &[
     0x3b, 0x07,
     0x02, 0x0e,
     0x18, 0x09,
-    0x80, 0xaf, 0x31,
+    0x80, 0xb0, 0x30,
     0x74, 0x0c,
     0x80, 0xd6, 0x1a,
     0x0c, 0x05,
@@ -322,7 +324,7 @@ const NORMAL0: &[u8] = &[
     0x37, 0x09,
     0x81, 0x5c, 0x14,
     0x80, 0xb8, 0x08,
-    0x80, 0xba, 0x3d,
+    0x80, 0xc7, 0x30,
     0x35, 0x04,
     0x0a, 0x06,
     0x38, 0x08,
@@ -335,7 +337,7 @@ const NORMAL0: &[u8] = &[
     0x80, 0x83, 0x18,
     0x1c, 0x0a,
     0x16, 0x09,
-    0x46, 0x0a,
+    0x48, 0x08,
     0x80, 0x8a, 0x06,
     0xab, 0xa4, 0x0c,
     0x17, 0x04,
@@ -405,7 +407,8 @@ const NORMAL1: &[u8] = &[
     0x0a, 0x81, 0x26,
     0x1f, 0x80, 0x81,
     0x28, 0x08,
-    0x2a, 0x80, 0xa6,
+    0x2a, 0x80, 0x86,
+    0x17, 0x09,
     0x4e, 0x04,
     0x1e, 0x0f,
     0x43, 0x0e,
@@ -422,20 +425,21 @@ const NORMAL1: &[u8] = &[
     0x01, 0x05,
     0x10, 0x03,
     0x05, 0x80, 0x8b,
-    0x5f, 0x21,
+    0x60, 0x20,
     0x48, 0x08,
     0x0a, 0x80, 0xa6,
     0x5e, 0x22,
     0x45, 0x0b,
     0x0a, 0x06,
     0x0d, 0x13,
-    0x38, 0x08,
+    0x39, 0x07,
     0x0a, 0x36,
     0x2c, 0x04,
     0x10, 0x80, 0xc0,
     0x3c, 0x64,
     0x53, 0x0c,
-    0x01, 0x81, 0x00,
+    0x01, 0x80, 0xa0,
+    0x45, 0x1b,
     0x48, 0x08,
     0x53, 0x1d,
     0x39, 0x81, 0x07,
@@ -447,8 +451,9 @@ const NORMAL1: &[u8] = &[
     0x0a, 0x06,
     0x39, 0x07,
     0x0a, 0x81, 0x36,
-    0x19, 0x81, 0x07,
-    0x83, 0x9a, 0x66,
+    0x19, 0x80, 0xc7,
+    0x32, 0x0d,
+    0x83, 0x9b, 0x66,
     0x75, 0x0b,
     0x80, 0xc4, 0x8a, 0xbc,
     0x84, 0x2f, 0x8f, 0xd1,
@@ -461,13 +466,15 @@ const NORMAL1: &[u8] = &[
     0x28, 0x05,
     0x13, 0x82, 0xb0,
     0x5b, 0x65,
-    0x45, 0x0b,
-    0x2f, 0x10,
+    0x4b, 0x04,
+    0x39, 0x07,
     0x11, 0x40,
-    0x02, 0x1e,
-    0x97, 0xf2, 0x0e,
+    0x04, 0x1c,
+    0x97, 0xf8, 0x08,
     0x82, 0xf3, 0xa5, 0x0d,
-    0x81, 0x1f, 0x51,
+    0x81, 0x1f, 0x31,
+    0x03, 0x11,
+    0x04, 0x08,
     0x81, 0x8c, 0x89, 0x04,
     0x6b, 0x05,
     0x0d, 0x03,
@@ -483,12 +490,18 @@ const NORMAL1: &[u8] = &[
     0x81, 0x47, 0x03,
     0x85, 0x42, 0x0f,
     0x15, 0x85, 0x50,
-    0x2b, 0x87, 0xd5,
+    0x2b, 0x80, 0xd5,
+    0x2d, 0x03,
+    0x1a, 0x04,
+    0x02, 0x81, 0x70,
+    0x3a, 0x05,
+    0x01, 0x85, 0x00,
     0x80, 0xd7, 0x29,
-    0x4b, 0x05,
+    0x4c, 0x04,
     0x0a, 0x04,
     0x02, 0x83, 0x11,
-    0x44, 0x81, 0x4b,
+    0x44, 0x4c,
+    0x3d, 0x80, 0xc2,
     0x3c, 0x06,
     0x01, 0x04,
     0x55, 0x05,
@@ -498,28 +511,29 @@ const NORMAL1: &[u8] = &[
     0x64, 0x0c,
     0x56, 0x0a,
     0x0d, 0x03,
-    0x5c, 0x04,
+    0x5d, 0x03,
     0x3d, 0x39,
     0x1d, 0x0d,
     0x2c, 0x04,
     0x09, 0x07,
     0x02, 0x0e,
     0x06, 0x80, 0x9a,
-    0x83, 0xd5, 0x0b,
+    0x83, 0xd6, 0x0a,
     0x0d, 0x03,
-    0x0a, 0x06,
+    0x0b, 0x05,
     0x74, 0x0c,
-    0x59, 0x27,
+    0x59, 0x07,
+    0x0c, 0x14,
     0x0c, 0x04,
     0x38, 0x08,
     0x0a, 0x06,
     0x28, 0x08,
     0x1e, 0x52,
-    0x0c, 0x04,
-    0x67, 0x03,
-    0x29, 0x0d,
-    0x0a, 0x06,
+    0x77, 0x03,
+    0x31, 0x03,
+    0x80, 0xa6, 0x0c,
+    0x14, 0x04,
+    0x03, 0x05,
     0x03, 0x0d,
-    0x30, 0x60,
-    0x0e, 0x85, 0x92,
+    0x06, 0x85, 0x6a,
 ];
diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs
index 758cdb0b7cf..3fae3a46ada 100644
--- a/src/libcore/unicode/tables.rs
+++ b/src/libcore/unicode/tables.rs
@@ -1,6 +1,6 @@
 // NOTE: The following code was generated by "./unicode.py", do not edit directly
 
-#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
+#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)]
 
 use crate::unicode::version::UnicodeVersion;
 use crate::unicode::bool_trie::{BoolTrie, SmallBoolTrie};
@@ -9,13 +9,13 @@ use crate::unicode::bool_trie::{BoolTrie, SmallBoolTrie};
 /// `char` and `str` methods are based on.
 #[unstable(feature = "unicode_version", issue = "49726")]
 pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {
-    major: 11,
-    minor: 0,
+    major: 12,
+    minor: 1,
     micro: 0,
     _priv: (),
 };
-pub mod general_category {
-    pub const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
+pub(crate) mod general_category {
+    const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
         r1: &[
             0, 1, 0
         ],
@@ -28,7 +28,7 @@ pub mod general_category {
         Cc_table.lookup(c)
     }
 
-    pub const N_table: &super::BoolTrie = &super::BoolTrie {
+    const N_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x03ff000000000000, 0x0000000000000000, 0x720c000000000000, 0x0000000000000000,
             0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
@@ -103,20 +103,21 @@ pub mod general_category {
             0, 0, 0, 0, 9, 10, 11, 12, 0, 13, 14, 0, 15, 16, 17, 0, 18, 19, 0, 0, 0, 0, 20, 21, 0,
             0, 0, 0, 22, 0, 0, 23, 24, 0, 0, 0, 25, 0, 21, 26, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 0, 0,
             28, 0, 28, 0, 0, 0, 0, 0, 28, 0, 29, 30, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 32, 0, 0, 0, 28, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 32, 0, 0, 0, 28, 8, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 38, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 39, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 21,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 28, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 28, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+            0
         ],
         r6: &[
             0x0000000000000000, 0x000fffffffffff80, 0x01ffffffffffffff, 0x0000000000000c00,
@@ -127,9 +128,10 @@ pub mod general_category {
             0xfc00000000000000, 0x03ff000000000000, 0x7fffffff00000000, 0x0000007fe0000000,
             0x00000000001e0000, 0x0000fffffffc0000, 0xffc0000000000000, 0x001ffffe03ff0000,
             0x0000000003ff0000, 0x00000000000003ff, 0x0fff000000000000, 0x0007ffff00000000,
-            0x00001fffffff0000, 0xffffffffffffffff, 0x00007fffffffffff, 0x00000003fbff0000,
-            0x00000000007fffff, 0x000fffff00000000, 0x01ffffff00000000, 0xffffffffffffc000,
-            0x000000000000ff80, 0xfffe000000000000, 0x001eefffffffffff, 0x0000000000001fff
+            0x00001fffffff0000, 0x00000000001fffff, 0xffffffffffffffff, 0x00007fffffffffff,
+            0x00000003fbff0000, 0x00000000007fffff, 0x000fffff00000000, 0x01ffffff00000000,
+            0xffffffffffffc000, 0x000000000000ff80, 0xfffe000000000000, 0x001eefffffffffff,
+            0x3fffbffffffffffe, 0x0000000000001fff
         ],
     };
 
@@ -139,8 +141,8 @@ pub mod general_category {
 
 }
 
-pub mod derived_property {
-    pub const Alphabetic_table: &super::BoolTrie = &super::BoolTrie {
+pub(crate) mod derived_property {
+    const Alphabetic_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
             0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
@@ -155,11 +157,11 @@ pub mod derived_property {
             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, 33, 34, 35, 36, 36, 36, 36, 36, 37, 38, 39, 40, 41,
             42, 43, 44, 36, 36, 36, 36, 36, 36, 36, 36, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
-            56, 57, 58, 59, 60, 61, 62, 31, 63, 64, 65, 66, 55, 67, 68, 69, 36, 36, 36, 70, 36, 36,
-            36, 36, 71, 72, 73, 74, 31, 75, 76, 31, 77, 78, 79, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-            31, 31, 80, 81, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-            31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 82, 83, 36, 84, 85, 86, 87, 88, 89, 31, 31, 31,
-            31, 31, 31, 31, 90, 44, 91, 92, 93, 36, 94, 95, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36,
+            56, 57, 58, 59, 60, 61, 62, 31, 63, 64, 65, 66, 67, 68, 69, 70, 36, 36, 36, 71, 36, 36,
+            36, 36, 72, 73, 74, 75, 31, 76, 77, 31, 78, 79, 80, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+            31, 31, 81, 82, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+            31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 83, 84, 36, 85, 86, 87, 88, 89, 90, 31, 31, 31,
+            31, 31, 31, 31, 91, 44, 92, 93, 94, 36, 95, 96, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
@@ -179,9 +181,9 @@ pub mod derived_property {
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-            36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 96, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-            36, 36, 36, 36, 36, 36, 36, 36, 97, 98, 36, 36, 36, 36, 99, 100, 36, 96, 101, 36, 102,
-            103, 104, 105, 36, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 36, 117, 36,
+            36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 97, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+            36, 36, 36, 36, 36, 36, 36, 36, 98, 99, 36, 36, 36, 36, 100, 101, 36, 97, 102, 36, 103,
+            104, 105, 106, 36, 107, 108, 109, 110, 111, 67, 112, 113, 114, 115, 116, 36, 117, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
@@ -196,8 +198,8 @@ pub mod derived_property {
             31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
             31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
             31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-            36, 36, 36, 36, 36, 120, 36, 121, 122, 123, 124, 125, 36, 36, 36, 36, 126, 127, 128,
-            129, 31, 130, 36, 131, 132, 133, 113, 134
+            36, 36, 36, 36, 36, 120, 36, 121, 122, 123, 124, 125, 36, 36, 36, 36, 126, 33, 127, 128,
+            31, 129, 36, 130, 131, 132, 113, 133
         ],
         r3: &[
             0x00001ffffcffffff, 0x000007ff01ffffff, 0x3fdfffff00000000, 0xffff03f8fff00000,
@@ -206,34 +208,34 @@ pub mod derived_property {
             0xe3edfdfffff99fee, 0x0002000fb0c0199f, 0xc3ffc718d63dc7ec, 0x0000000000811dc7,
             0xe3fffdfffffddfef, 0x0000000f07601ddf, 0xe3effdfffffddfef, 0x0006000f40601ddf,
             0xe7fffffffffddfef, 0xfc00000f80f05ddf, 0x2ffbfffffc7fffec, 0x000c0000ff5f807f,
-            0x07fffffffffffffe, 0x000000000000207f, 0x3bffecaefef02596, 0x00000000f000205f,
+            0x07fffffffffffffe, 0x000000000000207f, 0x3bffffaffffff7d6, 0x00000000f000205f,
             0x0000000000000001, 0xfffe1ffffffffeff, 0x1ffffffffeffff03, 0x0000000000000000,
-            0xf97fffffffffffff, 0xffffc1e7ffff0000, 0xffffffff3000407f, 0xf7ffffffffff20bf,
+            0xf97fffffffffffff, 0xffffffffffff0000, 0xffffffff3c00ffff, 0xf7ffffffffff20bf,
             0xffffffffffffffff, 0xffffffff3d7f3dff, 0x7f3dffffffff3dff, 0xffffffffff7fff3d,
-            0xffffffffff3dffff, 0x0000000087ffffff, 0xffffffff0000ffff, 0x3f3fffffffffffff,
+            0xffffffffff3dffff, 0x0000000007ffffff, 0xffffffff0000ffff, 0x3f3fffffffffffff,
             0xfffffffffffffffe, 0xffff9fffffffffff, 0xffffffff07fffffe, 0x01ffc7ffffffffff,
             0x000fffff000fdfff, 0x000ddfff000fffff, 0xffcfffffffffffff, 0x00000000108001ff,
             0xffffffff00000000, 0x01ffffffffffffff, 0xffff07ffffffffff, 0x003fffffffffffff,
             0x01ff0fff7fffffff, 0x001f3fffffff0000, 0xffff0fffffffffff, 0x00000000000003ff,
             0xffffffff0fffffff, 0x001ffffe7fffffff, 0x0000008000000000, 0xffefffffffffffff,
-            0x0000000000000fef, 0xfc00f3ffffffffff, 0x0003ffbfffffffff, 0x3ffffffffc00e000,
-            0xe7ffffffffff01ff, 0x006fde0000000000, 0x001fff8000000000, 0xffffffff3f3fffff,
-            0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x8002000000000000,
-            0x000000001fff0000, 0xf3ffbd503e2ffc84, 0xffffffff000043e0, 0x00000000000001ff,
-            0xffc0000000000000, 0x000003ffffffffff, 0xffff7fffffffffff, 0xffffffff7fffffff,
-            0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff,
-            0xffffffff7f7f7f7f, 0x0000800000000000, 0x1f3e03fe000000e0, 0xfffffffee07fffff,
-            0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000,
-            0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff,
-            0x8ff07fffffffffff, 0xfffffffcff800000, 0x03fffffffffff9ff, 0xff80000000000000,
-            0x000000fffffff7bb, 0x000fffffffffffff, 0x68fc00000000002f, 0xffff07fffffffc00,
-            0x1fffffff0007ffff, 0xfff7ffffffffffff, 0x7c00ffdf00008000, 0x007fffffffffffff,
-            0xc47fffff00003fff, 0x7fffffffffffffff, 0x003cffff38000005, 0xffff7f7f007e7e7e,
-            0xffff003ff7ffffff, 0x000007ffffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
+            0x0000000000000fef, 0xfc00f3ffffffffff, 0x0003ffbfffffffff, 0x007fffffffffffff,
+            0x3ffffffffc00e000, 0xe7ffffffffff01ff, 0x046fde0000000000, 0x001fff8000000000,
+            0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc,
+            0x8002000000000000, 0x000000001fff0000, 0xf3ffbd503e2ffc84, 0xffffffff000043e0,
+            0x00000000000001ff, 0xffc0000000000000, 0x000003ffffffffff, 0xffff7fffffffffff,
+            0xffffffff7fffffff, 0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff,
+            0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x0000800000000000, 0x1f3e03fe000000e0,
+            0xfffffffee07fffff, 0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff,
+            0xffff000000000000, 0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000,
+            0x00000c00ffff1fff, 0x8ff07fffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff,
+            0xff8000000000007c, 0x000000ffffffffbf, 0x000fffffffffffff, 0xe8fc00000000002f,
+            0xffff07fffffffc00, 0x1fffffff0007ffff, 0xfff7ffffffffffff, 0x7c00ffff00008000,
+            0xfc7fffff00003fff, 0x7fffffffffffffff, 0x003cffff38000005, 0xffff7f7f007e7e7e,
+            0xffff00fff7ffffff, 0x000007ffffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
             0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffe0f8007f, 0xffffffffffffffdb,
-            0x0003ffffffffffff, 0xfffffffffff80000, 0x3fffffffffffffff, 0xffffffffffff0000,
-            0xfffffffffffcffff, 0x0fff0000000000ff, 0xffdf000000000000, 0x1fffffffffffffff,
-            0x07fffffe00000000, 0xffffffc007fffffe, 0x000000001cfcfcfc
+            0x0003ffffffffffff, 0xfffffffffff80000, 0x3fffffffffffffff, 0xfffffffffffcffff,
+            0x0fff0000000000ff, 0xffdf000000000000, 0x1fffffffffffffff, 0x07fffffe00000000,
+            0xffffffc007fffffe, 0x000000001cfcfcfc
         ],
         r4: [
             0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 13, 14,
@@ -249,45 +251,45 @@ pub mod derived_property {
         r5: &[
             0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2,
             2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32,
-            32, 33, 4, 4, 4, 4, 4, 4, 4, 34, 35, 4, 4, 2, 35, 36, 37, 32, 38, 2, 39, 40, 4, 41, 42,
-            43, 44, 4, 4, 2, 45, 2, 46, 4, 4, 47, 48, 49, 50, 28, 4, 51, 4, 4, 4, 52, 4, 53, 54, 4,
-            4, 4, 4, 55, 56, 57, 52, 4, 4, 4, 4, 58, 59, 60, 4, 61, 62, 63, 4, 4, 4, 4, 64, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 4, 2, 66, 2, 2, 2, 67, 4, 4, 4, 4, 4,
+            32, 33, 4, 4, 4, 4, 4, 4, 4, 34, 35, 4, 36, 2, 35, 37, 38, 32, 39, 2, 40, 41, 4, 42, 43,
+            44, 45, 4, 4, 2, 46, 2, 47, 4, 4, 48, 49, 50, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4,
+            4, 57, 58, 59, 60, 61, 54, 4, 4, 4, 4, 62, 63, 64, 4, 65, 66, 67, 4, 4, 4, 4, 36, 4, 4,
+            4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 69, 2, 2, 2, 70, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 66, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            2, 2, 2, 2, 2, 2, 2, 2, 52, 20, 4, 69, 16, 70, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4,
-            4, 2, 72, 73, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 76, 2, 2, 2, 2, 2,
-            77, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 2, 78, 79, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 80, 81, 82, 83, 84, 2, 2, 2, 2, 85, 86, 87, 88, 89,
-            90, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 92, 2, 93, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 94, 95, 96, 4, 4, 4, 4, 4, 4, 4, 4, 4, 76, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 2, 2, 2, 2, 2, 2, 2, 2, 54, 20, 4, 72, 73, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
+            4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2, 2, 2, 2,
+            2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90, 91, 92,
+            93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 95, 4, 4, 4, 96, 97, 4, 4, 4, 4, 4, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 99, 2, 100, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 101, 102, 103, 4, 4, 4, 4, 4, 4, 4, 4, 4, 104, 105, 106, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
+            2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 100, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 101, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 102, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
+            2, 109, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
+            110, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
         ],
         r6: &[
             0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
@@ -299,22 +301,24 @@ pub mod derived_property {
             0x003ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
             0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff,
             0x0007ffffffffffff, 0x000000ffffffffff, 0xffff00801fffffff, 0x000000000000003f,
-            0x01fffffffffffffc, 0x000001ffffff0000, 0x0047ffffffff0070, 0x000000001400001e,
-            0x409ffffffffbffff, 0xffff01ffbfffbd7f, 0x000001ffffffffff, 0xe3edfdfffff99fef,
-            0x0000000fe081199f, 0x00000000000007bb, 0x00000000000000b3, 0x7f3fffffffffffff,
-            0x000000003f000000, 0x7fffffffffffffff, 0x0000000000000011, 0x000007ffe7ffffff,
-            0x01ffffffffffffff, 0xffffffff00000000, 0x80000000ffffffff, 0x7fe7ffffffffffff,
-            0xffffffffffff0000, 0x0000000020ffffcf, 0x7f7ffffffffffdff, 0xfffc000000000001,
+            0x007fffff00000000, 0x01fffffffffffffc, 0x000001ffffff0000, 0x0047ffffffff0070,
+            0x000000001400001e, 0x409ffffffffbffff, 0xffff01ffbfffbd7f, 0x000001ffffffffff,
+            0xe3edfdfffff99fef, 0x0000000fe081199f, 0x00000000800007bb, 0x00000000000000b3,
+            0x7f3fffffffffffff, 0x000000003f000000, 0x7fffffffffffffff, 0x0000000000000011,
+            0x013fffffffffffff, 0x000007ffe7ffffff, 0x01ffffffffffffff, 0xffffffff00000000,
+            0x80000000ffffffff, 0xfffffcff00000000, 0x0000001afcffffff, 0x7fe7ffffffffffff,
+            0xffffffffffff0000, 0x0000000020ffffff, 0x7f7ffffffffffdff, 0xfffc000000000001,
             0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf000000cb, 0x00000000017b7fff,
-            0x007fffff00000000, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f,
-            0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f, 0x000000000000ffff,
-            0x7fffffffffff001f, 0x00000000fff80000, 0x0000000300000000, 0x0003ffffffffffff,
-            0xffff000000000000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000043ff01ff,
+            0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f, 0x000000000000007f,
+            0x00003fffffff0000, 0x0000ffffffffffff, 0xe0fffff80000000f, 0x000000000000ffff,
+            0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000, 0x00ffffffffffffff,
+            0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000043ff01ff,
             0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
             0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
             0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x000007dbf9ffff7f,
-            0x000000000000001f, 0x000000000000008f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84,
-            0x0ffffbee0ffffbff, 0xffff03ffffff03ff, 0x00000000000003ff, 0x00000000007fffff,
+            0x3f801fffffffffff, 0x0000000000004000, 0x00000fffffffffff, 0x000000000000001f,
+            0x000000000000088f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff,
+            0xffff000000000000, 0xffff03ffffff03ff, 0x00000000000003ff, 0x00000000007fffff,
             0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff
         ],
     };
@@ -323,7 +327,7 @@ pub mod derived_property {
         Alphabetic_table.lookup(c)
     }
 
-    pub const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie {
+    const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x0400408000000000, 0x0000000140000000, 0x0190a10000000000, 0x0000000000000000,
             0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
@@ -378,7 +382,7 @@ pub mod derived_property {
             0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0x9000000000000002,
             0x0000000c0040201e, 0x0000000000000004, 0x0000000000002001, 0xc000000000000011,
             0x0000000c00603dc1, 0x0000000c00003040, 0x1800000000000003, 0x0000000c0000201e,
-            0x00000000005c0400, 0x07f2000000000000, 0x0000000000007fc0, 0x1bf2000000000000,
+            0x00000000005c0400, 0x07f2000000000000, 0x0000000000007fc0, 0x1ff2000000000000,
             0x0000000000003f40, 0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df,
             0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064,
             0x1000000000000000, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000,
@@ -393,7 +397,7 @@ pub mod derived_property {
             0x000000007e000000, 0x7000000000000000, 0x0000000000200000, 0x0000000000001000,
             0xbff7800000000000, 0x00000000f0000000, 0x0003000000000000, 0x00000003ffffffff,
             0x0001000000000000, 0x0000000000000700, 0x0300000000000000, 0x0000006000000844,
-            0x8003ffff00000030, 0x00003fc000000000, 0x000000000003ff80, 0x13c8000000000007,
+            0x8003ffff00000030, 0x00003fc000000000, 0x000000000003ff80, 0x33c8000000000007,
             0x0000006000008000, 0x00667e0000000000, 0x1001000000001008, 0xc19d000000000000,
             0x0058300020000002, 0x00000000f8000000, 0x0000212000000000, 0x0000000040000000,
             0xfffc000000000000, 0x0000000000000003, 0x0000ffff0008ffff, 0x0000000000240000,
@@ -401,38 +405,40 @@ pub mod derived_property {
             0x0e00000800000000
         ],
         r4: [
-            0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            0, 1, 2, 3, 2, 2, 4, 2, 2, 2, 2, 5, 2, 6, 7, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
         ],
         r5: &[
             0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
             0, 0, 0, 7, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 17, 18, 19, 0, 0, 20, 21, 22,
-            23, 0, 0, 24, 25, 26, 27, 28, 0, 29, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 0, 0,
-            0, 0, 0, 34, 0, 35, 0, 36, 37, 38, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            23, 0, 0, 24, 25, 26, 27, 28, 0, 29, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 0,
+            0, 0, 0, 0, 35, 0, 36, 0, 37, 38, 39, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 44, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0,
+            51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 52, 53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0,
+            0, 0, 56, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 58, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 56, 57, 0, 0, 57, 57, 57, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, 0, 0, 62, 62, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
         ],
         r6: &[
             0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000,
@@ -442,14 +448,15 @@ pub mod derived_property {
             0x40d3800000000000, 0x000007f880000000, 0x1800000000000003, 0x001f1fc000000001,
             0xff00000000000000, 0x000000004000005c, 0x85f8000000000000, 0x000000000000000d,
             0xb03c000000000000, 0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001,
-            0x00bf280000000000, 0x00000fbce0000000, 0x06ff800000000000, 0x79f80000000007fe,
-            0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000,
-            0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000,
-            0x001f000000000000, 0x007f000000000000, 0x000000000000000f, 0x00000000ffff8000,
-            0x0000000300000000, 0x0000000f60000000, 0xfff8038000000000, 0x00003c0000000fe7,
-            0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010,
-            0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0, 0xf800000000000000,
-            0xffffffff00000002, 0xffffffffffffffff, 0x0000ffffffffffff
+            0x00bf280000000000, 0x00000fbce0000000, 0x06ff800000000000, 0x000000010cf00000,
+            0x79f80000000007fe, 0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000,
+            0x006dfcfffffc0000, 0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000,
+            0x0018000000000000, 0x01ff000000000000, 0x001f000000000000, 0x007f000000000000,
+            0x000000000000000f, 0x0000000000008000, 0x00000000ffff8000, 0x0000000b00000000,
+            0x0000000f60000000, 0xfff8038000000000, 0x00003c0000000fe7, 0x000000000000001c,
+            0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f,
+            0x3fff000000000000, 0x0000f00000000000, 0x00000000007f0000, 0x0000000000000ff0,
+            0xf800000000000000, 0xffffffff00000002, 0xffffffffffffffff, 0x0000ffffffffffff
         ],
     };
 
@@ -457,7 +464,7 @@ pub mod derived_property {
         Case_Ignorable_table.lookup(c)
     }
 
-    pub const Cased_table: &super::BoolTrie = &super::BoolTrie {
+    const Cased_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
             0xffffffffffffffff, 0xffffffffffffffff, 0xf7ffffffffffffff, 0xfffffffffffffff0,
@@ -512,7 +519,7 @@ pub mod derived_property {
             0xf21fbd503e2ffc84, 0xffffffff000043e0, 0x0000000000000018, 0xffc0000000000000,
             0x000003ffffffffff, 0xffff7fffffffffff, 0xffffffff7fffffff, 0x000c781fffffffff,
             0x000020bfffffffff, 0x00003fffffffffff, 0x000000003fffffff, 0xfffffffc00000000,
-            0x03ffffffffff78ff, 0x0700000000000000, 0xffff000000000000, 0xffff003ff7ffffff,
+            0xffffffffffff78ff, 0x070000000000007c, 0xffff000000000000, 0xffff00fff7ffffff,
             0x0000000000f8007f, 0x07fffffe00000000, 0x0000000007fffffe
         ],
         r4: [
@@ -558,7 +565,7 @@ pub mod derived_property {
         Cased_table.lookup(c)
     }
 
-    pub const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie {
+    const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
             0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
@@ -613,17 +620,17 @@ pub mod derived_property {
             0x0000000c00c0201e, 0x4000000000000004, 0x0000000000802001, 0xc000000000000011,
             0x0000000c00603dc1, 0x9000000000000002, 0x0000000c00603044, 0x5800000000000003,
             0x0000000c0080201e, 0x00000000805c8400, 0x07f2000000000000, 0x0000000000007f80,
-            0x1bf2000000000000, 0x0000000000003f00, 0x02a0000003000000, 0x7ffe000000000000,
+            0x1ff2000000000000, 0x0000000000003f00, 0x02a0000003000000, 0x7ffe000000000000,
             0x1ffffffffeffe0df, 0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000,
             0x0000000020002064, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000,
             0x3fb0000000000000, 0x00000000200ffe40, 0x0000000000003800, 0x0000020000000060,
             0x0e04018700000000, 0x0000000009800000, 0x9ff81fe57f400000, 0x7fff000000000000,
-            0x17d000000000000f, 0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000,
+            0x17f000000000000f, 0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000,
             0x00cff00000000000, 0x031021fdfff70000, 0xfbffffffffffffff, 0x0000000000001000,
             0x0001ffffffff0000, 0x0003800000000000, 0x8000000000000000, 0xffffffff00000000,
             0x0000fc0000000000, 0x0000000006000000, 0x3ff7800000000000, 0x00000000c0000000,
             0x0003000000000000, 0x0000006000000844, 0x8003ffff00000030, 0x00003fc000000000,
-            0x000000000003ff80, 0x13c8000000000007, 0x0000002000000000, 0x00667e0000000000,
+            0x000000000003ff80, 0x33c8000000000007, 0x0000002000000000, 0x00667e0000000000,
             0x1000000000001008, 0xc19d000000000000, 0x0040300000000002, 0x0000212000000000,
             0x0000000040000000, 0x0000ffff0000ffff
         ],
@@ -642,22 +649,22 @@ pub mod derived_property {
             0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
             0, 0, 0, 7, 0, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 0, 0, 16, 17, 18, 0, 0, 19, 20, 21,
-            22, 0, 0, 23, 24, 25, 26, 27, 0, 28, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0,
-            0, 0, 0, 33, 0, 34, 0, 35, 36, 37, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            22, 0, 0, 23, 24, 25, 26, 27, 0, 28, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 30, 31, 32, 33, 0,
+            0, 0, 0, 0, 34, 0, 35, 0, 36, 37, 38, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 48, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0,
-            53, 53, 53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 50, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+            0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 56, 0,
+            0, 56, 56, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0
+            0, 0, 0, 0
         ],
         r6: &[
             0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000,
@@ -667,13 +674,14 @@ pub mod derived_property {
             0x000007f880000000, 0x5800000000000003, 0x001f1fc000800001, 0xff00000000000000,
             0x000000004000005c, 0xa5f9000000000000, 0x000000000000000d, 0xb03c800000000000,
             0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001, 0x00bf280000000000,
-            0x00000fbce0000000, 0x06ff800000000000, 0x79f80000000007fe, 0x000000000e7e0080,
-            0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000, 0xb47e000000000000,
-            0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000, 0x001f000000000000,
-            0x007f000000000000, 0x0000000000078000, 0x0000000060000000, 0xf807c3a000000000,
-            0x00003c0000000fe7, 0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff,
-            0x0000fffef8000010, 0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0,
-            0xffffffff00000000, 0xffffffffffffffff, 0x0000ffffffffffff
+            0x00000fbce0000000, 0x06ff800000000000, 0x000000010cf00000, 0x79f80000000007fe,
+            0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000,
+            0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000,
+            0x001f000000000000, 0x007f000000000000, 0x0000000000008000, 0x0000000000078000,
+            0x0000000060000000, 0xf807c3a000000000, 0x00003c0000000fe7, 0x000000000000001c,
+            0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f,
+            0x0000f00000000000, 0x00000000007f0000, 0x00000000000007f0, 0xffffffff00000000,
+            0xffffffffffffffff, 0x0000ffffffffffff
         ],
     };
 
@@ -681,7 +689,7 @@ pub mod derived_property {
         Grapheme_Extend_table.lookup(c)
     }
 
-    pub const Lowercase_table: &super::BoolTrie = &super::BoolTrie {
+    const Lowercase_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x0000000000000000, 0x07fffffe00000000, 0x0420040000000000, 0xff7fffff80000000,
             0x55aaaaaaaaaaaaaa, 0xd4aaaaaaaaaaab55, 0xe6512d2a4e243129, 0xaa29aaaab5555240,
@@ -736,7 +744,7 @@ pub mod derived_property {
             0x000000001fff0000, 0x321080000008c400, 0xffff0000000043c0, 0x0000000000000010,
             0x000003ffffff0000, 0xffff000000000000, 0x3fda15627fffffff, 0x0008501aaaaaaaaa,
             0x000020bfffffffff, 0x00002aaaaaaaaaaa, 0x000000003aaaaaaa, 0xaaabaaa800000000,
-            0x95ffaaaaaaaaaaaa, 0x02a082aaaaba50aa, 0x0700000000000000, 0xffff003ff7ffffff,
+            0x95ffaaaaaaaaaaaa, 0xaaa082aaaaba50aa, 0x0700000000000008, 0xffff00fff7ffffff,
             0x0000000000f8007f, 0x0000000007fffffe
         ],
         r4: [
@@ -781,7 +789,7 @@ pub mod derived_property {
         Lowercase_table.lookup(c)
     }
 
-    pub const Uppercase_table: &super::BoolTrie = &super::BoolTrie {
+    const Uppercase_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x0000000000000000, 0x0000000007fffffe, 0x0000000000000000, 0x000000007f7fffff,
             0xaa55555555555555, 0x2b555555555554aa, 0x11aed2d5b1dbced6, 0x55d255554aaaa490,
@@ -815,7 +823,7 @@ pub mod derived_property {
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0,
-            21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -827,7 +835,7 @@ pub mod derived_property {
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 24, 0, 0, 0
+            0, 0, 0, 0, 0, 25, 0, 0, 0
         ],
         r3: &[
             0x0000000000000000, 0xffffffff00000000, 0x00000000000020bf, 0x003fffffffffffff,
@@ -835,8 +843,8 @@ pub mod derived_property {
             0x0000ff00aa003f00, 0x0f00000000000000, 0x0f001f000f000f00, 0xc00f3d503e273884,
             0x0000ffff00000020, 0x0000000000000008, 0xffc0000000000000, 0x000000000000ffff,
             0x00007fffffffffff, 0xc025ea9d00000000, 0x0004280555555555, 0x0000155555555555,
-            0x0000000005555555, 0x5554555400000000, 0x6a00555555555555, 0x015f7d5555452855,
-            0x07fffffe00000000
+            0x0000000005555555, 0x5554555400000000, 0x6a00555555555555, 0x555f7d5555452855,
+            0x0000000000000074, 0x07fffffe00000000
         ],
         r4: [
             0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -882,7 +890,7 @@ pub mod derived_property {
         Uppercase_table.lookup(c)
     }
 
-    pub const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
+    const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x03ff000000000000, 0x07fffffe87fffffe, 0x04a0040000000000, 0xff7fffffff7fffff,
             0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
@@ -941,7 +949,7 @@ pub mod derived_property {
             0xf3edfdfffff99fee, 0x0002ffcfb0c0399f, 0xc3ffc718d63dc7ec, 0x0000ffc000813dc7,
             0xe3fffdfffffddfff, 0x0000ffcf07603ddf, 0xf3effdfffffddfef, 0x0006ffcf40603ddf,
             0xfffffffffffddfef, 0xfc00ffcf80f07ddf, 0x2ffbfffffc7fffec, 0x000cffc0ff5f847f,
-            0x07fffffffffffffe, 0x0000000003ff7fff, 0x3bffecaefef02596, 0x00000000f3ff3f5f,
+            0x07fffffffffffffe, 0x0000000003ff7fff, 0x3fffffaffffff7d6, 0x00000000f3ff3f5f,
             0xc2a003ff03000001, 0xfffe1ffffffffeff, 0x1ffffffffeffffdf, 0x0000000000000040,
             0xffffffffffff03ff, 0xffffffff3fffffff, 0xf7ffffffffff20bf, 0xffffffff3d7f3dff,
             0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0003fe00e7ffffff,
@@ -951,7 +959,7 @@ pub mod derived_property {
             0x003fffffffffffff, 0x0fff0fff7fffffff, 0x001f3fffffffffc0, 0xffff0fffffffffff,
             0x0000000007ff03ff, 0xffffffff0fffffff, 0x9fffffff7fffffff, 0x3fff008003ff03ff,
             0x0000000000000000, 0x000ff80003ff0fff, 0x000fffffffffffff, 0x00ffffffffffffff,
-            0x3fffffffffffe3ff, 0xe7ffffffffff01ff, 0x03fffffffff70000, 0xfbffffffffffffff,
+            0x3fffffffffffe3ff, 0xe7ffffffffff01ff, 0x07fffffffff70000, 0xfbffffffffffffff,
             0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc,
             0x8000000000000000, 0x8002000000100001, 0x000000001fff0000, 0x0001ffe21fff0000,
             0xf3fffd503f2ffc84, 0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff,
@@ -959,10 +967,10 @@ pub mod derived_property {
             0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x1f3efffe000000e0, 0xfffffffee67fffff,
             0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000,
             0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000fffffff1fff,
-            0xbff0ffffffffffff, 0x0003ffffffffffff, 0xfffffffcff800000, 0x03fffffffffff9ff,
-            0xff80000000000000, 0x000000ffffffffff, 0xe8ffffff03ff003f, 0xffff3fffffffffff,
+            0xbff0ffffffffffff, 0x0003ffffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff,
+            0xff8000000000007c, 0x000000ffffffffff, 0xe8ffffff03ff003f, 0xffff3fffffffffff,
             0x1fffffff000fffff, 0x7fffffff03ff8001, 0x007fffffffffffff, 0xfc7fffff03ff3fff,
-            0x007cffff38000007, 0xffff7f7f007e7e7e, 0xffff003ff7ffffff, 0x03ff37ffffffffff,
+            0x007cffff38000007, 0xffff7f7f007e7e7e, 0xffff00fff7ffffff, 0x03ff37ffffffffff,
             0xffff000fffffffff, 0x0ffffffffffff87f, 0x0000000003ffffff, 0x5f7ffdffe0f8007f,
             0xffffffffffffffdb, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
             0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0x0018ffff0000ffff,
@@ -983,45 +991,45 @@ pub mod derived_property {
         r5: &[
             0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16, 4, 4, 2, 2, 2,
             2, 17, 18, 4, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27, 28, 29, 30, 31, 4, 2, 32, 33,
-            33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 4, 2, 37, 3, 38, 39, 40, 2, 41, 42, 4, 43, 44,
-            45, 46, 4, 4, 2, 47, 2, 48, 4, 4, 49, 50, 2, 51, 52, 53, 54, 4, 4, 4, 3, 4, 55, 56, 4,
-            4, 4, 4, 57, 58, 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 69, 2, 2, 2, 70, 4, 4, 4, 4, 4,
+            33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 37, 2, 38, 3, 39, 40, 41, 2, 42, 43, 4, 44, 45,
+            46, 47, 4, 4, 2, 48, 2, 49, 4, 4, 50, 51, 2, 52, 53, 54, 55, 4, 4, 4, 3, 4, 56, 57, 4,
+            4, 58, 59, 60, 61, 62, 53, 4, 4, 4, 4, 63, 64, 65, 4, 66, 67, 68, 4, 4, 4, 4, 37, 4, 4,
+            4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 2, 70, 2, 2, 2, 71, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            2, 2, 2, 2, 2, 2, 2, 2, 60, 72, 4, 73, 17, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4,
-            4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            4, 2, 2, 2, 2, 2, 2, 2, 2, 53, 73, 4, 74, 17, 75, 76, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
+            4, 4, 2, 77, 78, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 80, 2, 2, 2, 2, 2,
-            81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            84, 85, 4, 4, 86, 4, 4, 4, 4, 4, 4, 2, 87, 88, 89, 90, 91, 2, 2, 2, 2, 92, 93, 94, 95,
-            96, 97, 4, 4, 4, 4, 4, 4, 4, 4, 98, 99, 100, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 102, 2, 103, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 104, 105, 106, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 80, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 81, 2, 2, 2, 2,
+            2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 83, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 85, 86, 4, 4, 87, 4, 4, 4, 4, 4, 4, 2, 88, 89, 90, 91, 92, 2, 2, 2, 2, 93, 94, 95,
+            96, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 102, 4, 4, 4, 103, 104, 4, 4, 4, 4, 4, 105, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 106, 2, 107, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 109, 110, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 111, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 108,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 109, 4, 4, 4, 4, 4,
+            2, 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 113, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 110, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 111, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 114, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 115, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
         ],
         r6: &[
             0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
@@ -1033,23 +1041,24 @@ pub mod derived_property {
             0xc0ffffffffffffff, 0x873ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff,
             0x0000007ffffffeff, 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff,
             0x00000000000001ff, 0x0007ffffffffffff, 0x03ff00ffffffffff, 0xffff00801fffffff,
-            0x000000000001ffff, 0x8000ffc00000007f, 0x03ff01ffffff0000, 0xffdfffffffffffff,
-            0x004fffffffff0070, 0x0000000017ff1e1f, 0x40fffffffffbffff, 0xffff01ffbfffbd7f,
-            0x03ff07ffffffffff, 0xfbedfdfffff99fef, 0x001f1fcfe081399f, 0x0000000043ff07ff,
-            0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001, 0x0000000003ff0011,
-            0x00ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe7ffffff, 0xffffffff00000000,
-            0x800003ffffffffff, 0x7fffffffffffffff, 0xffffffffffff0080, 0x0000000023ffffcf,
-            0x01ffffffffffffff, 0xff7ffffffffffdff, 0xfffc000003ff0001, 0x007ffefffffcffff,
-            0xb47ffffffffffb7f, 0xfffffdbf03ff00ff, 0x000003ff01fb7fff, 0x007fffff00000000,
-            0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f, 0x000000000000007f,
-            0x000003ff7fffffff, 0x001f3fffffff0000, 0xe0fffff803ff000f, 0x000000000000ffff,
-            0x7fffffffffff001f, 0x00000000ffff8000, 0x0000000300000000, 0x0003ffffffffffff,
-            0xffff000000000000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000063ff01ff,
-            0xf807e3e000000000, 0x00003c0000000fe7, 0x000000000000001c, 0xffffffffffdfffff,
-            0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f,
-            0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, 0xffff7fffffff7fff,
-            0xfffffdfffffffdff, 0xffffffffffffcff7, 0xf87fffffffffffff, 0x00201fffffffffff,
-            0x0000fffef8000010, 0x000007dbf9ffff7f, 0x00000000007f001f, 0x0000000003ff07ff,
+            0x000000000001ffff, 0x007fffff00000000, 0x8000ffc00000007f, 0x03ff01ffffff0000,
+            0xffdfffffffffffff, 0x004fffffffff0070, 0x0000000017ff1e1f, 0x40fffffffffbffff,
+            0xffff01ffbfffbd7f, 0x03ff07ffffffffff, 0xfbedfdfffff99fef, 0x001f1fcfe081399f,
+            0x00000000c3ff07ff, 0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001,
+            0x0000000003ff0011, 0x01ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe7ffffff,
+            0xffffffff00000000, 0x800003ffffffffff, 0xfffffcff00000000, 0x0000001bfcffffff,
+            0x7fffffffffffffff, 0xffffffffffff0080, 0x0000000023ffffff, 0xff7ffffffffffdff,
+            0xfffc000003ff0001, 0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf03ff00ff,
+            0x000003ff01fb7fff, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f,
+            0x000000000000007f, 0x000003ff7fffffff, 0x001f3fffffff0000, 0xe0fffff803ff000f,
+            0x000000000000ffff, 0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000,
+            0x00ffffffffffffff, 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff,
+            0x0000000063ff01ff, 0xf807e3e000000000, 0x00003c0000000fe7, 0x000000000000001c,
+            0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
+            0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
+            0xffff7fffffff7fff, 0xfffffdfffffffdff, 0xffffffffffffcff7, 0xf87fffffffffffff,
+            0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, 0x3fff1fffffffffff,
+            0x00000000000043ff, 0x03ffffffffffffff, 0x00000000007f001f, 0x0000000003ff0fff,
             0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff,
             0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff, 0x0000ffffffffffff
         ],
@@ -1059,7 +1068,7 @@ pub mod derived_property {
         XID_Continue_table.lookup(c)
     }
 
-    pub const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
+    const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
         r1: [
             0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
             0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
@@ -1123,7 +1132,7 @@ pub mod derived_property {
             0x23edfdfffff99fe0, 0x00020003b0000000, 0x03ffc718d63dc7e8, 0x0000000000010000,
             0x23fffdfffffddfe0, 0x0000000307000000, 0x23effdfffffddfe1, 0x0006000340000000,
             0x27fffffffffddfe0, 0xfc00000380704000, 0x2ffbfffffc7fffe0, 0x000000000000007f,
-            0x0005fffffffffffe, 0x2005ecaefef02596, 0x00000000f000005f, 0x0000000000000001,
+            0x0005fffffffffffe, 0x2005ffaffffff7d6, 0x00000000f000005f, 0x0000000000000001,
             0x00001ffffffffeff, 0x0000000000001f00, 0x800007ffffffffff, 0xffe1c0623c3f0000,
             0xffffffff00004003, 0xf7ffffffffff20bf, 0xffffffffffffffff, 0xffffffff3d7f3dff,
             0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0000000007ffffff,
@@ -1134,18 +1143,18 @@ pub mod derived_property {
             0xffff0fffffffffff, 0x00000000000003ff, 0xffffffff007fffff, 0x00000000001fffff,
             0x0000008000000000, 0x000fffffffffffe0, 0x0000000000000fe0, 0xfc00c001fffffff8,
             0x0000003fffffffff, 0x0000000fffffffff, 0x3ffffffffc00e000, 0xe7ffffffffff01ff,
-            0x0063de0000000000, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff,
+            0x046fde0000000000, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff,
             0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000, 0xf3fffd503f2ffc84,
             0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff, 0xffffffff7fffffff,
             0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff,
             0x000000007f7f7f7f, 0x1f3e03fe000000e0, 0xfffffffee07fffff, 0xf7ffffffffffffff,
             0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, 0x0000ffffffffffff,
             0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff, 0x80007fffffffffff,
-            0xffffffff3fffffff, 0xfffffffcff800000, 0x03fffffffffff9ff, 0xff80000000000000,
+            0xffffffff3fffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, 0xff8000000000007c,
             0x00000007fffff7bb, 0x000ffffffffffffc, 0x68fc000000000000, 0xffff003ffffffc00,
             0x1fffffff0000007f, 0x0007fffffffffff0, 0x7c00ffdf00008000, 0x000001ffffffffff,
             0xc47fffff00000ff7, 0x3e62ffffffffffff, 0x001c07ff38000005, 0xffff7f7f007e7e7e,
-            0xffff003ff7ffffff, 0x00000007ffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
+            0xffff00fff7ffffff, 0x00000007ffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
             0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffa0f8007f, 0xffffffffffffffdb,
             0x0003ffffffffffff, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
             0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0xaa8a000000000000,
@@ -1166,43 +1175,43 @@ pub mod derived_property {
         r5: &[
             0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2,
             2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32,
-            32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 4, 35, 4, 36, 37, 38, 39, 40, 41, 42, 4, 43, 20,
-            44, 45, 4, 4, 5, 46, 47, 48, 4, 4, 49, 50, 47, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4,
-            4, 4, 4, 57, 58, 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 49, 2, 2, 2, 69, 4, 4, 4, 4, 4,
+            32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 35, 36, 4, 37, 38, 39, 40, 41, 42, 43, 4, 44,
+            20, 45, 46, 4, 4, 5, 47, 48, 49, 4, 4, 50, 51, 48, 52, 53, 4, 54, 4, 4, 4, 55, 4, 56,
+            57, 4, 4, 58, 59, 60, 61, 62, 63, 4, 4, 4, 4, 64, 65, 66, 4, 67, 68, 69, 4, 4, 4, 4, 70,
+            4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 2, 50, 2, 2, 2, 72, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            2, 2, 2, 2, 2, 2, 2, 2, 60, 20, 4, 71, 47, 72, 63, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4,
-            4, 2, 73, 74, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 63, 20, 4, 74, 48, 75, 66, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 2, 4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 76, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 77, 2, 2, 2, 2, 2,
-            78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 2, 79, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 81, 82, 83, 84, 85, 2, 2, 2, 2, 86, 87, 88, 89, 90,
-            91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 92, 2, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 93, 94, 95, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2,
+            2, 2, 2, 2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90,
+            91, 92, 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 95, 96, 4, 4, 4, 4, 4, 55, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 97, 2, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 103,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 104, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 105, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
         ],
         r6: &[
             0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
@@ -1213,23 +1222,25 @@ pub mod derived_property {
             0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff,
             0x003ffffffeef0001, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
             0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff,
-            0x0007ffffffffffff, 0xffff00801fffffff, 0x000000000000003f, 0x00fffffffffffff8,
-            0x0000fffffffffff8, 0x000001ffffff0000, 0x0000007ffffffff8, 0x0047ffffffff0010,
-            0x0007fffffffffff8, 0x000000001400001e, 0x00000ffffffbffff, 0xffff01ffbfffbd7f,
-            0x23edfdfffff99fe0, 0x00000003e0010000, 0x0000000000000780, 0x0000ffffffffffff,
-            0x00000000000000b0, 0x00007fffffffffff, 0x000000000f000000, 0x0000000000000010,
-            0x000007ffffffffff, 0x0000000007ffffff, 0x00000fffffffffff, 0xffffffff00000000,
-            0x80000000ffffffff, 0x0407fffffffff801, 0xfffffffff0010000, 0x00000000200003cf,
-            0x01ffffffffffffff, 0x00007ffffffffdff, 0xfffc000000000001, 0x000000000000ffff,
-            0x0001fffffffffb7f, 0xfffffdbf00000040, 0x00000000010003ff, 0x0007ffff00000000,
-            0x0000000003ffffff, 0x000000000000000f, 0x000000000000007f, 0x00003fffffff0000,
-            0xe0fffff80000000f, 0x000000000001001f, 0x00000000fff80000, 0x0000000300000000,
-            0x0003ffffffffffff, 0xffff000000000000, 0x0fffffffffffffff, 0x1fff07ffffffffff,
-            0x0000000003ff01ff, 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef,
-            0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd,
-            0xffdfffffffdfffff, 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7,
-            0x000000000000001f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff,
-            0x00000000007fffff, 0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff
+            0x0007ffffffffffff, 0xffff00801fffffff, 0x000000000000003f, 0x007fffff00000000,
+            0x00fffffffffffff8, 0x0000fffffffffff8, 0x000001ffffff0000, 0x0000007ffffffff8,
+            0x0047ffffffff0010, 0x0007fffffffffff8, 0x000000001400001e, 0x00000ffffffbffff,
+            0xffff01ffbfffbd7f, 0x23edfdfffff99fe0, 0x00000003e0010000, 0x0000000080000780,
+            0x0000ffffffffffff, 0x00000000000000b0, 0x00007fffffffffff, 0x000000000f000000,
+            0x0000000000000010, 0x010007ffffffffff, 0x0000000007ffffff, 0x00000fffffffffff,
+            0xffffffff00000000, 0x80000000ffffffff, 0xfffffcff00000000, 0x0000000a0001ffff,
+            0x0407fffffffff801, 0xfffffffff0010000, 0x00000000200003ff, 0x01ffffffffffffff,
+            0x00007ffffffffdff, 0xfffc000000000001, 0x000000000000ffff, 0x0001fffffffffb7f,
+            0xfffffdbf00000040, 0x00000000010003ff, 0x0007ffff00000000, 0x0000000003ffffff,
+            0x000000000000000f, 0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f,
+            0x00000000000107ff, 0x00000000fff80000, 0x0000000b00000000, 0x00ffffffffffffff,
+            0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000003ff01ff,
+            0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
+            0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
+            0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x3f801fffffffffff,
+            0x0000000000004000, 0x000000000000001f, 0x000000000000080f, 0x0af7fe96ffffffef,
+            0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff, 0xffff0003ffffffff,
+            0x00000001ffffffff, 0x000000003fffffff
         ],
     };
 
@@ -1239,8 +1250,8 @@ pub mod derived_property {
 
 }
 
-pub mod property {
-    pub const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
+pub(crate) mod property {
+    const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
         r1: &[
             0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
             1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1257,7 +1268,7 @@ pub mod property {
         Pattern_White_Space_table.lookup(c)
     }
 
-    pub const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
+    const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
         r1: &[
             0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
             1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1279,7 +1290,7 @@ pub mod property {
 
 }
 
-pub mod conversions {
+pub(crate) mod conversions {
     pub fn to_lower(c: char) -> [char; 3] {
         match bsearch_case_table(c, to_lowercase_table) {
             None        => [c, '\0', '\0'],
@@ -1792,131 +1803,134 @@ pub mod conversions {
         ['\u{26c}', '\0', '\0']), ('\u{a7ae}', ['\u{26a}', '\0', '\0']), ('\u{a7b0}', ['\u{29e}',
         '\0', '\0']), ('\u{a7b1}', ['\u{287}', '\0', '\0']), ('\u{a7b2}', ['\u{29d}', '\0', '\0']),
         ('\u{a7b3}', ['\u{ab53}', '\0', '\0']), ('\u{a7b4}', ['\u{a7b5}', '\0', '\0']), ('\u{a7b6}',
-        ['\u{a7b7}', '\0', '\0']), ('\u{a7b8}', ['\u{a7b9}', '\0', '\0']), ('\u{ff21}', ['\u{ff41}',
-        '\0', '\0']), ('\u{ff22}', ['\u{ff42}', '\0', '\0']), ('\u{ff23}', ['\u{ff43}', '\0',
-        '\0']), ('\u{ff24}', ['\u{ff44}', '\0', '\0']), ('\u{ff25}', ['\u{ff45}', '\0', '\0']),
-        ('\u{ff26}', ['\u{ff46}', '\0', '\0']), ('\u{ff27}', ['\u{ff47}', '\0', '\0']), ('\u{ff28}',
-        ['\u{ff48}', '\0', '\0']), ('\u{ff29}', ['\u{ff49}', '\0', '\0']), ('\u{ff2a}', ['\u{ff4a}',
-        '\0', '\0']), ('\u{ff2b}', ['\u{ff4b}', '\0', '\0']), ('\u{ff2c}', ['\u{ff4c}', '\0',
-        '\0']), ('\u{ff2d}', ['\u{ff4d}', '\0', '\0']), ('\u{ff2e}', ['\u{ff4e}', '\0', '\0']),
-        ('\u{ff2f}', ['\u{ff4f}', '\0', '\0']), ('\u{ff30}', ['\u{ff50}', '\0', '\0']), ('\u{ff31}',
-        ['\u{ff51}', '\0', '\0']), ('\u{ff32}', ['\u{ff52}', '\0', '\0']), ('\u{ff33}', ['\u{ff53}',
-        '\0', '\0']), ('\u{ff34}', ['\u{ff54}', '\0', '\0']), ('\u{ff35}', ['\u{ff55}', '\0',
-        '\0']), ('\u{ff36}', ['\u{ff56}', '\0', '\0']), ('\u{ff37}', ['\u{ff57}', '\0', '\0']),
-        ('\u{ff38}', ['\u{ff58}', '\0', '\0']), ('\u{ff39}', ['\u{ff59}', '\0', '\0']), ('\u{ff3a}',
-        ['\u{ff5a}', '\0', '\0']), ('\u{10400}', ['\u{10428}', '\0', '\0']), ('\u{10401}',
-        ['\u{10429}', '\0', '\0']), ('\u{10402}', ['\u{1042a}', '\0', '\0']), ('\u{10403}',
-        ['\u{1042b}', '\0', '\0']), ('\u{10404}', ['\u{1042c}', '\0', '\0']), ('\u{10405}',
-        ['\u{1042d}', '\0', '\0']), ('\u{10406}', ['\u{1042e}', '\0', '\0']), ('\u{10407}',
-        ['\u{1042f}', '\0', '\0']), ('\u{10408}', ['\u{10430}', '\0', '\0']), ('\u{10409}',
-        ['\u{10431}', '\0', '\0']), ('\u{1040a}', ['\u{10432}', '\0', '\0']), ('\u{1040b}',
-        ['\u{10433}', '\0', '\0']), ('\u{1040c}', ['\u{10434}', '\0', '\0']), ('\u{1040d}',
-        ['\u{10435}', '\0', '\0']), ('\u{1040e}', ['\u{10436}', '\0', '\0']), ('\u{1040f}',
-        ['\u{10437}', '\0', '\0']), ('\u{10410}', ['\u{10438}', '\0', '\0']), ('\u{10411}',
-        ['\u{10439}', '\0', '\0']), ('\u{10412}', ['\u{1043a}', '\0', '\0']), ('\u{10413}',
-        ['\u{1043b}', '\0', '\0']), ('\u{10414}', ['\u{1043c}', '\0', '\0']), ('\u{10415}',
-        ['\u{1043d}', '\0', '\0']), ('\u{10416}', ['\u{1043e}', '\0', '\0']), ('\u{10417}',
-        ['\u{1043f}', '\0', '\0']), ('\u{10418}', ['\u{10440}', '\0', '\0']), ('\u{10419}',
-        ['\u{10441}', '\0', '\0']), ('\u{1041a}', ['\u{10442}', '\0', '\0']), ('\u{1041b}',
-        ['\u{10443}', '\0', '\0']), ('\u{1041c}', ['\u{10444}', '\0', '\0']), ('\u{1041d}',
-        ['\u{10445}', '\0', '\0']), ('\u{1041e}', ['\u{10446}', '\0', '\0']), ('\u{1041f}',
-        ['\u{10447}', '\0', '\0']), ('\u{10420}', ['\u{10448}', '\0', '\0']), ('\u{10421}',
-        ['\u{10449}', '\0', '\0']), ('\u{10422}', ['\u{1044a}', '\0', '\0']), ('\u{10423}',
-        ['\u{1044b}', '\0', '\0']), ('\u{10424}', ['\u{1044c}', '\0', '\0']), ('\u{10425}',
-        ['\u{1044d}', '\0', '\0']), ('\u{10426}', ['\u{1044e}', '\0', '\0']), ('\u{10427}',
-        ['\u{1044f}', '\0', '\0']), ('\u{104b0}', ['\u{104d8}', '\0', '\0']), ('\u{104b1}',
-        ['\u{104d9}', '\0', '\0']), ('\u{104b2}', ['\u{104da}', '\0', '\0']), ('\u{104b3}',
-        ['\u{104db}', '\0', '\0']), ('\u{104b4}', ['\u{104dc}', '\0', '\0']), ('\u{104b5}',
-        ['\u{104dd}', '\0', '\0']), ('\u{104b6}', ['\u{104de}', '\0', '\0']), ('\u{104b7}',
-        ['\u{104df}', '\0', '\0']), ('\u{104b8}', ['\u{104e0}', '\0', '\0']), ('\u{104b9}',
-        ['\u{104e1}', '\0', '\0']), ('\u{104ba}', ['\u{104e2}', '\0', '\0']), ('\u{104bb}',
-        ['\u{104e3}', '\0', '\0']), ('\u{104bc}', ['\u{104e4}', '\0', '\0']), ('\u{104bd}',
-        ['\u{104e5}', '\0', '\0']), ('\u{104be}', ['\u{104e6}', '\0', '\0']), ('\u{104bf}',
-        ['\u{104e7}', '\0', '\0']), ('\u{104c0}', ['\u{104e8}', '\0', '\0']), ('\u{104c1}',
-        ['\u{104e9}', '\0', '\0']), ('\u{104c2}', ['\u{104ea}', '\0', '\0']), ('\u{104c3}',
-        ['\u{104eb}', '\0', '\0']), ('\u{104c4}', ['\u{104ec}', '\0', '\0']), ('\u{104c5}',
-        ['\u{104ed}', '\0', '\0']), ('\u{104c6}', ['\u{104ee}', '\0', '\0']), ('\u{104c7}',
-        ['\u{104ef}', '\0', '\0']), ('\u{104c8}', ['\u{104f0}', '\0', '\0']), ('\u{104c9}',
-        ['\u{104f1}', '\0', '\0']), ('\u{104ca}', ['\u{104f2}', '\0', '\0']), ('\u{104cb}',
-        ['\u{104f3}', '\0', '\0']), ('\u{104cc}', ['\u{104f4}', '\0', '\0']), ('\u{104cd}',
-        ['\u{104f5}', '\0', '\0']), ('\u{104ce}', ['\u{104f6}', '\0', '\0']), ('\u{104cf}',
-        ['\u{104f7}', '\0', '\0']), ('\u{104d0}', ['\u{104f8}', '\0', '\0']), ('\u{104d1}',
-        ['\u{104f9}', '\0', '\0']), ('\u{104d2}', ['\u{104fa}', '\0', '\0']), ('\u{104d3}',
-        ['\u{104fb}', '\0', '\0']), ('\u{10c80}', ['\u{10cc0}', '\0', '\0']), ('\u{10c81}',
-        ['\u{10cc1}', '\0', '\0']), ('\u{10c82}', ['\u{10cc2}', '\0', '\0']), ('\u{10c83}',
-        ['\u{10cc3}', '\0', '\0']), ('\u{10c84}', ['\u{10cc4}', '\0', '\0']), ('\u{10c85}',
-        ['\u{10cc5}', '\0', '\0']), ('\u{10c86}', ['\u{10cc6}', '\0', '\0']), ('\u{10c87}',
-        ['\u{10cc7}', '\0', '\0']), ('\u{10c88}', ['\u{10cc8}', '\0', '\0']), ('\u{10c89}',
-        ['\u{10cc9}', '\0', '\0']), ('\u{10c8a}', ['\u{10cca}', '\0', '\0']), ('\u{10c8b}',
-        ['\u{10ccb}', '\0', '\0']), ('\u{10c8c}', ['\u{10ccc}', '\0', '\0']), ('\u{10c8d}',
-        ['\u{10ccd}', '\0', '\0']), ('\u{10c8e}', ['\u{10cce}', '\0', '\0']), ('\u{10c8f}',
-        ['\u{10ccf}', '\0', '\0']), ('\u{10c90}', ['\u{10cd0}', '\0', '\0']), ('\u{10c91}',
-        ['\u{10cd1}', '\0', '\0']), ('\u{10c92}', ['\u{10cd2}', '\0', '\0']), ('\u{10c93}',
-        ['\u{10cd3}', '\0', '\0']), ('\u{10c94}', ['\u{10cd4}', '\0', '\0']), ('\u{10c95}',
-        ['\u{10cd5}', '\0', '\0']), ('\u{10c96}', ['\u{10cd6}', '\0', '\0']), ('\u{10c97}',
-        ['\u{10cd7}', '\0', '\0']), ('\u{10c98}', ['\u{10cd8}', '\0', '\0']), ('\u{10c99}',
-        ['\u{10cd9}', '\0', '\0']), ('\u{10c9a}', ['\u{10cda}', '\0', '\0']), ('\u{10c9b}',
-        ['\u{10cdb}', '\0', '\0']), ('\u{10c9c}', ['\u{10cdc}', '\0', '\0']), ('\u{10c9d}',
-        ['\u{10cdd}', '\0', '\0']), ('\u{10c9e}', ['\u{10cde}', '\0', '\0']), ('\u{10c9f}',
-        ['\u{10cdf}', '\0', '\0']), ('\u{10ca0}', ['\u{10ce0}', '\0', '\0']), ('\u{10ca1}',
-        ['\u{10ce1}', '\0', '\0']), ('\u{10ca2}', ['\u{10ce2}', '\0', '\0']), ('\u{10ca3}',
-        ['\u{10ce3}', '\0', '\0']), ('\u{10ca4}', ['\u{10ce4}', '\0', '\0']), ('\u{10ca5}',
-        ['\u{10ce5}', '\0', '\0']), ('\u{10ca6}', ['\u{10ce6}', '\0', '\0']), ('\u{10ca7}',
-        ['\u{10ce7}', '\0', '\0']), ('\u{10ca8}', ['\u{10ce8}', '\0', '\0']), ('\u{10ca9}',
-        ['\u{10ce9}', '\0', '\0']), ('\u{10caa}', ['\u{10cea}', '\0', '\0']), ('\u{10cab}',
-        ['\u{10ceb}', '\0', '\0']), ('\u{10cac}', ['\u{10cec}', '\0', '\0']), ('\u{10cad}',
-        ['\u{10ced}', '\0', '\0']), ('\u{10cae}', ['\u{10cee}', '\0', '\0']), ('\u{10caf}',
-        ['\u{10cef}', '\0', '\0']), ('\u{10cb0}', ['\u{10cf0}', '\0', '\0']), ('\u{10cb1}',
-        ['\u{10cf1}', '\0', '\0']), ('\u{10cb2}', ['\u{10cf2}', '\0', '\0']), ('\u{118a0}',
-        ['\u{118c0}', '\0', '\0']), ('\u{118a1}', ['\u{118c1}', '\0', '\0']), ('\u{118a2}',
-        ['\u{118c2}', '\0', '\0']), ('\u{118a3}', ['\u{118c3}', '\0', '\0']), ('\u{118a4}',
-        ['\u{118c4}', '\0', '\0']), ('\u{118a5}', ['\u{118c5}', '\0', '\0']), ('\u{118a6}',
-        ['\u{118c6}', '\0', '\0']), ('\u{118a7}', ['\u{118c7}', '\0', '\0']), ('\u{118a8}',
-        ['\u{118c8}', '\0', '\0']), ('\u{118a9}', ['\u{118c9}', '\0', '\0']), ('\u{118aa}',
-        ['\u{118ca}', '\0', '\0']), ('\u{118ab}', ['\u{118cb}', '\0', '\0']), ('\u{118ac}',
-        ['\u{118cc}', '\0', '\0']), ('\u{118ad}', ['\u{118cd}', '\0', '\0']), ('\u{118ae}',
-        ['\u{118ce}', '\0', '\0']), ('\u{118af}', ['\u{118cf}', '\0', '\0']), ('\u{118b0}',
-        ['\u{118d0}', '\0', '\0']), ('\u{118b1}', ['\u{118d1}', '\0', '\0']), ('\u{118b2}',
-        ['\u{118d2}', '\0', '\0']), ('\u{118b3}', ['\u{118d3}', '\0', '\0']), ('\u{118b4}',
-        ['\u{118d4}', '\0', '\0']), ('\u{118b5}', ['\u{118d5}', '\0', '\0']), ('\u{118b6}',
-        ['\u{118d6}', '\0', '\0']), ('\u{118b7}', ['\u{118d7}', '\0', '\0']), ('\u{118b8}',
-        ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']), ('\u{118ba}',
-        ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']), ('\u{118bc}',
-        ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']), ('\u{118be}',
-        ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']), ('\u{16e40}',
-        ['\u{16e60}', '\0', '\0']), ('\u{16e41}', ['\u{16e61}', '\0', '\0']), ('\u{16e42}',
-        ['\u{16e62}', '\0', '\0']), ('\u{16e43}', ['\u{16e63}', '\0', '\0']), ('\u{16e44}',
-        ['\u{16e64}', '\0', '\0']), ('\u{16e45}', ['\u{16e65}', '\0', '\0']), ('\u{16e46}',
-        ['\u{16e66}', '\0', '\0']), ('\u{16e47}', ['\u{16e67}', '\0', '\0']), ('\u{16e48}',
-        ['\u{16e68}', '\0', '\0']), ('\u{16e49}', ['\u{16e69}', '\0', '\0']), ('\u{16e4a}',
-        ['\u{16e6a}', '\0', '\0']), ('\u{16e4b}', ['\u{16e6b}', '\0', '\0']), ('\u{16e4c}',
-        ['\u{16e6c}', '\0', '\0']), ('\u{16e4d}', ['\u{16e6d}', '\0', '\0']), ('\u{16e4e}',
-        ['\u{16e6e}', '\0', '\0']), ('\u{16e4f}', ['\u{16e6f}', '\0', '\0']), ('\u{16e50}',
-        ['\u{16e70}', '\0', '\0']), ('\u{16e51}', ['\u{16e71}', '\0', '\0']), ('\u{16e52}',
-        ['\u{16e72}', '\0', '\0']), ('\u{16e53}', ['\u{16e73}', '\0', '\0']), ('\u{16e54}',
-        ['\u{16e74}', '\0', '\0']), ('\u{16e55}', ['\u{16e75}', '\0', '\0']), ('\u{16e56}',
-        ['\u{16e76}', '\0', '\0']), ('\u{16e57}', ['\u{16e77}', '\0', '\0']), ('\u{16e58}',
-        ['\u{16e78}', '\0', '\0']), ('\u{16e59}', ['\u{16e79}', '\0', '\0']), ('\u{16e5a}',
-        ['\u{16e7a}', '\0', '\0']), ('\u{16e5b}', ['\u{16e7b}', '\0', '\0']), ('\u{16e5c}',
-        ['\u{16e7c}', '\0', '\0']), ('\u{16e5d}', ['\u{16e7d}', '\0', '\0']), ('\u{16e5e}',
-        ['\u{16e7e}', '\0', '\0']), ('\u{16e5f}', ['\u{16e7f}', '\0', '\0']), ('\u{1e900}',
-        ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']), ('\u{1e902}',
-        ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']), ('\u{1e904}',
-        ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']), ('\u{1e906}',
-        ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']), ('\u{1e908}',
-        ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']), ('\u{1e90a}',
-        ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']), ('\u{1e90c}',
-        ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']), ('\u{1e90e}',
-        ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']), ('\u{1e910}',
-        ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']), ('\u{1e912}',
-        ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']), ('\u{1e914}',
-        ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']), ('\u{1e916}',
-        ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']), ('\u{1e918}',
-        ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']), ('\u{1e91a}',
-        ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']), ('\u{1e91c}',
-        ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']), ('\u{1e91e}',
-        ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']), ('\u{1e920}',
-        ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0'])
+        ['\u{a7b7}', '\0', '\0']), ('\u{a7b8}', ['\u{a7b9}', '\0', '\0']), ('\u{a7ba}', ['\u{a7bb}',
+        '\0', '\0']), ('\u{a7bc}', ['\u{a7bd}', '\0', '\0']), ('\u{a7be}', ['\u{a7bf}', '\0',
+        '\0']), ('\u{a7c2}', ['\u{a7c3}', '\0', '\0']), ('\u{a7c4}', ['\u{a794}', '\0', '\0']),
+        ('\u{a7c5}', ['\u{282}', '\0', '\0']), ('\u{a7c6}', ['\u{1d8e}', '\0', '\0']), ('\u{ff21}',
+        ['\u{ff41}', '\0', '\0']), ('\u{ff22}', ['\u{ff42}', '\0', '\0']), ('\u{ff23}', ['\u{ff43}',
+        '\0', '\0']), ('\u{ff24}', ['\u{ff44}', '\0', '\0']), ('\u{ff25}', ['\u{ff45}', '\0',
+        '\0']), ('\u{ff26}', ['\u{ff46}', '\0', '\0']), ('\u{ff27}', ['\u{ff47}', '\0', '\0']),
+        ('\u{ff28}', ['\u{ff48}', '\0', '\0']), ('\u{ff29}', ['\u{ff49}', '\0', '\0']), ('\u{ff2a}',
+        ['\u{ff4a}', '\0', '\0']), ('\u{ff2b}', ['\u{ff4b}', '\0', '\0']), ('\u{ff2c}', ['\u{ff4c}',
+        '\0', '\0']), ('\u{ff2d}', ['\u{ff4d}', '\0', '\0']), ('\u{ff2e}', ['\u{ff4e}', '\0',
+        '\0']), ('\u{ff2f}', ['\u{ff4f}', '\0', '\0']), ('\u{ff30}', ['\u{ff50}', '\0', '\0']),
+        ('\u{ff31}', ['\u{ff51}', '\0', '\0']), ('\u{ff32}', ['\u{ff52}', '\0', '\0']), ('\u{ff33}',
+        ['\u{ff53}', '\0', '\0']), ('\u{ff34}', ['\u{ff54}', '\0', '\0']), ('\u{ff35}', ['\u{ff55}',
+        '\0', '\0']), ('\u{ff36}', ['\u{ff56}', '\0', '\0']), ('\u{ff37}', ['\u{ff57}', '\0',
+        '\0']), ('\u{ff38}', ['\u{ff58}', '\0', '\0']), ('\u{ff39}', ['\u{ff59}', '\0', '\0']),
+        ('\u{ff3a}', ['\u{ff5a}', '\0', '\0']), ('\u{10400}', ['\u{10428}', '\0', '\0']),
+        ('\u{10401}', ['\u{10429}', '\0', '\0']), ('\u{10402}', ['\u{1042a}', '\0', '\0']),
+        ('\u{10403}', ['\u{1042b}', '\0', '\0']), ('\u{10404}', ['\u{1042c}', '\0', '\0']),
+        ('\u{10405}', ['\u{1042d}', '\0', '\0']), ('\u{10406}', ['\u{1042e}', '\0', '\0']),
+        ('\u{10407}', ['\u{1042f}', '\0', '\0']), ('\u{10408}', ['\u{10430}', '\0', '\0']),
+        ('\u{10409}', ['\u{10431}', '\0', '\0']), ('\u{1040a}', ['\u{10432}', '\0', '\0']),
+        ('\u{1040b}', ['\u{10433}', '\0', '\0']), ('\u{1040c}', ['\u{10434}', '\0', '\0']),
+        ('\u{1040d}', ['\u{10435}', '\0', '\0']), ('\u{1040e}', ['\u{10436}', '\0', '\0']),
+        ('\u{1040f}', ['\u{10437}', '\0', '\0']), ('\u{10410}', ['\u{10438}', '\0', '\0']),
+        ('\u{10411}', ['\u{10439}', '\0', '\0']), ('\u{10412}', ['\u{1043a}', '\0', '\0']),
+        ('\u{10413}', ['\u{1043b}', '\0', '\0']), ('\u{10414}', ['\u{1043c}', '\0', '\0']),
+        ('\u{10415}', ['\u{1043d}', '\0', '\0']), ('\u{10416}', ['\u{1043e}', '\0', '\0']),
+        ('\u{10417}', ['\u{1043f}', '\0', '\0']), ('\u{10418}', ['\u{10440}', '\0', '\0']),
+        ('\u{10419}', ['\u{10441}', '\0', '\0']), ('\u{1041a}', ['\u{10442}', '\0', '\0']),
+        ('\u{1041b}', ['\u{10443}', '\0', '\0']), ('\u{1041c}', ['\u{10444}', '\0', '\0']),
+        ('\u{1041d}', ['\u{10445}', '\0', '\0']), ('\u{1041e}', ['\u{10446}', '\0', '\0']),
+        ('\u{1041f}', ['\u{10447}', '\0', '\0']), ('\u{10420}', ['\u{10448}', '\0', '\0']),
+        ('\u{10421}', ['\u{10449}', '\0', '\0']), ('\u{10422}', ['\u{1044a}', '\0', '\0']),
+        ('\u{10423}', ['\u{1044b}', '\0', '\0']), ('\u{10424}', ['\u{1044c}', '\0', '\0']),
+        ('\u{10425}', ['\u{1044d}', '\0', '\0']), ('\u{10426}', ['\u{1044e}', '\0', '\0']),
+        ('\u{10427}', ['\u{1044f}', '\0', '\0']), ('\u{104b0}', ['\u{104d8}', '\0', '\0']),
+        ('\u{104b1}', ['\u{104d9}', '\0', '\0']), ('\u{104b2}', ['\u{104da}', '\0', '\0']),
+        ('\u{104b3}', ['\u{104db}', '\0', '\0']), ('\u{104b4}', ['\u{104dc}', '\0', '\0']),
+        ('\u{104b5}', ['\u{104dd}', '\0', '\0']), ('\u{104b6}', ['\u{104de}', '\0', '\0']),
+        ('\u{104b7}', ['\u{104df}', '\0', '\0']), ('\u{104b8}', ['\u{104e0}', '\0', '\0']),
+        ('\u{104b9}', ['\u{104e1}', '\0', '\0']), ('\u{104ba}', ['\u{104e2}', '\0', '\0']),
+        ('\u{104bb}', ['\u{104e3}', '\0', '\0']), ('\u{104bc}', ['\u{104e4}', '\0', '\0']),
+        ('\u{104bd}', ['\u{104e5}', '\0', '\0']), ('\u{104be}', ['\u{104e6}', '\0', '\0']),
+        ('\u{104bf}', ['\u{104e7}', '\0', '\0']), ('\u{104c0}', ['\u{104e8}', '\0', '\0']),
+        ('\u{104c1}', ['\u{104e9}', '\0', '\0']), ('\u{104c2}', ['\u{104ea}', '\0', '\0']),
+        ('\u{104c3}', ['\u{104eb}', '\0', '\0']), ('\u{104c4}', ['\u{104ec}', '\0', '\0']),
+        ('\u{104c5}', ['\u{104ed}', '\0', '\0']), ('\u{104c6}', ['\u{104ee}', '\0', '\0']),
+        ('\u{104c7}', ['\u{104ef}', '\0', '\0']), ('\u{104c8}', ['\u{104f0}', '\0', '\0']),
+        ('\u{104c9}', ['\u{104f1}', '\0', '\0']), ('\u{104ca}', ['\u{104f2}', '\0', '\0']),
+        ('\u{104cb}', ['\u{104f3}', '\0', '\0']), ('\u{104cc}', ['\u{104f4}', '\0', '\0']),
+        ('\u{104cd}', ['\u{104f5}', '\0', '\0']), ('\u{104ce}', ['\u{104f6}', '\0', '\0']),
+        ('\u{104cf}', ['\u{104f7}', '\0', '\0']), ('\u{104d0}', ['\u{104f8}', '\0', '\0']),
+        ('\u{104d1}', ['\u{104f9}', '\0', '\0']), ('\u{104d2}', ['\u{104fa}', '\0', '\0']),
+        ('\u{104d3}', ['\u{104fb}', '\0', '\0']), ('\u{10c80}', ['\u{10cc0}', '\0', '\0']),
+        ('\u{10c81}', ['\u{10cc1}', '\0', '\0']), ('\u{10c82}', ['\u{10cc2}', '\0', '\0']),
+        ('\u{10c83}', ['\u{10cc3}', '\0', '\0']), ('\u{10c84}', ['\u{10cc4}', '\0', '\0']),
+        ('\u{10c85}', ['\u{10cc5}', '\0', '\0']), ('\u{10c86}', ['\u{10cc6}', '\0', '\0']),
+        ('\u{10c87}', ['\u{10cc7}', '\0', '\0']), ('\u{10c88}', ['\u{10cc8}', '\0', '\0']),
+        ('\u{10c89}', ['\u{10cc9}', '\0', '\0']), ('\u{10c8a}', ['\u{10cca}', '\0', '\0']),
+        ('\u{10c8b}', ['\u{10ccb}', '\0', '\0']), ('\u{10c8c}', ['\u{10ccc}', '\0', '\0']),
+        ('\u{10c8d}', ['\u{10ccd}', '\0', '\0']), ('\u{10c8e}', ['\u{10cce}', '\0', '\0']),
+        ('\u{10c8f}', ['\u{10ccf}', '\0', '\0']), ('\u{10c90}', ['\u{10cd0}', '\0', '\0']),
+        ('\u{10c91}', ['\u{10cd1}', '\0', '\0']), ('\u{10c92}', ['\u{10cd2}', '\0', '\0']),
+        ('\u{10c93}', ['\u{10cd3}', '\0', '\0']), ('\u{10c94}', ['\u{10cd4}', '\0', '\0']),
+        ('\u{10c95}', ['\u{10cd5}', '\0', '\0']), ('\u{10c96}', ['\u{10cd6}', '\0', '\0']),
+        ('\u{10c97}', ['\u{10cd7}', '\0', '\0']), ('\u{10c98}', ['\u{10cd8}', '\0', '\0']),
+        ('\u{10c99}', ['\u{10cd9}', '\0', '\0']), ('\u{10c9a}', ['\u{10cda}', '\0', '\0']),
+        ('\u{10c9b}', ['\u{10cdb}', '\0', '\0']), ('\u{10c9c}', ['\u{10cdc}', '\0', '\0']),
+        ('\u{10c9d}', ['\u{10cdd}', '\0', '\0']), ('\u{10c9e}', ['\u{10cde}', '\0', '\0']),
+        ('\u{10c9f}', ['\u{10cdf}', '\0', '\0']), ('\u{10ca0}', ['\u{10ce0}', '\0', '\0']),
+        ('\u{10ca1}', ['\u{10ce1}', '\0', '\0']), ('\u{10ca2}', ['\u{10ce2}', '\0', '\0']),
+        ('\u{10ca3}', ['\u{10ce3}', '\0', '\0']), ('\u{10ca4}', ['\u{10ce4}', '\0', '\0']),
+        ('\u{10ca5}', ['\u{10ce5}', '\0', '\0']), ('\u{10ca6}', ['\u{10ce6}', '\0', '\0']),
+        ('\u{10ca7}', ['\u{10ce7}', '\0', '\0']), ('\u{10ca8}', ['\u{10ce8}', '\0', '\0']),
+        ('\u{10ca9}', ['\u{10ce9}', '\0', '\0']), ('\u{10caa}', ['\u{10cea}', '\0', '\0']),
+        ('\u{10cab}', ['\u{10ceb}', '\0', '\0']), ('\u{10cac}', ['\u{10cec}', '\0', '\0']),
+        ('\u{10cad}', ['\u{10ced}', '\0', '\0']), ('\u{10cae}', ['\u{10cee}', '\0', '\0']),
+        ('\u{10caf}', ['\u{10cef}', '\0', '\0']), ('\u{10cb0}', ['\u{10cf0}', '\0', '\0']),
+        ('\u{10cb1}', ['\u{10cf1}', '\0', '\0']), ('\u{10cb2}', ['\u{10cf2}', '\0', '\0']),
+        ('\u{118a0}', ['\u{118c0}', '\0', '\0']), ('\u{118a1}', ['\u{118c1}', '\0', '\0']),
+        ('\u{118a2}', ['\u{118c2}', '\0', '\0']), ('\u{118a3}', ['\u{118c3}', '\0', '\0']),
+        ('\u{118a4}', ['\u{118c4}', '\0', '\0']), ('\u{118a5}', ['\u{118c5}', '\0', '\0']),
+        ('\u{118a6}', ['\u{118c6}', '\0', '\0']), ('\u{118a7}', ['\u{118c7}', '\0', '\0']),
+        ('\u{118a8}', ['\u{118c8}', '\0', '\0']), ('\u{118a9}', ['\u{118c9}', '\0', '\0']),
+        ('\u{118aa}', ['\u{118ca}', '\0', '\0']), ('\u{118ab}', ['\u{118cb}', '\0', '\0']),
+        ('\u{118ac}', ['\u{118cc}', '\0', '\0']), ('\u{118ad}', ['\u{118cd}', '\0', '\0']),
+        ('\u{118ae}', ['\u{118ce}', '\0', '\0']), ('\u{118af}', ['\u{118cf}', '\0', '\0']),
+        ('\u{118b0}', ['\u{118d0}', '\0', '\0']), ('\u{118b1}', ['\u{118d1}', '\0', '\0']),
+        ('\u{118b2}', ['\u{118d2}', '\0', '\0']), ('\u{118b3}', ['\u{118d3}', '\0', '\0']),
+        ('\u{118b4}', ['\u{118d4}', '\0', '\0']), ('\u{118b5}', ['\u{118d5}', '\0', '\0']),
+        ('\u{118b6}', ['\u{118d6}', '\0', '\0']), ('\u{118b7}', ['\u{118d7}', '\0', '\0']),
+        ('\u{118b8}', ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']),
+        ('\u{118ba}', ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']),
+        ('\u{118bc}', ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']),
+        ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']),
+        ('\u{16e40}', ['\u{16e60}', '\0', '\0']), ('\u{16e41}', ['\u{16e61}', '\0', '\0']),
+        ('\u{16e42}', ['\u{16e62}', '\0', '\0']), ('\u{16e43}', ['\u{16e63}', '\0', '\0']),
+        ('\u{16e44}', ['\u{16e64}', '\0', '\0']), ('\u{16e45}', ['\u{16e65}', '\0', '\0']),
+        ('\u{16e46}', ['\u{16e66}', '\0', '\0']), ('\u{16e47}', ['\u{16e67}', '\0', '\0']),
+        ('\u{16e48}', ['\u{16e68}', '\0', '\0']), ('\u{16e49}', ['\u{16e69}', '\0', '\0']),
+        ('\u{16e4a}', ['\u{16e6a}', '\0', '\0']), ('\u{16e4b}', ['\u{16e6b}', '\0', '\0']),
+        ('\u{16e4c}', ['\u{16e6c}', '\0', '\0']), ('\u{16e4d}', ['\u{16e6d}', '\0', '\0']),
+        ('\u{16e4e}', ['\u{16e6e}', '\0', '\0']), ('\u{16e4f}', ['\u{16e6f}', '\0', '\0']),
+        ('\u{16e50}', ['\u{16e70}', '\0', '\0']), ('\u{16e51}', ['\u{16e71}', '\0', '\0']),
+        ('\u{16e52}', ['\u{16e72}', '\0', '\0']), ('\u{16e53}', ['\u{16e73}', '\0', '\0']),
+        ('\u{16e54}', ['\u{16e74}', '\0', '\0']), ('\u{16e55}', ['\u{16e75}', '\0', '\0']),
+        ('\u{16e56}', ['\u{16e76}', '\0', '\0']), ('\u{16e57}', ['\u{16e77}', '\0', '\0']),
+        ('\u{16e58}', ['\u{16e78}', '\0', '\0']), ('\u{16e59}', ['\u{16e79}', '\0', '\0']),
+        ('\u{16e5a}', ['\u{16e7a}', '\0', '\0']), ('\u{16e5b}', ['\u{16e7b}', '\0', '\0']),
+        ('\u{16e5c}', ['\u{16e7c}', '\0', '\0']), ('\u{16e5d}', ['\u{16e7d}', '\0', '\0']),
+        ('\u{16e5e}', ['\u{16e7e}', '\0', '\0']), ('\u{16e5f}', ['\u{16e7f}', '\0', '\0']),
+        ('\u{1e900}', ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']),
+        ('\u{1e902}', ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']),
+        ('\u{1e904}', ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']),
+        ('\u{1e906}', ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']),
+        ('\u{1e908}', ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']),
+        ('\u{1e90a}', ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']),
+        ('\u{1e90c}', ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']),
+        ('\u{1e90e}', ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']),
+        ('\u{1e910}', ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']),
+        ('\u{1e912}', ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']),
+        ('\u{1e914}', ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']),
+        ('\u{1e916}', ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']),
+        ('\u{1e918}', ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']),
+        ('\u{1e91a}', ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']),
+        ('\u{1e91c}', ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']),
+        ('\u{1e91e}', ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']),
+        ('\u{1e920}', ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0'])
     ];
 
     const to_uppercase_table: &[(char, [char; 3])] = &[
@@ -2019,260 +2033,261 @@ pub mod conversions {
         ('\u{26a}', ['\u{a7ae}', '\0', '\0']), ('\u{26b}', ['\u{2c62}', '\0', '\0']), ('\u{26c}',
         ['\u{a7ad}', '\0', '\0']), ('\u{26f}', ['\u{19c}', '\0', '\0']), ('\u{271}', ['\u{2c6e}',
         '\0', '\0']), ('\u{272}', ['\u{19d}', '\0', '\0']), ('\u{275}', ['\u{19f}', '\0', '\0']),
-        ('\u{27d}', ['\u{2c64}', '\0', '\0']), ('\u{280}', ['\u{1a6}', '\0', '\0']), ('\u{283}',
-        ['\u{1a9}', '\0', '\0']), ('\u{287}', ['\u{a7b1}', '\0', '\0']), ('\u{288}', ['\u{1ae}',
-        '\0', '\0']), ('\u{289}', ['\u{244}', '\0', '\0']), ('\u{28a}', ['\u{1b1}', '\0', '\0']),
-        ('\u{28b}', ['\u{1b2}', '\0', '\0']), ('\u{28c}', ['\u{245}', '\0', '\0']), ('\u{292}',
-        ['\u{1b7}', '\0', '\0']), ('\u{29d}', ['\u{a7b2}', '\0', '\0']), ('\u{29e}', ['\u{a7b0}',
-        '\0', '\0']), ('\u{345}', ['\u{399}', '\0', '\0']), ('\u{371}', ['\u{370}', '\0', '\0']),
-        ('\u{373}', ['\u{372}', '\0', '\0']), ('\u{377}', ['\u{376}', '\0', '\0']), ('\u{37b}',
-        ['\u{3fd}', '\0', '\0']), ('\u{37c}', ['\u{3fe}', '\0', '\0']), ('\u{37d}', ['\u{3ff}',
-        '\0', '\0']), ('\u{390}', ['\u{399}', '\u{308}', '\u{301}']), ('\u{3ac}', ['\u{386}', '\0',
-        '\0']), ('\u{3ad}', ['\u{388}', '\0', '\0']), ('\u{3ae}', ['\u{389}', '\0', '\0']),
-        ('\u{3af}', ['\u{38a}', '\0', '\0']), ('\u{3b0}', ['\u{3a5}', '\u{308}', '\u{301}']),
-        ('\u{3b1}', ['\u{391}', '\0', '\0']), ('\u{3b2}', ['\u{392}', '\0', '\0']), ('\u{3b3}',
-        ['\u{393}', '\0', '\0']), ('\u{3b4}', ['\u{394}', '\0', '\0']), ('\u{3b5}', ['\u{395}',
-        '\0', '\0']), ('\u{3b6}', ['\u{396}', '\0', '\0']), ('\u{3b7}', ['\u{397}', '\0', '\0']),
-        ('\u{3b8}', ['\u{398}', '\0', '\0']), ('\u{3b9}', ['\u{399}', '\0', '\0']), ('\u{3ba}',
-        ['\u{39a}', '\0', '\0']), ('\u{3bb}', ['\u{39b}', '\0', '\0']), ('\u{3bc}', ['\u{39c}',
-        '\0', '\0']), ('\u{3bd}', ['\u{39d}', '\0', '\0']), ('\u{3be}', ['\u{39e}', '\0', '\0']),
-        ('\u{3bf}', ['\u{39f}', '\0', '\0']), ('\u{3c0}', ['\u{3a0}', '\0', '\0']), ('\u{3c1}',
-        ['\u{3a1}', '\0', '\0']), ('\u{3c2}', ['\u{3a3}', '\0', '\0']), ('\u{3c3}', ['\u{3a3}',
-        '\0', '\0']), ('\u{3c4}', ['\u{3a4}', '\0', '\0']), ('\u{3c5}', ['\u{3a5}', '\0', '\0']),
-        ('\u{3c6}', ['\u{3a6}', '\0', '\0']), ('\u{3c7}', ['\u{3a7}', '\0', '\0']), ('\u{3c8}',
-        ['\u{3a8}', '\0', '\0']), ('\u{3c9}', ['\u{3a9}', '\0', '\0']), ('\u{3ca}', ['\u{3aa}',
-        '\0', '\0']), ('\u{3cb}', ['\u{3ab}', '\0', '\0']), ('\u{3cc}', ['\u{38c}', '\0', '\0']),
-        ('\u{3cd}', ['\u{38e}', '\0', '\0']), ('\u{3ce}', ['\u{38f}', '\0', '\0']), ('\u{3d0}',
-        ['\u{392}', '\0', '\0']), ('\u{3d1}', ['\u{398}', '\0', '\0']), ('\u{3d5}', ['\u{3a6}',
-        '\0', '\0']), ('\u{3d6}', ['\u{3a0}', '\0', '\0']), ('\u{3d7}', ['\u{3cf}', '\0', '\0']),
-        ('\u{3d9}', ['\u{3d8}', '\0', '\0']), ('\u{3db}', ['\u{3da}', '\0', '\0']), ('\u{3dd}',
-        ['\u{3dc}', '\0', '\0']), ('\u{3df}', ['\u{3de}', '\0', '\0']), ('\u{3e1}', ['\u{3e0}',
-        '\0', '\0']), ('\u{3e3}', ['\u{3e2}', '\0', '\0']), ('\u{3e5}', ['\u{3e4}', '\0', '\0']),
-        ('\u{3e7}', ['\u{3e6}', '\0', '\0']), ('\u{3e9}', ['\u{3e8}', '\0', '\0']), ('\u{3eb}',
-        ['\u{3ea}', '\0', '\0']), ('\u{3ed}', ['\u{3ec}', '\0', '\0']), ('\u{3ef}', ['\u{3ee}',
-        '\0', '\0']), ('\u{3f0}', ['\u{39a}', '\0', '\0']), ('\u{3f1}', ['\u{3a1}', '\0', '\0']),
-        ('\u{3f2}', ['\u{3f9}', '\0', '\0']), ('\u{3f3}', ['\u{37f}', '\0', '\0']), ('\u{3f5}',
-        ['\u{395}', '\0', '\0']), ('\u{3f8}', ['\u{3f7}', '\0', '\0']), ('\u{3fb}', ['\u{3fa}',
-        '\0', '\0']), ('\u{430}', ['\u{410}', '\0', '\0']), ('\u{431}', ['\u{411}', '\0', '\0']),
-        ('\u{432}', ['\u{412}', '\0', '\0']), ('\u{433}', ['\u{413}', '\0', '\0']), ('\u{434}',
-        ['\u{414}', '\0', '\0']), ('\u{435}', ['\u{415}', '\0', '\0']), ('\u{436}', ['\u{416}',
-        '\0', '\0']), ('\u{437}', ['\u{417}', '\0', '\0']), ('\u{438}', ['\u{418}', '\0', '\0']),
-        ('\u{439}', ['\u{419}', '\0', '\0']), ('\u{43a}', ['\u{41a}', '\0', '\0']), ('\u{43b}',
-        ['\u{41b}', '\0', '\0']), ('\u{43c}', ['\u{41c}', '\0', '\0']), ('\u{43d}', ['\u{41d}',
-        '\0', '\0']), ('\u{43e}', ['\u{41e}', '\0', '\0']), ('\u{43f}', ['\u{41f}', '\0', '\0']),
-        ('\u{440}', ['\u{420}', '\0', '\0']), ('\u{441}', ['\u{421}', '\0', '\0']), ('\u{442}',
-        ['\u{422}', '\0', '\0']), ('\u{443}', ['\u{423}', '\0', '\0']), ('\u{444}', ['\u{424}',
-        '\0', '\0']), ('\u{445}', ['\u{425}', '\0', '\0']), ('\u{446}', ['\u{426}', '\0', '\0']),
-        ('\u{447}', ['\u{427}', '\0', '\0']), ('\u{448}', ['\u{428}', '\0', '\0']), ('\u{449}',
-        ['\u{429}', '\0', '\0']), ('\u{44a}', ['\u{42a}', '\0', '\0']), ('\u{44b}', ['\u{42b}',
-        '\0', '\0']), ('\u{44c}', ['\u{42c}', '\0', '\0']), ('\u{44d}', ['\u{42d}', '\0', '\0']),
-        ('\u{44e}', ['\u{42e}', '\0', '\0']), ('\u{44f}', ['\u{42f}', '\0', '\0']), ('\u{450}',
-        ['\u{400}', '\0', '\0']), ('\u{451}', ['\u{401}', '\0', '\0']), ('\u{452}', ['\u{402}',
-        '\0', '\0']), ('\u{453}', ['\u{403}', '\0', '\0']), ('\u{454}', ['\u{404}', '\0', '\0']),
-        ('\u{455}', ['\u{405}', '\0', '\0']), ('\u{456}', ['\u{406}', '\0', '\0']), ('\u{457}',
-        ['\u{407}', '\0', '\0']), ('\u{458}', ['\u{408}', '\0', '\0']), ('\u{459}', ['\u{409}',
-        '\0', '\0']), ('\u{45a}', ['\u{40a}', '\0', '\0']), ('\u{45b}', ['\u{40b}', '\0', '\0']),
-        ('\u{45c}', ['\u{40c}', '\0', '\0']), ('\u{45d}', ['\u{40d}', '\0', '\0']), ('\u{45e}',
-        ['\u{40e}', '\0', '\0']), ('\u{45f}', ['\u{40f}', '\0', '\0']), ('\u{461}', ['\u{460}',
-        '\0', '\0']), ('\u{463}', ['\u{462}', '\0', '\0']), ('\u{465}', ['\u{464}', '\0', '\0']),
-        ('\u{467}', ['\u{466}', '\0', '\0']), ('\u{469}', ['\u{468}', '\0', '\0']), ('\u{46b}',
-        ['\u{46a}', '\0', '\0']), ('\u{46d}', ['\u{46c}', '\0', '\0']), ('\u{46f}', ['\u{46e}',
-        '\0', '\0']), ('\u{471}', ['\u{470}', '\0', '\0']), ('\u{473}', ['\u{472}', '\0', '\0']),
-        ('\u{475}', ['\u{474}', '\0', '\0']), ('\u{477}', ['\u{476}', '\0', '\0']), ('\u{479}',
-        ['\u{478}', '\0', '\0']), ('\u{47b}', ['\u{47a}', '\0', '\0']), ('\u{47d}', ['\u{47c}',
-        '\0', '\0']), ('\u{47f}', ['\u{47e}', '\0', '\0']), ('\u{481}', ['\u{480}', '\0', '\0']),
-        ('\u{48b}', ['\u{48a}', '\0', '\0']), ('\u{48d}', ['\u{48c}', '\0', '\0']), ('\u{48f}',
-        ['\u{48e}', '\0', '\0']), ('\u{491}', ['\u{490}', '\0', '\0']), ('\u{493}', ['\u{492}',
-        '\0', '\0']), ('\u{495}', ['\u{494}', '\0', '\0']), ('\u{497}', ['\u{496}', '\0', '\0']),
-        ('\u{499}', ['\u{498}', '\0', '\0']), ('\u{49b}', ['\u{49a}', '\0', '\0']), ('\u{49d}',
-        ['\u{49c}', '\0', '\0']), ('\u{49f}', ['\u{49e}', '\0', '\0']), ('\u{4a1}', ['\u{4a0}',
-        '\0', '\0']), ('\u{4a3}', ['\u{4a2}', '\0', '\0']), ('\u{4a5}', ['\u{4a4}', '\0', '\0']),
-        ('\u{4a7}', ['\u{4a6}', '\0', '\0']), ('\u{4a9}', ['\u{4a8}', '\0', '\0']), ('\u{4ab}',
-        ['\u{4aa}', '\0', '\0']), ('\u{4ad}', ['\u{4ac}', '\0', '\0']), ('\u{4af}', ['\u{4ae}',
-        '\0', '\0']), ('\u{4b1}', ['\u{4b0}', '\0', '\0']), ('\u{4b3}', ['\u{4b2}', '\0', '\0']),
-        ('\u{4b5}', ['\u{4b4}', '\0', '\0']), ('\u{4b7}', ['\u{4b6}', '\0', '\0']), ('\u{4b9}',
-        ['\u{4b8}', '\0', '\0']), ('\u{4bb}', ['\u{4ba}', '\0', '\0']), ('\u{4bd}', ['\u{4bc}',
-        '\0', '\0']), ('\u{4bf}', ['\u{4be}', '\0', '\0']), ('\u{4c2}', ['\u{4c1}', '\0', '\0']),
-        ('\u{4c4}', ['\u{4c3}', '\0', '\0']), ('\u{4c6}', ['\u{4c5}', '\0', '\0']), ('\u{4c8}',
-        ['\u{4c7}', '\0', '\0']), ('\u{4ca}', ['\u{4c9}', '\0', '\0']), ('\u{4cc}', ['\u{4cb}',
-        '\0', '\0']), ('\u{4ce}', ['\u{4cd}', '\0', '\0']), ('\u{4cf}', ['\u{4c0}', '\0', '\0']),
-        ('\u{4d1}', ['\u{4d0}', '\0', '\0']), ('\u{4d3}', ['\u{4d2}', '\0', '\0']), ('\u{4d5}',
-        ['\u{4d4}', '\0', '\0']), ('\u{4d7}', ['\u{4d6}', '\0', '\0']), ('\u{4d9}', ['\u{4d8}',
-        '\0', '\0']), ('\u{4db}', ['\u{4da}', '\0', '\0']), ('\u{4dd}', ['\u{4dc}', '\0', '\0']),
-        ('\u{4df}', ['\u{4de}', '\0', '\0']), ('\u{4e1}', ['\u{4e0}', '\0', '\0']), ('\u{4e3}',
-        ['\u{4e2}', '\0', '\0']), ('\u{4e5}', ['\u{4e4}', '\0', '\0']), ('\u{4e7}', ['\u{4e6}',
-        '\0', '\0']), ('\u{4e9}', ['\u{4e8}', '\0', '\0']), ('\u{4eb}', ['\u{4ea}', '\0', '\0']),
-        ('\u{4ed}', ['\u{4ec}', '\0', '\0']), ('\u{4ef}', ['\u{4ee}', '\0', '\0']), ('\u{4f1}',
-        ['\u{4f0}', '\0', '\0']), ('\u{4f3}', ['\u{4f2}', '\0', '\0']), ('\u{4f5}', ['\u{4f4}',
-        '\0', '\0']), ('\u{4f7}', ['\u{4f6}', '\0', '\0']), ('\u{4f9}', ['\u{4f8}', '\0', '\0']),
-        ('\u{4fb}', ['\u{4fa}', '\0', '\0']), ('\u{4fd}', ['\u{4fc}', '\0', '\0']), ('\u{4ff}',
-        ['\u{4fe}', '\0', '\0']), ('\u{501}', ['\u{500}', '\0', '\0']), ('\u{503}', ['\u{502}',
-        '\0', '\0']), ('\u{505}', ['\u{504}', '\0', '\0']), ('\u{507}', ['\u{506}', '\0', '\0']),
-        ('\u{509}', ['\u{508}', '\0', '\0']), ('\u{50b}', ['\u{50a}', '\0', '\0']), ('\u{50d}',
-        ['\u{50c}', '\0', '\0']), ('\u{50f}', ['\u{50e}', '\0', '\0']), ('\u{511}', ['\u{510}',
-        '\0', '\0']), ('\u{513}', ['\u{512}', '\0', '\0']), ('\u{515}', ['\u{514}', '\0', '\0']),
-        ('\u{517}', ['\u{516}', '\0', '\0']), ('\u{519}', ['\u{518}', '\0', '\0']), ('\u{51b}',
-        ['\u{51a}', '\0', '\0']), ('\u{51d}', ['\u{51c}', '\0', '\0']), ('\u{51f}', ['\u{51e}',
-        '\0', '\0']), ('\u{521}', ['\u{520}', '\0', '\0']), ('\u{523}', ['\u{522}', '\0', '\0']),
-        ('\u{525}', ['\u{524}', '\0', '\0']), ('\u{527}', ['\u{526}', '\0', '\0']), ('\u{529}',
-        ['\u{528}', '\0', '\0']), ('\u{52b}', ['\u{52a}', '\0', '\0']), ('\u{52d}', ['\u{52c}',
-        '\0', '\0']), ('\u{52f}', ['\u{52e}', '\0', '\0']), ('\u{561}', ['\u{531}', '\0', '\0']),
-        ('\u{562}', ['\u{532}', '\0', '\0']), ('\u{563}', ['\u{533}', '\0', '\0']), ('\u{564}',
-        ['\u{534}', '\0', '\0']), ('\u{565}', ['\u{535}', '\0', '\0']), ('\u{566}', ['\u{536}',
-        '\0', '\0']), ('\u{567}', ['\u{537}', '\0', '\0']), ('\u{568}', ['\u{538}', '\0', '\0']),
-        ('\u{569}', ['\u{539}', '\0', '\0']), ('\u{56a}', ['\u{53a}', '\0', '\0']), ('\u{56b}',
-        ['\u{53b}', '\0', '\0']), ('\u{56c}', ['\u{53c}', '\0', '\0']), ('\u{56d}', ['\u{53d}',
-        '\0', '\0']), ('\u{56e}', ['\u{53e}', '\0', '\0']), ('\u{56f}', ['\u{53f}', '\0', '\0']),
-        ('\u{570}', ['\u{540}', '\0', '\0']), ('\u{571}', ['\u{541}', '\0', '\0']), ('\u{572}',
-        ['\u{542}', '\0', '\0']), ('\u{573}', ['\u{543}', '\0', '\0']), ('\u{574}', ['\u{544}',
-        '\0', '\0']), ('\u{575}', ['\u{545}', '\0', '\0']), ('\u{576}', ['\u{546}', '\0', '\0']),
-        ('\u{577}', ['\u{547}', '\0', '\0']), ('\u{578}', ['\u{548}', '\0', '\0']), ('\u{579}',
-        ['\u{549}', '\0', '\0']), ('\u{57a}', ['\u{54a}', '\0', '\0']), ('\u{57b}', ['\u{54b}',
-        '\0', '\0']), ('\u{57c}', ['\u{54c}', '\0', '\0']), ('\u{57d}', ['\u{54d}', '\0', '\0']),
-        ('\u{57e}', ['\u{54e}', '\0', '\0']), ('\u{57f}', ['\u{54f}', '\0', '\0']), ('\u{580}',
-        ['\u{550}', '\0', '\0']), ('\u{581}', ['\u{551}', '\0', '\0']), ('\u{582}', ['\u{552}',
-        '\0', '\0']), ('\u{583}', ['\u{553}', '\0', '\0']), ('\u{584}', ['\u{554}', '\0', '\0']),
-        ('\u{585}', ['\u{555}', '\0', '\0']), ('\u{586}', ['\u{556}', '\0', '\0']), ('\u{587}',
-        ['\u{535}', '\u{552}', '\0']), ('\u{10d0}', ['\u{1c90}', '\0', '\0']), ('\u{10d1}',
-        ['\u{1c91}', '\0', '\0']), ('\u{10d2}', ['\u{1c92}', '\0', '\0']), ('\u{10d3}', ['\u{1c93}',
-        '\0', '\0']), ('\u{10d4}', ['\u{1c94}', '\0', '\0']), ('\u{10d5}', ['\u{1c95}', '\0',
-        '\0']), ('\u{10d6}', ['\u{1c96}', '\0', '\0']), ('\u{10d7}', ['\u{1c97}', '\0', '\0']),
-        ('\u{10d8}', ['\u{1c98}', '\0', '\0']), ('\u{10d9}', ['\u{1c99}', '\0', '\0']), ('\u{10da}',
-        ['\u{1c9a}', '\0', '\0']), ('\u{10db}', ['\u{1c9b}', '\0', '\0']), ('\u{10dc}', ['\u{1c9c}',
-        '\0', '\0']), ('\u{10dd}', ['\u{1c9d}', '\0', '\0']), ('\u{10de}', ['\u{1c9e}', '\0',
-        '\0']), ('\u{10df}', ['\u{1c9f}', '\0', '\0']), ('\u{10e0}', ['\u{1ca0}', '\0', '\0']),
-        ('\u{10e1}', ['\u{1ca1}', '\0', '\0']), ('\u{10e2}', ['\u{1ca2}', '\0', '\0']), ('\u{10e3}',
-        ['\u{1ca3}', '\0', '\0']), ('\u{10e4}', ['\u{1ca4}', '\0', '\0']), ('\u{10e5}', ['\u{1ca5}',
-        '\0', '\0']), ('\u{10e6}', ['\u{1ca6}', '\0', '\0']), ('\u{10e7}', ['\u{1ca7}', '\0',
-        '\0']), ('\u{10e8}', ['\u{1ca8}', '\0', '\0']), ('\u{10e9}', ['\u{1ca9}', '\0', '\0']),
-        ('\u{10ea}', ['\u{1caa}', '\0', '\0']), ('\u{10eb}', ['\u{1cab}', '\0', '\0']), ('\u{10ec}',
-        ['\u{1cac}', '\0', '\0']), ('\u{10ed}', ['\u{1cad}', '\0', '\0']), ('\u{10ee}', ['\u{1cae}',
-        '\0', '\0']), ('\u{10ef}', ['\u{1caf}', '\0', '\0']), ('\u{10f0}', ['\u{1cb0}', '\0',
-        '\0']), ('\u{10f1}', ['\u{1cb1}', '\0', '\0']), ('\u{10f2}', ['\u{1cb2}', '\0', '\0']),
-        ('\u{10f3}', ['\u{1cb3}', '\0', '\0']), ('\u{10f4}', ['\u{1cb4}', '\0', '\0']), ('\u{10f5}',
-        ['\u{1cb5}', '\0', '\0']), ('\u{10f6}', ['\u{1cb6}', '\0', '\0']), ('\u{10f7}', ['\u{1cb7}',
-        '\0', '\0']), ('\u{10f8}', ['\u{1cb8}', '\0', '\0']), ('\u{10f9}', ['\u{1cb9}', '\0',
-        '\0']), ('\u{10fa}', ['\u{1cba}', '\0', '\0']), ('\u{10fd}', ['\u{1cbd}', '\0', '\0']),
-        ('\u{10fe}', ['\u{1cbe}', '\0', '\0']), ('\u{10ff}', ['\u{1cbf}', '\0', '\0']), ('\u{13f8}',
-        ['\u{13f0}', '\0', '\0']), ('\u{13f9}', ['\u{13f1}', '\0', '\0']), ('\u{13fa}', ['\u{13f2}',
-        '\0', '\0']), ('\u{13fb}', ['\u{13f3}', '\0', '\0']), ('\u{13fc}', ['\u{13f4}', '\0',
-        '\0']), ('\u{13fd}', ['\u{13f5}', '\0', '\0']), ('\u{1c80}', ['\u{412}', '\0', '\0']),
-        ('\u{1c81}', ['\u{414}', '\0', '\0']), ('\u{1c82}', ['\u{41e}', '\0', '\0']), ('\u{1c83}',
-        ['\u{421}', '\0', '\0']), ('\u{1c84}', ['\u{422}', '\0', '\0']), ('\u{1c85}', ['\u{422}',
-        '\0', '\0']), ('\u{1c86}', ['\u{42a}', '\0', '\0']), ('\u{1c87}', ['\u{462}', '\0', '\0']),
-        ('\u{1c88}', ['\u{a64a}', '\0', '\0']), ('\u{1d79}', ['\u{a77d}', '\0', '\0']), ('\u{1d7d}',
-        ['\u{2c63}', '\0', '\0']), ('\u{1e01}', ['\u{1e00}', '\0', '\0']), ('\u{1e03}', ['\u{1e02}',
-        '\0', '\0']), ('\u{1e05}', ['\u{1e04}', '\0', '\0']), ('\u{1e07}', ['\u{1e06}', '\0',
-        '\0']), ('\u{1e09}', ['\u{1e08}', '\0', '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0', '\0']),
-        ('\u{1e0d}', ['\u{1e0c}', '\0', '\0']), ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']), ('\u{1e11}',
-        ['\u{1e10}', '\0', '\0']), ('\u{1e13}', ['\u{1e12}', '\0', '\0']), ('\u{1e15}', ['\u{1e14}',
-        '\0', '\0']), ('\u{1e17}', ['\u{1e16}', '\0', '\0']), ('\u{1e19}', ['\u{1e18}', '\0',
-        '\0']), ('\u{1e1b}', ['\u{1e1a}', '\0', '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0', '\0']),
-        ('\u{1e1f}', ['\u{1e1e}', '\0', '\0']), ('\u{1e21}', ['\u{1e20}', '\0', '\0']), ('\u{1e23}',
-        ['\u{1e22}', '\0', '\0']), ('\u{1e25}', ['\u{1e24}', '\0', '\0']), ('\u{1e27}', ['\u{1e26}',
-        '\0', '\0']), ('\u{1e29}', ['\u{1e28}', '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}', '\0',
-        '\0']), ('\u{1e2d}', ['\u{1e2c}', '\0', '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0', '\0']),
-        ('\u{1e31}', ['\u{1e30}', '\0', '\0']), ('\u{1e33}', ['\u{1e32}', '\0', '\0']), ('\u{1e35}',
-        ['\u{1e34}', '\0', '\0']), ('\u{1e37}', ['\u{1e36}', '\0', '\0']), ('\u{1e39}', ['\u{1e38}',
-        '\0', '\0']), ('\u{1e3b}', ['\u{1e3a}', '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}', '\0',
-        '\0']), ('\u{1e3f}', ['\u{1e3e}', '\0', '\0']), ('\u{1e41}', ['\u{1e40}', '\0', '\0']),
-        ('\u{1e43}', ['\u{1e42}', '\0', '\0']), ('\u{1e45}', ['\u{1e44}', '\0', '\0']), ('\u{1e47}',
-        ['\u{1e46}', '\0', '\0']), ('\u{1e49}', ['\u{1e48}', '\0', '\0']), ('\u{1e4b}', ['\u{1e4a}',
-        '\0', '\0']), ('\u{1e4d}', ['\u{1e4c}', '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}', '\0',
-        '\0']), ('\u{1e51}', ['\u{1e50}', '\0', '\0']), ('\u{1e53}', ['\u{1e52}', '\0', '\0']),
-        ('\u{1e55}', ['\u{1e54}', '\0', '\0']), ('\u{1e57}', ['\u{1e56}', '\0', '\0']), ('\u{1e59}',
-        ['\u{1e58}', '\0', '\0']), ('\u{1e5b}', ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}', ['\u{1e5c}',
-        '\0', '\0']), ('\u{1e5f}', ['\u{1e5e}', '\0', '\0']), ('\u{1e61}', ['\u{1e60}', '\0',
-        '\0']), ('\u{1e63}', ['\u{1e62}', '\0', '\0']), ('\u{1e65}', ['\u{1e64}', '\0', '\0']),
-        ('\u{1e67}', ['\u{1e66}', '\0', '\0']), ('\u{1e69}', ['\u{1e68}', '\0', '\0']), ('\u{1e6b}',
-        ['\u{1e6a}', '\0', '\0']), ('\u{1e6d}', ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}', ['\u{1e6e}',
-        '\0', '\0']), ('\u{1e71}', ['\u{1e70}', '\0', '\0']), ('\u{1e73}', ['\u{1e72}', '\0',
-        '\0']), ('\u{1e75}', ['\u{1e74}', '\0', '\0']), ('\u{1e77}', ['\u{1e76}', '\0', '\0']),
-        ('\u{1e79}', ['\u{1e78}', '\0', '\0']), ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']), ('\u{1e7d}',
-        ['\u{1e7c}', '\0', '\0']), ('\u{1e7f}', ['\u{1e7e}', '\0', '\0']), ('\u{1e81}', ['\u{1e80}',
-        '\0', '\0']), ('\u{1e83}', ['\u{1e82}', '\0', '\0']), ('\u{1e85}', ['\u{1e84}', '\0',
-        '\0']), ('\u{1e87}', ['\u{1e86}', '\0', '\0']), ('\u{1e89}', ['\u{1e88}', '\0', '\0']),
-        ('\u{1e8b}', ['\u{1e8a}', '\0', '\0']), ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']), ('\u{1e8f}',
-        ['\u{1e8e}', '\0', '\0']), ('\u{1e91}', ['\u{1e90}', '\0', '\0']), ('\u{1e93}', ['\u{1e92}',
-        '\0', '\0']), ('\u{1e95}', ['\u{1e94}', '\0', '\0']), ('\u{1e96}', ['\u{48}', '\u{331}',
-        '\0']), ('\u{1e97}', ['\u{54}', '\u{308}', '\0']), ('\u{1e98}', ['\u{57}', '\u{30a}',
-        '\0']), ('\u{1e99}', ['\u{59}', '\u{30a}', '\0']), ('\u{1e9a}', ['\u{41}', '\u{2be}',
-        '\0']), ('\u{1e9b}', ['\u{1e60}', '\0', '\0']), ('\u{1ea1}', ['\u{1ea0}', '\0', '\0']),
-        ('\u{1ea3}', ['\u{1ea2}', '\0', '\0']), ('\u{1ea5}', ['\u{1ea4}', '\0', '\0']), ('\u{1ea7}',
-        ['\u{1ea6}', '\0', '\0']), ('\u{1ea9}', ['\u{1ea8}', '\0', '\0']), ('\u{1eab}', ['\u{1eaa}',
-        '\0', '\0']), ('\u{1ead}', ['\u{1eac}', '\0', '\0']), ('\u{1eaf}', ['\u{1eae}', '\0',
-        '\0']), ('\u{1eb1}', ['\u{1eb0}', '\0', '\0']), ('\u{1eb3}', ['\u{1eb2}', '\0', '\0']),
-        ('\u{1eb5}', ['\u{1eb4}', '\0', '\0']), ('\u{1eb7}', ['\u{1eb6}', '\0', '\0']), ('\u{1eb9}',
-        ['\u{1eb8}', '\0', '\0']), ('\u{1ebb}', ['\u{1eba}', '\0', '\0']), ('\u{1ebd}', ['\u{1ebc}',
-        '\0', '\0']), ('\u{1ebf}', ['\u{1ebe}', '\0', '\0']), ('\u{1ec1}', ['\u{1ec0}', '\0',
-        '\0']), ('\u{1ec3}', ['\u{1ec2}', '\0', '\0']), ('\u{1ec5}', ['\u{1ec4}', '\0', '\0']),
-        ('\u{1ec7}', ['\u{1ec6}', '\0', '\0']), ('\u{1ec9}', ['\u{1ec8}', '\0', '\0']), ('\u{1ecb}',
-        ['\u{1eca}', '\0', '\0']), ('\u{1ecd}', ['\u{1ecc}', '\0', '\0']), ('\u{1ecf}', ['\u{1ece}',
-        '\0', '\0']), ('\u{1ed1}', ['\u{1ed0}', '\0', '\0']), ('\u{1ed3}', ['\u{1ed2}', '\0',
-        '\0']), ('\u{1ed5}', ['\u{1ed4}', '\0', '\0']), ('\u{1ed7}', ['\u{1ed6}', '\0', '\0']),
-        ('\u{1ed9}', ['\u{1ed8}', '\0', '\0']), ('\u{1edb}', ['\u{1eda}', '\0', '\0']), ('\u{1edd}',
-        ['\u{1edc}', '\0', '\0']), ('\u{1edf}', ['\u{1ede}', '\0', '\0']), ('\u{1ee1}', ['\u{1ee0}',
-        '\0', '\0']), ('\u{1ee3}', ['\u{1ee2}', '\0', '\0']), ('\u{1ee5}', ['\u{1ee4}', '\0',
-        '\0']), ('\u{1ee7}', ['\u{1ee6}', '\0', '\0']), ('\u{1ee9}', ['\u{1ee8}', '\0', '\0']),
-        ('\u{1eeb}', ['\u{1eea}', '\0', '\0']), ('\u{1eed}', ['\u{1eec}', '\0', '\0']), ('\u{1eef}',
-        ['\u{1eee}', '\0', '\0']), ('\u{1ef1}', ['\u{1ef0}', '\0', '\0']), ('\u{1ef3}', ['\u{1ef2}',
-        '\0', '\0']), ('\u{1ef5}', ['\u{1ef4}', '\0', '\0']), ('\u{1ef7}', ['\u{1ef6}', '\0',
-        '\0']), ('\u{1ef9}', ['\u{1ef8}', '\0', '\0']), ('\u{1efb}', ['\u{1efa}', '\0', '\0']),
-        ('\u{1efd}', ['\u{1efc}', '\0', '\0']), ('\u{1eff}', ['\u{1efe}', '\0', '\0']), ('\u{1f00}',
-        ['\u{1f08}', '\0', '\0']), ('\u{1f01}', ['\u{1f09}', '\0', '\0']), ('\u{1f02}', ['\u{1f0a}',
-        '\0', '\0']), ('\u{1f03}', ['\u{1f0b}', '\0', '\0']), ('\u{1f04}', ['\u{1f0c}', '\0',
-        '\0']), ('\u{1f05}', ['\u{1f0d}', '\0', '\0']), ('\u{1f06}', ['\u{1f0e}', '\0', '\0']),
-        ('\u{1f07}', ['\u{1f0f}', '\0', '\0']), ('\u{1f10}', ['\u{1f18}', '\0', '\0']), ('\u{1f11}',
-        ['\u{1f19}', '\0', '\0']), ('\u{1f12}', ['\u{1f1a}', '\0', '\0']), ('\u{1f13}', ['\u{1f1b}',
-        '\0', '\0']), ('\u{1f14}', ['\u{1f1c}', '\0', '\0']), ('\u{1f15}', ['\u{1f1d}', '\0',
-        '\0']), ('\u{1f20}', ['\u{1f28}', '\0', '\0']), ('\u{1f21}', ['\u{1f29}', '\0', '\0']),
-        ('\u{1f22}', ['\u{1f2a}', '\0', '\0']), ('\u{1f23}', ['\u{1f2b}', '\0', '\0']), ('\u{1f24}',
-        ['\u{1f2c}', '\0', '\0']), ('\u{1f25}', ['\u{1f2d}', '\0', '\0']), ('\u{1f26}', ['\u{1f2e}',
-        '\0', '\0']), ('\u{1f27}', ['\u{1f2f}', '\0', '\0']), ('\u{1f30}', ['\u{1f38}', '\0',
-        '\0']), ('\u{1f31}', ['\u{1f39}', '\0', '\0']), ('\u{1f32}', ['\u{1f3a}', '\0', '\0']),
-        ('\u{1f33}', ['\u{1f3b}', '\0', '\0']), ('\u{1f34}', ['\u{1f3c}', '\0', '\0']), ('\u{1f35}',
-        ['\u{1f3d}', '\0', '\0']), ('\u{1f36}', ['\u{1f3e}', '\0', '\0']), ('\u{1f37}', ['\u{1f3f}',
-        '\0', '\0']), ('\u{1f40}', ['\u{1f48}', '\0', '\0']), ('\u{1f41}', ['\u{1f49}', '\0',
-        '\0']), ('\u{1f42}', ['\u{1f4a}', '\0', '\0']), ('\u{1f43}', ['\u{1f4b}', '\0', '\0']),
-        ('\u{1f44}', ['\u{1f4c}', '\0', '\0']), ('\u{1f45}', ['\u{1f4d}', '\0', '\0']), ('\u{1f50}',
-        ['\u{3a5}', '\u{313}', '\0']), ('\u{1f51}', ['\u{1f59}', '\0', '\0']), ('\u{1f52}',
-        ['\u{3a5}', '\u{313}', '\u{300}']), ('\u{1f53}', ['\u{1f5b}', '\0', '\0']), ('\u{1f54}',
-        ['\u{3a5}', '\u{313}', '\u{301}']), ('\u{1f55}', ['\u{1f5d}', '\0', '\0']), ('\u{1f56}',
-        ['\u{3a5}', '\u{313}', '\u{342}']), ('\u{1f57}', ['\u{1f5f}', '\0', '\0']), ('\u{1f60}',
-        ['\u{1f68}', '\0', '\0']), ('\u{1f61}', ['\u{1f69}', '\0', '\0']), ('\u{1f62}', ['\u{1f6a}',
-        '\0', '\0']), ('\u{1f63}', ['\u{1f6b}', '\0', '\0']), ('\u{1f64}', ['\u{1f6c}', '\0',
-        '\0']), ('\u{1f65}', ['\u{1f6d}', '\0', '\0']), ('\u{1f66}', ['\u{1f6e}', '\0', '\0']),
-        ('\u{1f67}', ['\u{1f6f}', '\0', '\0']), ('\u{1f70}', ['\u{1fba}', '\0', '\0']), ('\u{1f71}',
-        ['\u{1fbb}', '\0', '\0']), ('\u{1f72}', ['\u{1fc8}', '\0', '\0']), ('\u{1f73}', ['\u{1fc9}',
-        '\0', '\0']), ('\u{1f74}', ['\u{1fca}', '\0', '\0']), ('\u{1f75}', ['\u{1fcb}', '\0',
-        '\0']), ('\u{1f76}', ['\u{1fda}', '\0', '\0']), ('\u{1f77}', ['\u{1fdb}', '\0', '\0']),
-        ('\u{1f78}', ['\u{1ff8}', '\0', '\0']), ('\u{1f79}', ['\u{1ff9}', '\0', '\0']), ('\u{1f7a}',
-        ['\u{1fea}', '\0', '\0']), ('\u{1f7b}', ['\u{1feb}', '\0', '\0']), ('\u{1f7c}', ['\u{1ffa}',
-        '\0', '\0']), ('\u{1f7d}', ['\u{1ffb}', '\0', '\0']), ('\u{1f80}', ['\u{1f08}', '\u{399}',
-        '\0']), ('\u{1f81}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f82}', ['\u{1f0a}', '\u{399}',
-        '\0']), ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f84}', ['\u{1f0c}', '\u{399}',
-        '\0']), ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f86}', ['\u{1f0e}', '\u{399}',
-        '\0']), ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f88}', ['\u{1f08}', '\u{399}',
-        '\0']), ('\u{1f89}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f8a}', ['\u{1f0a}', '\u{399}',
-        '\0']), ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f8c}', ['\u{1f0c}', '\u{399}',
-        '\0']), ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f8e}', ['\u{1f0e}', '\u{399}',
-        '\0']), ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f90}', ['\u{1f28}', '\u{399}',
-        '\0']), ('\u{1f91}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f92}', ['\u{1f2a}', '\u{399}',
-        '\0']), ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f94}', ['\u{1f2c}', '\u{399}',
-        '\0']), ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f96}', ['\u{1f2e}', '\u{399}',
-        '\0']), ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1f98}', ['\u{1f28}', '\u{399}',
-        '\0']), ('\u{1f99}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f9a}', ['\u{1f2a}', '\u{399}',
-        '\0']), ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f9c}', ['\u{1f2c}', '\u{399}',
-        '\0']), ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f9e}', ['\u{1f2e}', '\u{399}',
-        '\0']), ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1fa0}', ['\u{1f68}', '\u{399}',
-        '\0']), ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1fa2}', ['\u{1f6a}', '\u{399}',
-        '\0']), ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fa4}', ['\u{1f6c}', '\u{399}',
-        '\0']), ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fa6}', ['\u{1f6e}', '\u{399}',
-        '\0']), ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fa8}', ['\u{1f68}', '\u{399}',
-        '\0']), ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1faa}', ['\u{1f6a}', '\u{399}',
-        '\0']), ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fac}', ['\u{1f6c}', '\u{399}',
-        '\0']), ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fae}', ['\u{1f6e}', '\u{399}',
-        '\0']), ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fb0}', ['\u{1fb8}', '\0', '\0']),
+        ('\u{27d}', ['\u{2c64}', '\0', '\0']), ('\u{280}', ['\u{1a6}', '\0', '\0']), ('\u{282}',
+        ['\u{a7c5}', '\0', '\0']), ('\u{283}', ['\u{1a9}', '\0', '\0']), ('\u{287}', ['\u{a7b1}',
+        '\0', '\0']), ('\u{288}', ['\u{1ae}', '\0', '\0']), ('\u{289}', ['\u{244}', '\0', '\0']),
+        ('\u{28a}', ['\u{1b1}', '\0', '\0']), ('\u{28b}', ['\u{1b2}', '\0', '\0']), ('\u{28c}',
+        ['\u{245}', '\0', '\0']), ('\u{292}', ['\u{1b7}', '\0', '\0']), ('\u{29d}', ['\u{a7b2}',
+        '\0', '\0']), ('\u{29e}', ['\u{a7b0}', '\0', '\0']), ('\u{345}', ['\u{399}', '\0', '\0']),
+        ('\u{371}', ['\u{370}', '\0', '\0']), ('\u{373}', ['\u{372}', '\0', '\0']), ('\u{377}',
+        ['\u{376}', '\0', '\0']), ('\u{37b}', ['\u{3fd}', '\0', '\0']), ('\u{37c}', ['\u{3fe}',
+        '\0', '\0']), ('\u{37d}', ['\u{3ff}', '\0', '\0']), ('\u{390}', ['\u{399}', '\u{308}',
+        '\u{301}']), ('\u{3ac}', ['\u{386}', '\0', '\0']), ('\u{3ad}', ['\u{388}', '\0', '\0']),
+        ('\u{3ae}', ['\u{389}', '\0', '\0']), ('\u{3af}', ['\u{38a}', '\0', '\0']), ('\u{3b0}',
+        ['\u{3a5}', '\u{308}', '\u{301}']), ('\u{3b1}', ['\u{391}', '\0', '\0']), ('\u{3b2}',
+        ['\u{392}', '\0', '\0']), ('\u{3b3}', ['\u{393}', '\0', '\0']), ('\u{3b4}', ['\u{394}',
+        '\0', '\0']), ('\u{3b5}', ['\u{395}', '\0', '\0']), ('\u{3b6}', ['\u{396}', '\0', '\0']),
+        ('\u{3b7}', ['\u{397}', '\0', '\0']), ('\u{3b8}', ['\u{398}', '\0', '\0']), ('\u{3b9}',
+        ['\u{399}', '\0', '\0']), ('\u{3ba}', ['\u{39a}', '\0', '\0']), ('\u{3bb}', ['\u{39b}',
+        '\0', '\0']), ('\u{3bc}', ['\u{39c}', '\0', '\0']), ('\u{3bd}', ['\u{39d}', '\0', '\0']),
+        ('\u{3be}', ['\u{39e}', '\0', '\0']), ('\u{3bf}', ['\u{39f}', '\0', '\0']), ('\u{3c0}',
+        ['\u{3a0}', '\0', '\0']), ('\u{3c1}', ['\u{3a1}', '\0', '\0']), ('\u{3c2}', ['\u{3a3}',
+        '\0', '\0']), ('\u{3c3}', ['\u{3a3}', '\0', '\0']), ('\u{3c4}', ['\u{3a4}', '\0', '\0']),
+        ('\u{3c5}', ['\u{3a5}', '\0', '\0']), ('\u{3c6}', ['\u{3a6}', '\0', '\0']), ('\u{3c7}',
+        ['\u{3a7}', '\0', '\0']), ('\u{3c8}', ['\u{3a8}', '\0', '\0']), ('\u{3c9}', ['\u{3a9}',
+        '\0', '\0']), ('\u{3ca}', ['\u{3aa}', '\0', '\0']), ('\u{3cb}', ['\u{3ab}', '\0', '\0']),
+        ('\u{3cc}', ['\u{38c}', '\0', '\0']), ('\u{3cd}', ['\u{38e}', '\0', '\0']), ('\u{3ce}',
+        ['\u{38f}', '\0', '\0']), ('\u{3d0}', ['\u{392}', '\0', '\0']), ('\u{3d1}', ['\u{398}',
+        '\0', '\0']), ('\u{3d5}', ['\u{3a6}', '\0', '\0']), ('\u{3d6}', ['\u{3a0}', '\0', '\0']),
+        ('\u{3d7}', ['\u{3cf}', '\0', '\0']), ('\u{3d9}', ['\u{3d8}', '\0', '\0']), ('\u{3db}',
+        ['\u{3da}', '\0', '\0']), ('\u{3dd}', ['\u{3dc}', '\0', '\0']), ('\u{3df}', ['\u{3de}',
+        '\0', '\0']), ('\u{3e1}', ['\u{3e0}', '\0', '\0']), ('\u{3e3}', ['\u{3e2}', '\0', '\0']),
+        ('\u{3e5}', ['\u{3e4}', '\0', '\0']), ('\u{3e7}', ['\u{3e6}', '\0', '\0']), ('\u{3e9}',
+        ['\u{3e8}', '\0', '\0']), ('\u{3eb}', ['\u{3ea}', '\0', '\0']), ('\u{3ed}', ['\u{3ec}',
+        '\0', '\0']), ('\u{3ef}', ['\u{3ee}', '\0', '\0']), ('\u{3f0}', ['\u{39a}', '\0', '\0']),
+        ('\u{3f1}', ['\u{3a1}', '\0', '\0']), ('\u{3f2}', ['\u{3f9}', '\0', '\0']), ('\u{3f3}',
+        ['\u{37f}', '\0', '\0']), ('\u{3f5}', ['\u{395}', '\0', '\0']), ('\u{3f8}', ['\u{3f7}',
+        '\0', '\0']), ('\u{3fb}', ['\u{3fa}', '\0', '\0']), ('\u{430}', ['\u{410}', '\0', '\0']),
+        ('\u{431}', ['\u{411}', '\0', '\0']), ('\u{432}', ['\u{412}', '\0', '\0']), ('\u{433}',
+        ['\u{413}', '\0', '\0']), ('\u{434}', ['\u{414}', '\0', '\0']), ('\u{435}', ['\u{415}',
+        '\0', '\0']), ('\u{436}', ['\u{416}', '\0', '\0']), ('\u{437}', ['\u{417}', '\0', '\0']),
+        ('\u{438}', ['\u{418}', '\0', '\0']), ('\u{439}', ['\u{419}', '\0', '\0']), ('\u{43a}',
+        ['\u{41a}', '\0', '\0']), ('\u{43b}', ['\u{41b}', '\0', '\0']), ('\u{43c}', ['\u{41c}',
+        '\0', '\0']), ('\u{43d}', ['\u{41d}', '\0', '\0']), ('\u{43e}', ['\u{41e}', '\0', '\0']),
+        ('\u{43f}', ['\u{41f}', '\0', '\0']), ('\u{440}', ['\u{420}', '\0', '\0']), ('\u{441}',
+        ['\u{421}', '\0', '\0']), ('\u{442}', ['\u{422}', '\0', '\0']), ('\u{443}', ['\u{423}',
+        '\0', '\0']), ('\u{444}', ['\u{424}', '\0', '\0']), ('\u{445}', ['\u{425}', '\0', '\0']),
+        ('\u{446}', ['\u{426}', '\0', '\0']), ('\u{447}', ['\u{427}', '\0', '\0']), ('\u{448}',
+        ['\u{428}', '\0', '\0']), ('\u{449}', ['\u{429}', '\0', '\0']), ('\u{44a}', ['\u{42a}',
+        '\0', '\0']), ('\u{44b}', ['\u{42b}', '\0', '\0']), ('\u{44c}', ['\u{42c}', '\0', '\0']),
+        ('\u{44d}', ['\u{42d}', '\0', '\0']), ('\u{44e}', ['\u{42e}', '\0', '\0']), ('\u{44f}',
+        ['\u{42f}', '\0', '\0']), ('\u{450}', ['\u{400}', '\0', '\0']), ('\u{451}', ['\u{401}',
+        '\0', '\0']), ('\u{452}', ['\u{402}', '\0', '\0']), ('\u{453}', ['\u{403}', '\0', '\0']),
+        ('\u{454}', ['\u{404}', '\0', '\0']), ('\u{455}', ['\u{405}', '\0', '\0']), ('\u{456}',
+        ['\u{406}', '\0', '\0']), ('\u{457}', ['\u{407}', '\0', '\0']), ('\u{458}', ['\u{408}',
+        '\0', '\0']), ('\u{459}', ['\u{409}', '\0', '\0']), ('\u{45a}', ['\u{40a}', '\0', '\0']),
+        ('\u{45b}', ['\u{40b}', '\0', '\0']), ('\u{45c}', ['\u{40c}', '\0', '\0']), ('\u{45d}',
+        ['\u{40d}', '\0', '\0']), ('\u{45e}', ['\u{40e}', '\0', '\0']), ('\u{45f}', ['\u{40f}',
+        '\0', '\0']), ('\u{461}', ['\u{460}', '\0', '\0']), ('\u{463}', ['\u{462}', '\0', '\0']),
+        ('\u{465}', ['\u{464}', '\0', '\0']), ('\u{467}', ['\u{466}', '\0', '\0']), ('\u{469}',
+        ['\u{468}', '\0', '\0']), ('\u{46b}', ['\u{46a}', '\0', '\0']), ('\u{46d}', ['\u{46c}',
+        '\0', '\0']), ('\u{46f}', ['\u{46e}', '\0', '\0']), ('\u{471}', ['\u{470}', '\0', '\0']),
+        ('\u{473}', ['\u{472}', '\0', '\0']), ('\u{475}', ['\u{474}', '\0', '\0']), ('\u{477}',
+        ['\u{476}', '\0', '\0']), ('\u{479}', ['\u{478}', '\0', '\0']), ('\u{47b}', ['\u{47a}',
+        '\0', '\0']), ('\u{47d}', ['\u{47c}', '\0', '\0']), ('\u{47f}', ['\u{47e}', '\0', '\0']),
+        ('\u{481}', ['\u{480}', '\0', '\0']), ('\u{48b}', ['\u{48a}', '\0', '\0']), ('\u{48d}',
+        ['\u{48c}', '\0', '\0']), ('\u{48f}', ['\u{48e}', '\0', '\0']), ('\u{491}', ['\u{490}',
+        '\0', '\0']), ('\u{493}', ['\u{492}', '\0', '\0']), ('\u{495}', ['\u{494}', '\0', '\0']),
+        ('\u{497}', ['\u{496}', '\0', '\0']), ('\u{499}', ['\u{498}', '\0', '\0']), ('\u{49b}',
+        ['\u{49a}', '\0', '\0']), ('\u{49d}', ['\u{49c}', '\0', '\0']), ('\u{49f}', ['\u{49e}',
+        '\0', '\0']), ('\u{4a1}', ['\u{4a0}', '\0', '\0']), ('\u{4a3}', ['\u{4a2}', '\0', '\0']),
+        ('\u{4a5}', ['\u{4a4}', '\0', '\0']), ('\u{4a7}', ['\u{4a6}', '\0', '\0']), ('\u{4a9}',
+        ['\u{4a8}', '\0', '\0']), ('\u{4ab}', ['\u{4aa}', '\0', '\0']), ('\u{4ad}', ['\u{4ac}',
+        '\0', '\0']), ('\u{4af}', ['\u{4ae}', '\0', '\0']), ('\u{4b1}', ['\u{4b0}', '\0', '\0']),
+        ('\u{4b3}', ['\u{4b2}', '\0', '\0']), ('\u{4b5}', ['\u{4b4}', '\0', '\0']), ('\u{4b7}',
+        ['\u{4b6}', '\0', '\0']), ('\u{4b9}', ['\u{4b8}', '\0', '\0']), ('\u{4bb}', ['\u{4ba}',
+        '\0', '\0']), ('\u{4bd}', ['\u{4bc}', '\0', '\0']), ('\u{4bf}', ['\u{4be}', '\0', '\0']),
+        ('\u{4c2}', ['\u{4c1}', '\0', '\0']), ('\u{4c4}', ['\u{4c3}', '\0', '\0']), ('\u{4c6}',
+        ['\u{4c5}', '\0', '\0']), ('\u{4c8}', ['\u{4c7}', '\0', '\0']), ('\u{4ca}', ['\u{4c9}',
+        '\0', '\0']), ('\u{4cc}', ['\u{4cb}', '\0', '\0']), ('\u{4ce}', ['\u{4cd}', '\0', '\0']),
+        ('\u{4cf}', ['\u{4c0}', '\0', '\0']), ('\u{4d1}', ['\u{4d0}', '\0', '\0']), ('\u{4d3}',
+        ['\u{4d2}', '\0', '\0']), ('\u{4d5}', ['\u{4d4}', '\0', '\0']), ('\u{4d7}', ['\u{4d6}',
+        '\0', '\0']), ('\u{4d9}', ['\u{4d8}', '\0', '\0']), ('\u{4db}', ['\u{4da}', '\0', '\0']),
+        ('\u{4dd}', ['\u{4dc}', '\0', '\0']), ('\u{4df}', ['\u{4de}', '\0', '\0']), ('\u{4e1}',
+        ['\u{4e0}', '\0', '\0']), ('\u{4e3}', ['\u{4e2}', '\0', '\0']), ('\u{4e5}', ['\u{4e4}',
+        '\0', '\0']), ('\u{4e7}', ['\u{4e6}', '\0', '\0']), ('\u{4e9}', ['\u{4e8}', '\0', '\0']),
+        ('\u{4eb}', ['\u{4ea}', '\0', '\0']), ('\u{4ed}', ['\u{4ec}', '\0', '\0']), ('\u{4ef}',
+        ['\u{4ee}', '\0', '\0']), ('\u{4f1}', ['\u{4f0}', '\0', '\0']), ('\u{4f3}', ['\u{4f2}',
+        '\0', '\0']), ('\u{4f5}', ['\u{4f4}', '\0', '\0']), ('\u{4f7}', ['\u{4f6}', '\0', '\0']),
+        ('\u{4f9}', ['\u{4f8}', '\0', '\0']), ('\u{4fb}', ['\u{4fa}', '\0', '\0']), ('\u{4fd}',
+        ['\u{4fc}', '\0', '\0']), ('\u{4ff}', ['\u{4fe}', '\0', '\0']), ('\u{501}', ['\u{500}',
+        '\0', '\0']), ('\u{503}', ['\u{502}', '\0', '\0']), ('\u{505}', ['\u{504}', '\0', '\0']),
+        ('\u{507}', ['\u{506}', '\0', '\0']), ('\u{509}', ['\u{508}', '\0', '\0']), ('\u{50b}',
+        ['\u{50a}', '\0', '\0']), ('\u{50d}', ['\u{50c}', '\0', '\0']), ('\u{50f}', ['\u{50e}',
+        '\0', '\0']), ('\u{511}', ['\u{510}', '\0', '\0']), ('\u{513}', ['\u{512}', '\0', '\0']),
+        ('\u{515}', ['\u{514}', '\0', '\0']), ('\u{517}', ['\u{516}', '\0', '\0']), ('\u{519}',
+        ['\u{518}', '\0', '\0']), ('\u{51b}', ['\u{51a}', '\0', '\0']), ('\u{51d}', ['\u{51c}',
+        '\0', '\0']), ('\u{51f}', ['\u{51e}', '\0', '\0']), ('\u{521}', ['\u{520}', '\0', '\0']),
+        ('\u{523}', ['\u{522}', '\0', '\0']), ('\u{525}', ['\u{524}', '\0', '\0']), ('\u{527}',
+        ['\u{526}', '\0', '\0']), ('\u{529}', ['\u{528}', '\0', '\0']), ('\u{52b}', ['\u{52a}',
+        '\0', '\0']), ('\u{52d}', ['\u{52c}', '\0', '\0']), ('\u{52f}', ['\u{52e}', '\0', '\0']),
+        ('\u{561}', ['\u{531}', '\0', '\0']), ('\u{562}', ['\u{532}', '\0', '\0']), ('\u{563}',
+        ['\u{533}', '\0', '\0']), ('\u{564}', ['\u{534}', '\0', '\0']), ('\u{565}', ['\u{535}',
+        '\0', '\0']), ('\u{566}', ['\u{536}', '\0', '\0']), ('\u{567}', ['\u{537}', '\0', '\0']),
+        ('\u{568}', ['\u{538}', '\0', '\0']), ('\u{569}', ['\u{539}', '\0', '\0']), ('\u{56a}',
+        ['\u{53a}', '\0', '\0']), ('\u{56b}', ['\u{53b}', '\0', '\0']), ('\u{56c}', ['\u{53c}',
+        '\0', '\0']), ('\u{56d}', ['\u{53d}', '\0', '\0']), ('\u{56e}', ['\u{53e}', '\0', '\0']),
+        ('\u{56f}', ['\u{53f}', '\0', '\0']), ('\u{570}', ['\u{540}', '\0', '\0']), ('\u{571}',
+        ['\u{541}', '\0', '\0']), ('\u{572}', ['\u{542}', '\0', '\0']), ('\u{573}', ['\u{543}',
+        '\0', '\0']), ('\u{574}', ['\u{544}', '\0', '\0']), ('\u{575}', ['\u{545}', '\0', '\0']),
+        ('\u{576}', ['\u{546}', '\0', '\0']), ('\u{577}', ['\u{547}', '\0', '\0']), ('\u{578}',
+        ['\u{548}', '\0', '\0']), ('\u{579}', ['\u{549}', '\0', '\0']), ('\u{57a}', ['\u{54a}',
+        '\0', '\0']), ('\u{57b}', ['\u{54b}', '\0', '\0']), ('\u{57c}', ['\u{54c}', '\0', '\0']),
+        ('\u{57d}', ['\u{54d}', '\0', '\0']), ('\u{57e}', ['\u{54e}', '\0', '\0']), ('\u{57f}',
+        ['\u{54f}', '\0', '\0']), ('\u{580}', ['\u{550}', '\0', '\0']), ('\u{581}', ['\u{551}',
+        '\0', '\0']), ('\u{582}', ['\u{552}', '\0', '\0']), ('\u{583}', ['\u{553}', '\0', '\0']),
+        ('\u{584}', ['\u{554}', '\0', '\0']), ('\u{585}', ['\u{555}', '\0', '\0']), ('\u{586}',
+        ['\u{556}', '\0', '\0']), ('\u{587}', ['\u{535}', '\u{552}', '\0']), ('\u{10d0}',
+        ['\u{1c90}', '\0', '\0']), ('\u{10d1}', ['\u{1c91}', '\0', '\0']), ('\u{10d2}', ['\u{1c92}',
+        '\0', '\0']), ('\u{10d3}', ['\u{1c93}', '\0', '\0']), ('\u{10d4}', ['\u{1c94}', '\0',
+        '\0']), ('\u{10d5}', ['\u{1c95}', '\0', '\0']), ('\u{10d6}', ['\u{1c96}', '\0', '\0']),
+        ('\u{10d7}', ['\u{1c97}', '\0', '\0']), ('\u{10d8}', ['\u{1c98}', '\0', '\0']), ('\u{10d9}',
+        ['\u{1c99}', '\0', '\0']), ('\u{10da}', ['\u{1c9a}', '\0', '\0']), ('\u{10db}', ['\u{1c9b}',
+        '\0', '\0']), ('\u{10dc}', ['\u{1c9c}', '\0', '\0']), ('\u{10dd}', ['\u{1c9d}', '\0',
+        '\0']), ('\u{10de}', ['\u{1c9e}', '\0', '\0']), ('\u{10df}', ['\u{1c9f}', '\0', '\0']),
+        ('\u{10e0}', ['\u{1ca0}', '\0', '\0']), ('\u{10e1}', ['\u{1ca1}', '\0', '\0']), ('\u{10e2}',
+        ['\u{1ca2}', '\0', '\0']), ('\u{10e3}', ['\u{1ca3}', '\0', '\0']), ('\u{10e4}', ['\u{1ca4}',
+        '\0', '\0']), ('\u{10e5}', ['\u{1ca5}', '\0', '\0']), ('\u{10e6}', ['\u{1ca6}', '\0',
+        '\0']), ('\u{10e7}', ['\u{1ca7}', '\0', '\0']), ('\u{10e8}', ['\u{1ca8}', '\0', '\0']),
+        ('\u{10e9}', ['\u{1ca9}', '\0', '\0']), ('\u{10ea}', ['\u{1caa}', '\0', '\0']), ('\u{10eb}',
+        ['\u{1cab}', '\0', '\0']), ('\u{10ec}', ['\u{1cac}', '\0', '\0']), ('\u{10ed}', ['\u{1cad}',
+        '\0', '\0']), ('\u{10ee}', ['\u{1cae}', '\0', '\0']), ('\u{10ef}', ['\u{1caf}', '\0',
+        '\0']), ('\u{10f0}', ['\u{1cb0}', '\0', '\0']), ('\u{10f1}', ['\u{1cb1}', '\0', '\0']),
+        ('\u{10f2}', ['\u{1cb2}', '\0', '\0']), ('\u{10f3}', ['\u{1cb3}', '\0', '\0']), ('\u{10f4}',
+        ['\u{1cb4}', '\0', '\0']), ('\u{10f5}', ['\u{1cb5}', '\0', '\0']), ('\u{10f6}', ['\u{1cb6}',
+        '\0', '\0']), ('\u{10f7}', ['\u{1cb7}', '\0', '\0']), ('\u{10f8}', ['\u{1cb8}', '\0',
+        '\0']), ('\u{10f9}', ['\u{1cb9}', '\0', '\0']), ('\u{10fa}', ['\u{1cba}', '\0', '\0']),
+        ('\u{10fd}', ['\u{1cbd}', '\0', '\0']), ('\u{10fe}', ['\u{1cbe}', '\0', '\0']), ('\u{10ff}',
+        ['\u{1cbf}', '\0', '\0']), ('\u{13f8}', ['\u{13f0}', '\0', '\0']), ('\u{13f9}', ['\u{13f1}',
+        '\0', '\0']), ('\u{13fa}', ['\u{13f2}', '\0', '\0']), ('\u{13fb}', ['\u{13f3}', '\0',
+        '\0']), ('\u{13fc}', ['\u{13f4}', '\0', '\0']), ('\u{13fd}', ['\u{13f5}', '\0', '\0']),
+        ('\u{1c80}', ['\u{412}', '\0', '\0']), ('\u{1c81}', ['\u{414}', '\0', '\0']), ('\u{1c82}',
+        ['\u{41e}', '\0', '\0']), ('\u{1c83}', ['\u{421}', '\0', '\0']), ('\u{1c84}', ['\u{422}',
+        '\0', '\0']), ('\u{1c85}', ['\u{422}', '\0', '\0']), ('\u{1c86}', ['\u{42a}', '\0', '\0']),
+        ('\u{1c87}', ['\u{462}', '\0', '\0']), ('\u{1c88}', ['\u{a64a}', '\0', '\0']), ('\u{1d79}',
+        ['\u{a77d}', '\0', '\0']), ('\u{1d7d}', ['\u{2c63}', '\0', '\0']), ('\u{1d8e}', ['\u{a7c6}',
+        '\0', '\0']), ('\u{1e01}', ['\u{1e00}', '\0', '\0']), ('\u{1e03}', ['\u{1e02}', '\0',
+        '\0']), ('\u{1e05}', ['\u{1e04}', '\0', '\0']), ('\u{1e07}', ['\u{1e06}', '\0', '\0']),
+        ('\u{1e09}', ['\u{1e08}', '\0', '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0', '\0']), ('\u{1e0d}',
+        ['\u{1e0c}', '\0', '\0']), ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']), ('\u{1e11}', ['\u{1e10}',
+        '\0', '\0']), ('\u{1e13}', ['\u{1e12}', '\0', '\0']), ('\u{1e15}', ['\u{1e14}', '\0',
+        '\0']), ('\u{1e17}', ['\u{1e16}', '\0', '\0']), ('\u{1e19}', ['\u{1e18}', '\0', '\0']),
+        ('\u{1e1b}', ['\u{1e1a}', '\0', '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0', '\0']), ('\u{1e1f}',
+        ['\u{1e1e}', '\0', '\0']), ('\u{1e21}', ['\u{1e20}', '\0', '\0']), ('\u{1e23}', ['\u{1e22}',
+        '\0', '\0']), ('\u{1e25}', ['\u{1e24}', '\0', '\0']), ('\u{1e27}', ['\u{1e26}', '\0',
+        '\0']), ('\u{1e29}', ['\u{1e28}', '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}', '\0', '\0']),
+        ('\u{1e2d}', ['\u{1e2c}', '\0', '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0', '\0']), ('\u{1e31}',
+        ['\u{1e30}', '\0', '\0']), ('\u{1e33}', ['\u{1e32}', '\0', '\0']), ('\u{1e35}', ['\u{1e34}',
+        '\0', '\0']), ('\u{1e37}', ['\u{1e36}', '\0', '\0']), ('\u{1e39}', ['\u{1e38}', '\0',
+        '\0']), ('\u{1e3b}', ['\u{1e3a}', '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}', '\0', '\0']),
+        ('\u{1e3f}', ['\u{1e3e}', '\0', '\0']), ('\u{1e41}', ['\u{1e40}', '\0', '\0']), ('\u{1e43}',
+        ['\u{1e42}', '\0', '\0']), ('\u{1e45}', ['\u{1e44}', '\0', '\0']), ('\u{1e47}', ['\u{1e46}',
+        '\0', '\0']), ('\u{1e49}', ['\u{1e48}', '\0', '\0']), ('\u{1e4b}', ['\u{1e4a}', '\0',
+        '\0']), ('\u{1e4d}', ['\u{1e4c}', '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}', '\0', '\0']),
+        ('\u{1e51}', ['\u{1e50}', '\0', '\0']), ('\u{1e53}', ['\u{1e52}', '\0', '\0']), ('\u{1e55}',
+        ['\u{1e54}', '\0', '\0']), ('\u{1e57}', ['\u{1e56}', '\0', '\0']), ('\u{1e59}', ['\u{1e58}',
+        '\0', '\0']), ('\u{1e5b}', ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}', ['\u{1e5c}', '\0',
+        '\0']), ('\u{1e5f}', ['\u{1e5e}', '\0', '\0']), ('\u{1e61}', ['\u{1e60}', '\0', '\0']),
+        ('\u{1e63}', ['\u{1e62}', '\0', '\0']), ('\u{1e65}', ['\u{1e64}', '\0', '\0']), ('\u{1e67}',
+        ['\u{1e66}', '\0', '\0']), ('\u{1e69}', ['\u{1e68}', '\0', '\0']), ('\u{1e6b}', ['\u{1e6a}',
+        '\0', '\0']), ('\u{1e6d}', ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}', ['\u{1e6e}', '\0',
+        '\0']), ('\u{1e71}', ['\u{1e70}', '\0', '\0']), ('\u{1e73}', ['\u{1e72}', '\0', '\0']),
+        ('\u{1e75}', ['\u{1e74}', '\0', '\0']), ('\u{1e77}', ['\u{1e76}', '\0', '\0']), ('\u{1e79}',
+        ['\u{1e78}', '\0', '\0']), ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']), ('\u{1e7d}', ['\u{1e7c}',
+        '\0', '\0']), ('\u{1e7f}', ['\u{1e7e}', '\0', '\0']), ('\u{1e81}', ['\u{1e80}', '\0',
+        '\0']), ('\u{1e83}', ['\u{1e82}', '\0', '\0']), ('\u{1e85}', ['\u{1e84}', '\0', '\0']),
+        ('\u{1e87}', ['\u{1e86}', '\0', '\0']), ('\u{1e89}', ['\u{1e88}', '\0', '\0']), ('\u{1e8b}',
+        ['\u{1e8a}', '\0', '\0']), ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']), ('\u{1e8f}', ['\u{1e8e}',
+        '\0', '\0']), ('\u{1e91}', ['\u{1e90}', '\0', '\0']), ('\u{1e93}', ['\u{1e92}', '\0',
+        '\0']), ('\u{1e95}', ['\u{1e94}', '\0', '\0']), ('\u{1e96}', ['\u{48}', '\u{331}', '\0']),
+        ('\u{1e97}', ['\u{54}', '\u{308}', '\0']), ('\u{1e98}', ['\u{57}', '\u{30a}', '\0']),
+        ('\u{1e99}', ['\u{59}', '\u{30a}', '\0']), ('\u{1e9a}', ['\u{41}', '\u{2be}', '\0']),
+        ('\u{1e9b}', ['\u{1e60}', '\0', '\0']), ('\u{1ea1}', ['\u{1ea0}', '\0', '\0']), ('\u{1ea3}',
+        ['\u{1ea2}', '\0', '\0']), ('\u{1ea5}', ['\u{1ea4}', '\0', '\0']), ('\u{1ea7}', ['\u{1ea6}',
+        '\0', '\0']), ('\u{1ea9}', ['\u{1ea8}', '\0', '\0']), ('\u{1eab}', ['\u{1eaa}', '\0',
+        '\0']), ('\u{1ead}', ['\u{1eac}', '\0', '\0']), ('\u{1eaf}', ['\u{1eae}', '\0', '\0']),
+        ('\u{1eb1}', ['\u{1eb0}', '\0', '\0']), ('\u{1eb3}', ['\u{1eb2}', '\0', '\0']), ('\u{1eb5}',
+        ['\u{1eb4}', '\0', '\0']), ('\u{1eb7}', ['\u{1eb6}', '\0', '\0']), ('\u{1eb9}', ['\u{1eb8}',
+        '\0', '\0']), ('\u{1ebb}', ['\u{1eba}', '\0', '\0']), ('\u{1ebd}', ['\u{1ebc}', '\0',
+        '\0']), ('\u{1ebf}', ['\u{1ebe}', '\0', '\0']), ('\u{1ec1}', ['\u{1ec0}', '\0', '\0']),
+        ('\u{1ec3}', ['\u{1ec2}', '\0', '\0']), ('\u{1ec5}', ['\u{1ec4}', '\0', '\0']), ('\u{1ec7}',
+        ['\u{1ec6}', '\0', '\0']), ('\u{1ec9}', ['\u{1ec8}', '\0', '\0']), ('\u{1ecb}', ['\u{1eca}',
+        '\0', '\0']), ('\u{1ecd}', ['\u{1ecc}', '\0', '\0']), ('\u{1ecf}', ['\u{1ece}', '\0',
+        '\0']), ('\u{1ed1}', ['\u{1ed0}', '\0', '\0']), ('\u{1ed3}', ['\u{1ed2}', '\0', '\0']),
+        ('\u{1ed5}', ['\u{1ed4}', '\0', '\0']), ('\u{1ed7}', ['\u{1ed6}', '\0', '\0']), ('\u{1ed9}',
+        ['\u{1ed8}', '\0', '\0']), ('\u{1edb}', ['\u{1eda}', '\0', '\0']), ('\u{1edd}', ['\u{1edc}',
+        '\0', '\0']), ('\u{1edf}', ['\u{1ede}', '\0', '\0']), ('\u{1ee1}', ['\u{1ee0}', '\0',
+        '\0']), ('\u{1ee3}', ['\u{1ee2}', '\0', '\0']), ('\u{1ee5}', ['\u{1ee4}', '\0', '\0']),
+        ('\u{1ee7}', ['\u{1ee6}', '\0', '\0']), ('\u{1ee9}', ['\u{1ee8}', '\0', '\0']), ('\u{1eeb}',
+        ['\u{1eea}', '\0', '\0']), ('\u{1eed}', ['\u{1eec}', '\0', '\0']), ('\u{1eef}', ['\u{1eee}',
+        '\0', '\0']), ('\u{1ef1}', ['\u{1ef0}', '\0', '\0']), ('\u{1ef3}', ['\u{1ef2}', '\0',
+        '\0']), ('\u{1ef5}', ['\u{1ef4}', '\0', '\0']), ('\u{1ef7}', ['\u{1ef6}', '\0', '\0']),
+        ('\u{1ef9}', ['\u{1ef8}', '\0', '\0']), ('\u{1efb}', ['\u{1efa}', '\0', '\0']), ('\u{1efd}',
+        ['\u{1efc}', '\0', '\0']), ('\u{1eff}', ['\u{1efe}', '\0', '\0']), ('\u{1f00}', ['\u{1f08}',
+        '\0', '\0']), ('\u{1f01}', ['\u{1f09}', '\0', '\0']), ('\u{1f02}', ['\u{1f0a}', '\0',
+        '\0']), ('\u{1f03}', ['\u{1f0b}', '\0', '\0']), ('\u{1f04}', ['\u{1f0c}', '\0', '\0']),
+        ('\u{1f05}', ['\u{1f0d}', '\0', '\0']), ('\u{1f06}', ['\u{1f0e}', '\0', '\0']), ('\u{1f07}',
+        ['\u{1f0f}', '\0', '\0']), ('\u{1f10}', ['\u{1f18}', '\0', '\0']), ('\u{1f11}', ['\u{1f19}',
+        '\0', '\0']), ('\u{1f12}', ['\u{1f1a}', '\0', '\0']), ('\u{1f13}', ['\u{1f1b}', '\0',
+        '\0']), ('\u{1f14}', ['\u{1f1c}', '\0', '\0']), ('\u{1f15}', ['\u{1f1d}', '\0', '\0']),
+        ('\u{1f20}', ['\u{1f28}', '\0', '\0']), ('\u{1f21}', ['\u{1f29}', '\0', '\0']), ('\u{1f22}',
+        ['\u{1f2a}', '\0', '\0']), ('\u{1f23}', ['\u{1f2b}', '\0', '\0']), ('\u{1f24}', ['\u{1f2c}',
+        '\0', '\0']), ('\u{1f25}', ['\u{1f2d}', '\0', '\0']), ('\u{1f26}', ['\u{1f2e}', '\0',
+        '\0']), ('\u{1f27}', ['\u{1f2f}', '\0', '\0']), ('\u{1f30}', ['\u{1f38}', '\0', '\0']),
+        ('\u{1f31}', ['\u{1f39}', '\0', '\0']), ('\u{1f32}', ['\u{1f3a}', '\0', '\0']), ('\u{1f33}',
+        ['\u{1f3b}', '\0', '\0']), ('\u{1f34}', ['\u{1f3c}', '\0', '\0']), ('\u{1f35}', ['\u{1f3d}',
+        '\0', '\0']), ('\u{1f36}', ['\u{1f3e}', '\0', '\0']), ('\u{1f37}', ['\u{1f3f}', '\0',
+        '\0']), ('\u{1f40}', ['\u{1f48}', '\0', '\0']), ('\u{1f41}', ['\u{1f49}', '\0', '\0']),
+        ('\u{1f42}', ['\u{1f4a}', '\0', '\0']), ('\u{1f43}', ['\u{1f4b}', '\0', '\0']), ('\u{1f44}',
+        ['\u{1f4c}', '\0', '\0']), ('\u{1f45}', ['\u{1f4d}', '\0', '\0']), ('\u{1f50}', ['\u{3a5}',
+        '\u{313}', '\0']), ('\u{1f51}', ['\u{1f59}', '\0', '\0']), ('\u{1f52}', ['\u{3a5}',
+        '\u{313}', '\u{300}']), ('\u{1f53}', ['\u{1f5b}', '\0', '\0']), ('\u{1f54}', ['\u{3a5}',
+        '\u{313}', '\u{301}']), ('\u{1f55}', ['\u{1f5d}', '\0', '\0']), ('\u{1f56}', ['\u{3a5}',
+        '\u{313}', '\u{342}']), ('\u{1f57}', ['\u{1f5f}', '\0', '\0']), ('\u{1f60}', ['\u{1f68}',
+        '\0', '\0']), ('\u{1f61}', ['\u{1f69}', '\0', '\0']), ('\u{1f62}', ['\u{1f6a}', '\0',
+        '\0']), ('\u{1f63}', ['\u{1f6b}', '\0', '\0']), ('\u{1f64}', ['\u{1f6c}', '\0', '\0']),
+        ('\u{1f65}', ['\u{1f6d}', '\0', '\0']), ('\u{1f66}', ['\u{1f6e}', '\0', '\0']), ('\u{1f67}',
+        ['\u{1f6f}', '\0', '\0']), ('\u{1f70}', ['\u{1fba}', '\0', '\0']), ('\u{1f71}', ['\u{1fbb}',
+        '\0', '\0']), ('\u{1f72}', ['\u{1fc8}', '\0', '\0']), ('\u{1f73}', ['\u{1fc9}', '\0',
+        '\0']), ('\u{1f74}', ['\u{1fca}', '\0', '\0']), ('\u{1f75}', ['\u{1fcb}', '\0', '\0']),
+        ('\u{1f76}', ['\u{1fda}', '\0', '\0']), ('\u{1f77}', ['\u{1fdb}', '\0', '\0']), ('\u{1f78}',
+        ['\u{1ff8}', '\0', '\0']), ('\u{1f79}', ['\u{1ff9}', '\0', '\0']), ('\u{1f7a}', ['\u{1fea}',
+        '\0', '\0']), ('\u{1f7b}', ['\u{1feb}', '\0', '\0']), ('\u{1f7c}', ['\u{1ffa}', '\0',
+        '\0']), ('\u{1f7d}', ['\u{1ffb}', '\0', '\0']), ('\u{1f80}', ['\u{1f08}', '\u{399}', '\0']),
+        ('\u{1f81}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f82}', ['\u{1f0a}', '\u{399}', '\0']),
+        ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f84}', ['\u{1f0c}', '\u{399}', '\0']),
+        ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f86}', ['\u{1f0e}', '\u{399}', '\0']),
+        ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f88}', ['\u{1f08}', '\u{399}', '\0']),
+        ('\u{1f89}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f8a}', ['\u{1f0a}', '\u{399}', '\0']),
+        ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f8c}', ['\u{1f0c}', '\u{399}', '\0']),
+        ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f8e}', ['\u{1f0e}', '\u{399}', '\0']),
+        ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f90}', ['\u{1f28}', '\u{399}', '\0']),
+        ('\u{1f91}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f92}', ['\u{1f2a}', '\u{399}', '\0']),
+        ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f94}', ['\u{1f2c}', '\u{399}', '\0']),
+        ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f96}', ['\u{1f2e}', '\u{399}', '\0']),
+        ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1f98}', ['\u{1f28}', '\u{399}', '\0']),
+        ('\u{1f99}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f9a}', ['\u{1f2a}', '\u{399}', '\0']),
+        ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f9c}', ['\u{1f2c}', '\u{399}', '\0']),
+        ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f9e}', ['\u{1f2e}', '\u{399}', '\0']),
+        ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1fa0}', ['\u{1f68}', '\u{399}', '\0']),
+        ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1fa2}', ['\u{1f6a}', '\u{399}', '\0']),
+        ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fa4}', ['\u{1f6c}', '\u{399}', '\0']),
+        ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fa6}', ['\u{1f6e}', '\u{399}', '\0']),
+        ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fa8}', ['\u{1f68}', '\u{399}', '\0']),
+        ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1faa}', ['\u{1f6a}', '\u{399}', '\0']),
+        ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fac}', ['\u{1f6c}', '\u{399}', '\0']),
+        ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fae}', ['\u{1f6e}', '\u{399}', '\0']),
+        ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fb0}', ['\u{1fb8}', '\0', '\0']),
         ('\u{1fb1}', ['\u{1fb9}', '\0', '\0']), ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\0']),
         ('\u{1fb3}', ['\u{391}', '\u{399}', '\0']), ('\u{1fb4}', ['\u{386}', '\u{399}', '\0']),
         ('\u{1fb6}', ['\u{391}', '\u{342}', '\0']), ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']),
@@ -2413,66 +2428,68 @@ pub mod conversions {
         ('\u{a781}', ['\u{a780}', '\0', '\0']), ('\u{a783}', ['\u{a782}', '\0', '\0']), ('\u{a785}',
         ['\u{a784}', '\0', '\0']), ('\u{a787}', ['\u{a786}', '\0', '\0']), ('\u{a78c}', ['\u{a78b}',
         '\0', '\0']), ('\u{a791}', ['\u{a790}', '\0', '\0']), ('\u{a793}', ['\u{a792}', '\0',
-        '\0']), ('\u{a797}', ['\u{a796}', '\0', '\0']), ('\u{a799}', ['\u{a798}', '\0', '\0']),
-        ('\u{a79b}', ['\u{a79a}', '\0', '\0']), ('\u{a79d}', ['\u{a79c}', '\0', '\0']), ('\u{a79f}',
-        ['\u{a79e}', '\0', '\0']), ('\u{a7a1}', ['\u{a7a0}', '\0', '\0']), ('\u{a7a3}', ['\u{a7a2}',
-        '\0', '\0']), ('\u{a7a5}', ['\u{a7a4}', '\0', '\0']), ('\u{a7a7}', ['\u{a7a6}', '\0',
-        '\0']), ('\u{a7a9}', ['\u{a7a8}', '\0', '\0']), ('\u{a7b5}', ['\u{a7b4}', '\0', '\0']),
-        ('\u{a7b7}', ['\u{a7b6}', '\0', '\0']), ('\u{a7b9}', ['\u{a7b8}', '\0', '\0']), ('\u{ab53}',
-        ['\u{a7b3}', '\0', '\0']), ('\u{ab70}', ['\u{13a0}', '\0', '\0']), ('\u{ab71}', ['\u{13a1}',
-        '\0', '\0']), ('\u{ab72}', ['\u{13a2}', '\0', '\0']), ('\u{ab73}', ['\u{13a3}', '\0',
-        '\0']), ('\u{ab74}', ['\u{13a4}', '\0', '\0']), ('\u{ab75}', ['\u{13a5}', '\0', '\0']),
-        ('\u{ab76}', ['\u{13a6}', '\0', '\0']), ('\u{ab77}', ['\u{13a7}', '\0', '\0']), ('\u{ab78}',
-        ['\u{13a8}', '\0', '\0']), ('\u{ab79}', ['\u{13a9}', '\0', '\0']), ('\u{ab7a}', ['\u{13aa}',
-        '\0', '\0']), ('\u{ab7b}', ['\u{13ab}', '\0', '\0']), ('\u{ab7c}', ['\u{13ac}', '\0',
-        '\0']), ('\u{ab7d}', ['\u{13ad}', '\0', '\0']), ('\u{ab7e}', ['\u{13ae}', '\0', '\0']),
-        ('\u{ab7f}', ['\u{13af}', '\0', '\0']), ('\u{ab80}', ['\u{13b0}', '\0', '\0']), ('\u{ab81}',
-        ['\u{13b1}', '\0', '\0']), ('\u{ab82}', ['\u{13b2}', '\0', '\0']), ('\u{ab83}', ['\u{13b3}',
-        '\0', '\0']), ('\u{ab84}', ['\u{13b4}', '\0', '\0']), ('\u{ab85}', ['\u{13b5}', '\0',
-        '\0']), ('\u{ab86}', ['\u{13b6}', '\0', '\0']), ('\u{ab87}', ['\u{13b7}', '\0', '\0']),
-        ('\u{ab88}', ['\u{13b8}', '\0', '\0']), ('\u{ab89}', ['\u{13b9}', '\0', '\0']), ('\u{ab8a}',
-        ['\u{13ba}', '\0', '\0']), ('\u{ab8b}', ['\u{13bb}', '\0', '\0']), ('\u{ab8c}', ['\u{13bc}',
-        '\0', '\0']), ('\u{ab8d}', ['\u{13bd}', '\0', '\0']), ('\u{ab8e}', ['\u{13be}', '\0',
-        '\0']), ('\u{ab8f}', ['\u{13bf}', '\0', '\0']), ('\u{ab90}', ['\u{13c0}', '\0', '\0']),
-        ('\u{ab91}', ['\u{13c1}', '\0', '\0']), ('\u{ab92}', ['\u{13c2}', '\0', '\0']), ('\u{ab93}',
-        ['\u{13c3}', '\0', '\0']), ('\u{ab94}', ['\u{13c4}', '\0', '\0']), ('\u{ab95}', ['\u{13c5}',
-        '\0', '\0']), ('\u{ab96}', ['\u{13c6}', '\0', '\0']), ('\u{ab97}', ['\u{13c7}', '\0',
-        '\0']), ('\u{ab98}', ['\u{13c8}', '\0', '\0']), ('\u{ab99}', ['\u{13c9}', '\0', '\0']),
-        ('\u{ab9a}', ['\u{13ca}', '\0', '\0']), ('\u{ab9b}', ['\u{13cb}', '\0', '\0']), ('\u{ab9c}',
-        ['\u{13cc}', '\0', '\0']), ('\u{ab9d}', ['\u{13cd}', '\0', '\0']), ('\u{ab9e}', ['\u{13ce}',
-        '\0', '\0']), ('\u{ab9f}', ['\u{13cf}', '\0', '\0']), ('\u{aba0}', ['\u{13d0}', '\0',
-        '\0']), ('\u{aba1}', ['\u{13d1}', '\0', '\0']), ('\u{aba2}', ['\u{13d2}', '\0', '\0']),
-        ('\u{aba3}', ['\u{13d3}', '\0', '\0']), ('\u{aba4}', ['\u{13d4}', '\0', '\0']), ('\u{aba5}',
-        ['\u{13d5}', '\0', '\0']), ('\u{aba6}', ['\u{13d6}', '\0', '\0']), ('\u{aba7}', ['\u{13d7}',
-        '\0', '\0']), ('\u{aba8}', ['\u{13d8}', '\0', '\0']), ('\u{aba9}', ['\u{13d9}', '\0',
-        '\0']), ('\u{abaa}', ['\u{13da}', '\0', '\0']), ('\u{abab}', ['\u{13db}', '\0', '\0']),
-        ('\u{abac}', ['\u{13dc}', '\0', '\0']), ('\u{abad}', ['\u{13dd}', '\0', '\0']), ('\u{abae}',
-        ['\u{13de}', '\0', '\0']), ('\u{abaf}', ['\u{13df}', '\0', '\0']), ('\u{abb0}', ['\u{13e0}',
-        '\0', '\0']), ('\u{abb1}', ['\u{13e1}', '\0', '\0']), ('\u{abb2}', ['\u{13e2}', '\0',
-        '\0']), ('\u{abb3}', ['\u{13e3}', '\0', '\0']), ('\u{abb4}', ['\u{13e4}', '\0', '\0']),
-        ('\u{abb5}', ['\u{13e5}', '\0', '\0']), ('\u{abb6}', ['\u{13e6}', '\0', '\0']), ('\u{abb7}',
-        ['\u{13e7}', '\0', '\0']), ('\u{abb8}', ['\u{13e8}', '\0', '\0']), ('\u{abb9}', ['\u{13e9}',
-        '\0', '\0']), ('\u{abba}', ['\u{13ea}', '\0', '\0']), ('\u{abbb}', ['\u{13eb}', '\0',
-        '\0']), ('\u{abbc}', ['\u{13ec}', '\0', '\0']), ('\u{abbd}', ['\u{13ed}', '\0', '\0']),
-        ('\u{abbe}', ['\u{13ee}', '\0', '\0']), ('\u{abbf}', ['\u{13ef}', '\0', '\0']), ('\u{fb00}',
-        ['\u{46}', '\u{46}', '\0']), ('\u{fb01}', ['\u{46}', '\u{49}', '\0']), ('\u{fb02}',
-        ['\u{46}', '\u{4c}', '\0']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']), ('\u{fb04}',
-        ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\0']), ('\u{fb06}',
-        ['\u{53}', '\u{54}', '\0']), ('\u{fb13}', ['\u{544}', '\u{546}', '\0']), ('\u{fb14}',
-        ['\u{544}', '\u{535}', '\0']), ('\u{fb15}', ['\u{544}', '\u{53b}', '\0']), ('\u{fb16}',
-        ['\u{54e}', '\u{546}', '\0']), ('\u{fb17}', ['\u{544}', '\u{53d}', '\0']), ('\u{ff41}',
-        ['\u{ff21}', '\0', '\0']), ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}', ['\u{ff23}',
-        '\0', '\0']), ('\u{ff44}', ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}', '\0',
-        '\0']), ('\u{ff46}', ['\u{ff26}', '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0', '\0']),
-        ('\u{ff48}', ['\u{ff28}', '\0', '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']), ('\u{ff4a}',
-        ['\u{ff2a}', '\0', '\0']), ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}', ['\u{ff2c}',
-        '\0', '\0']), ('\u{ff4d}', ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}', '\0',
-        '\0']), ('\u{ff4f}', ['\u{ff2f}', '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0', '\0']),
-        ('\u{ff51}', ['\u{ff31}', '\0', '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']), ('\u{ff53}',
-        ['\u{ff33}', '\0', '\0']), ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}', ['\u{ff35}',
-        '\0', '\0']), ('\u{ff56}', ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}', '\0',
-        '\0']), ('\u{ff58}', ['\u{ff38}', '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0', '\0']),
-        ('\u{ff5a}', ['\u{ff3a}', '\0', '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']),
+        '\0']), ('\u{a794}', ['\u{a7c4}', '\0', '\0']), ('\u{a797}', ['\u{a796}', '\0', '\0']),
+        ('\u{a799}', ['\u{a798}', '\0', '\0']), ('\u{a79b}', ['\u{a79a}', '\0', '\0']), ('\u{a79d}',
+        ['\u{a79c}', '\0', '\0']), ('\u{a79f}', ['\u{a79e}', '\0', '\0']), ('\u{a7a1}', ['\u{a7a0}',
+        '\0', '\0']), ('\u{a7a3}', ['\u{a7a2}', '\0', '\0']), ('\u{a7a5}', ['\u{a7a4}', '\0',
+        '\0']), ('\u{a7a7}', ['\u{a7a6}', '\0', '\0']), ('\u{a7a9}', ['\u{a7a8}', '\0', '\0']),
+        ('\u{a7b5}', ['\u{a7b4}', '\0', '\0']), ('\u{a7b7}', ['\u{a7b6}', '\0', '\0']), ('\u{a7b9}',
+        ['\u{a7b8}', '\0', '\0']), ('\u{a7bb}', ['\u{a7ba}', '\0', '\0']), ('\u{a7bd}', ['\u{a7bc}',
+        '\0', '\0']), ('\u{a7bf}', ['\u{a7be}', '\0', '\0']), ('\u{a7c3}', ['\u{a7c2}', '\0',
+        '\0']), ('\u{ab53}', ['\u{a7b3}', '\0', '\0']), ('\u{ab70}', ['\u{13a0}', '\0', '\0']),
+        ('\u{ab71}', ['\u{13a1}', '\0', '\0']), ('\u{ab72}', ['\u{13a2}', '\0', '\0']), ('\u{ab73}',
+        ['\u{13a3}', '\0', '\0']), ('\u{ab74}', ['\u{13a4}', '\0', '\0']), ('\u{ab75}', ['\u{13a5}',
+        '\0', '\0']), ('\u{ab76}', ['\u{13a6}', '\0', '\0']), ('\u{ab77}', ['\u{13a7}', '\0',
+        '\0']), ('\u{ab78}', ['\u{13a8}', '\0', '\0']), ('\u{ab79}', ['\u{13a9}', '\0', '\0']),
+        ('\u{ab7a}', ['\u{13aa}', '\0', '\0']), ('\u{ab7b}', ['\u{13ab}', '\0', '\0']), ('\u{ab7c}',
+        ['\u{13ac}', '\0', '\0']), ('\u{ab7d}', ['\u{13ad}', '\0', '\0']), ('\u{ab7e}', ['\u{13ae}',
+        '\0', '\0']), ('\u{ab7f}', ['\u{13af}', '\0', '\0']), ('\u{ab80}', ['\u{13b0}', '\0',
+        '\0']), ('\u{ab81}', ['\u{13b1}', '\0', '\0']), ('\u{ab82}', ['\u{13b2}', '\0', '\0']),
+        ('\u{ab83}', ['\u{13b3}', '\0', '\0']), ('\u{ab84}', ['\u{13b4}', '\0', '\0']), ('\u{ab85}',
+        ['\u{13b5}', '\0', '\0']), ('\u{ab86}', ['\u{13b6}', '\0', '\0']), ('\u{ab87}', ['\u{13b7}',
+        '\0', '\0']), ('\u{ab88}', ['\u{13b8}', '\0', '\0']), ('\u{ab89}', ['\u{13b9}', '\0',
+        '\0']), ('\u{ab8a}', ['\u{13ba}', '\0', '\0']), ('\u{ab8b}', ['\u{13bb}', '\0', '\0']),
+        ('\u{ab8c}', ['\u{13bc}', '\0', '\0']), ('\u{ab8d}', ['\u{13bd}', '\0', '\0']), ('\u{ab8e}',
+        ['\u{13be}', '\0', '\0']), ('\u{ab8f}', ['\u{13bf}', '\0', '\0']), ('\u{ab90}', ['\u{13c0}',
+        '\0', '\0']), ('\u{ab91}', ['\u{13c1}', '\0', '\0']), ('\u{ab92}', ['\u{13c2}', '\0',
+        '\0']), ('\u{ab93}', ['\u{13c3}', '\0', '\0']), ('\u{ab94}', ['\u{13c4}', '\0', '\0']),
+        ('\u{ab95}', ['\u{13c5}', '\0', '\0']), ('\u{ab96}', ['\u{13c6}', '\0', '\0']), ('\u{ab97}',
+        ['\u{13c7}', '\0', '\0']), ('\u{ab98}', ['\u{13c8}', '\0', '\0']), ('\u{ab99}', ['\u{13c9}',
+        '\0', '\0']), ('\u{ab9a}', ['\u{13ca}', '\0', '\0']), ('\u{ab9b}', ['\u{13cb}', '\0',
+        '\0']), ('\u{ab9c}', ['\u{13cc}', '\0', '\0']), ('\u{ab9d}', ['\u{13cd}', '\0', '\0']),
+        ('\u{ab9e}', ['\u{13ce}', '\0', '\0']), ('\u{ab9f}', ['\u{13cf}', '\0', '\0']), ('\u{aba0}',
+        ['\u{13d0}', '\0', '\0']), ('\u{aba1}', ['\u{13d1}', '\0', '\0']), ('\u{aba2}', ['\u{13d2}',
+        '\0', '\0']), ('\u{aba3}', ['\u{13d3}', '\0', '\0']), ('\u{aba4}', ['\u{13d4}', '\0',
+        '\0']), ('\u{aba5}', ['\u{13d5}', '\0', '\0']), ('\u{aba6}', ['\u{13d6}', '\0', '\0']),
+        ('\u{aba7}', ['\u{13d7}', '\0', '\0']), ('\u{aba8}', ['\u{13d8}', '\0', '\0']), ('\u{aba9}',
+        ['\u{13d9}', '\0', '\0']), ('\u{abaa}', ['\u{13da}', '\0', '\0']), ('\u{abab}', ['\u{13db}',
+        '\0', '\0']), ('\u{abac}', ['\u{13dc}', '\0', '\0']), ('\u{abad}', ['\u{13dd}', '\0',
+        '\0']), ('\u{abae}', ['\u{13de}', '\0', '\0']), ('\u{abaf}', ['\u{13df}', '\0', '\0']),
+        ('\u{abb0}', ['\u{13e0}', '\0', '\0']), ('\u{abb1}', ['\u{13e1}', '\0', '\0']), ('\u{abb2}',
+        ['\u{13e2}', '\0', '\0']), ('\u{abb3}', ['\u{13e3}', '\0', '\0']), ('\u{abb4}', ['\u{13e4}',
+        '\0', '\0']), ('\u{abb5}', ['\u{13e5}', '\0', '\0']), ('\u{abb6}', ['\u{13e6}', '\0',
+        '\0']), ('\u{abb7}', ['\u{13e7}', '\0', '\0']), ('\u{abb8}', ['\u{13e8}', '\0', '\0']),
+        ('\u{abb9}', ['\u{13e9}', '\0', '\0']), ('\u{abba}', ['\u{13ea}', '\0', '\0']), ('\u{abbb}',
+        ['\u{13eb}', '\0', '\0']), ('\u{abbc}', ['\u{13ec}', '\0', '\0']), ('\u{abbd}', ['\u{13ed}',
+        '\0', '\0']), ('\u{abbe}', ['\u{13ee}', '\0', '\0']), ('\u{abbf}', ['\u{13ef}', '\0',
+        '\0']), ('\u{fb00}', ['\u{46}', '\u{46}', '\0']), ('\u{fb01}', ['\u{46}', '\u{49}', '\0']),
+        ('\u{fb02}', ['\u{46}', '\u{4c}', '\0']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']),
+        ('\u{fb04}', ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\0']),
+        ('\u{fb06}', ['\u{53}', '\u{54}', '\0']), ('\u{fb13}', ['\u{544}', '\u{546}', '\0']),
+        ('\u{fb14}', ['\u{544}', '\u{535}', '\0']), ('\u{fb15}', ['\u{544}', '\u{53b}', '\0']),
+        ('\u{fb16}', ['\u{54e}', '\u{546}', '\0']), ('\u{fb17}', ['\u{544}', '\u{53d}', '\0']),
+        ('\u{ff41}', ['\u{ff21}', '\0', '\0']), ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}',
+        ['\u{ff23}', '\0', '\0']), ('\u{ff44}', ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}',
+        '\0', '\0']), ('\u{ff46}', ['\u{ff26}', '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0',
+        '\0']), ('\u{ff48}', ['\u{ff28}', '\0', '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']),
+        ('\u{ff4a}', ['\u{ff2a}', '\0', '\0']), ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}',
+        ['\u{ff2c}', '\0', '\0']), ('\u{ff4d}', ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}',
+        '\0', '\0']), ('\u{ff4f}', ['\u{ff2f}', '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0',
+        '\0']), ('\u{ff51}', ['\u{ff31}', '\0', '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']),
+        ('\u{ff53}', ['\u{ff33}', '\0', '\0']), ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}',
+        ['\u{ff35}', '\0', '\0']), ('\u{ff56}', ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}',
+        '\0', '\0']), ('\u{ff58}', ['\u{ff38}', '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0',
+        '\0']), ('\u{ff5a}', ['\u{ff3a}', '\0', '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']),
         ('\u{10429}', ['\u{10401}', '\0', '\0']), ('\u{1042a}', ['\u{10402}', '\0', '\0']),
         ('\u{1042b}', ['\u{10403}', '\0', '\0']), ('\u{1042c}', ['\u{10404}', '\0', '\0']),
         ('\u{1042d}', ['\u{10405}', '\0', '\0']), ('\u{1042e}', ['\u{10406}', '\0', '\0']),
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index ae356c3ff44..6de5d9e033b 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -1,147 +1,350 @@
 #!/usr/bin/env python
 
-# This script uses the following Unicode tables:
-# - DerivedCoreProperties.txt
-# - DerivedNormalizationProps.txt
-# - EastAsianWidth.txt
-# - auxiliary/GraphemeBreakProperty.txt
-# - PropList.txt
-# - ReadMe.txt
-# - Scripts.txt
-# - UnicodeData.txt
-#
-# Since this should not require frequent updates, we just store this
-# out-of-line and check the tables.rs file into git.
+"""
+Regenerate Unicode tables (tables.rs).
+"""
 
-import fileinput, re, os, sys, operator, math, datetime
+# This script uses the Unicode tables as defined
+# in the UnicodeFiles class.
 
-# The directory in which this file resides.
-fdir = os.path.dirname(os.path.realpath(__file__)) + "/"
+# Since this should not require frequent updates, we just store this
+# out-of-line and check the tables.rs file into git.
 
-preamble = '''
+# Note that the "curl" program is required for operation.
+# This script is compatible with Python 2.7 and 3.x.
+
+import argparse
+import datetime
+import fileinput
+import itertools
+import os
+import re
+import textwrap
+import subprocess
+
+from collections import defaultdict, namedtuple
+
+try:
+    # Python 3
+    from itertools import zip_longest
+    from io import StringIO
+except ImportError:
+    # Python 2 compatibility
+    zip_longest = itertools.izip_longest
+    from StringIO import StringIO
+
+try:
+    # Completely optional type hinting
+    # (Python 2 compatible using comments,
+    # see: https://mypy.readthedocs.io/en/latest/python2.html)
+    # This is very helpful in typing-aware IDE like PyCharm.
+    from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Set, Tuple
+except ImportError:
+    pass
+
+
+# We don't use enum.Enum because of Python 2.7 compatibility.
+class UnicodeFiles(object):
+    # ReadMe does not contain any Unicode data, we
+    # only use it to extract versions.
+    README = "ReadMe.txt"
+
+    DERIVED_CORE_PROPERTIES = "DerivedCoreProperties.txt"
+    DERIVED_NORMALIZATION_PROPS = "DerivedNormalizationProps.txt"
+    PROPS = "PropList.txt"
+    SCRIPTS = "Scripts.txt"
+    SPECIAL_CASING = "SpecialCasing.txt"
+    UNICODE_DATA = "UnicodeData.txt"
+
+
+# The order doesn't really matter (Python < 3.6 won't preserve it),
+# we only want to aggregate all the file names.
+ALL_UNICODE_FILES = tuple(
+    value for name, value in UnicodeFiles.__dict__.items()
+    if not name.startswith("_")
+)
+
+assert len(ALL_UNICODE_FILES) == 7, "Unexpected number of unicode files"
+
+# The directory this file is located in.
+THIS_DIR = os.path.dirname(os.path.realpath(__file__))
+
+# Where to download the Unicode data.  The downloaded files
+# will be placed in sub-directories named after Unicode version.
+FETCH_DIR = os.path.join(THIS_DIR, "downloaded")
+
+FETCH_URL_LATEST = "ftp://ftp.unicode.org/Public/UNIDATA/{filename}"
+FETCH_URL_VERSION = "ftp://ftp.unicode.org/Public/{version}/ucd/{filename}"
+
+PREAMBLE = """\
 // NOTE: The following code was generated by "./unicode.py", do not edit directly
 
-#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
+#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)]
 
-use unicode::version::UnicodeVersion;
-use unicode::bool_trie::{{BoolTrie, SmallBoolTrie}};
-'''.format(year = datetime.datetime.now().year)
+use crate::unicode::version::UnicodeVersion;
+use crate::unicode::bool_trie::{{BoolTrie, SmallBoolTrie}};
+""".format(year=datetime.datetime.now().year)
 
 # Mapping taken from Table 12 from:
 # http://www.unicode.org/reports/tr44/#General_Category_Values
-expanded_categories = {
-    'Lu': ['LC', 'L'], 'Ll': ['LC', 'L'], 'Lt': ['LC', 'L'],
-    'Lm': ['L'], 'Lo': ['L'],
-    'Mn': ['M'], 'Mc': ['M'], 'Me': ['M'],
-    'Nd': ['N'], 'Nl': ['N'], 'No': ['N'],
-    'Pc': ['P'], 'Pd': ['P'], 'Ps': ['P'], 'Pe': ['P'],
-    'Pi': ['P'], 'Pf': ['P'], 'Po': ['P'],
-    'Sm': ['S'], 'Sc': ['S'], 'Sk': ['S'], 'So': ['S'],
-    'Zs': ['Z'], 'Zl': ['Z'], 'Zp': ['Z'],
-    'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'],
+EXPANDED_CATEGORIES = {
+    "Lu": ["LC", "L"], "Ll": ["LC", "L"], "Lt": ["LC", "L"],
+    "Lm": ["L"], "Lo": ["L"],
+    "Mn": ["M"], "Mc": ["M"], "Me": ["M"],
+    "Nd": ["N"], "Nl": ["N"], "No": ["N"],
+    "Pc": ["P"], "Pd": ["P"], "Ps": ["P"], "Pe": ["P"],
+    "Pi": ["P"], "Pf": ["P"], "Po": ["P"],
+    "Sm": ["S"], "Sc": ["S"], "Sk": ["S"], "So": ["S"],
+    "Zs": ["Z"], "Zl": ["Z"], "Zp": ["Z"],
+    "Cc": ["C"], "Cf": ["C"], "Cs": ["C"], "Co": ["C"], "Cn": ["C"],
 }
 
-# these are the surrogate codepoints, which are not valid rust characters
-surrogate_codepoints = (0xd800, 0xdfff)
+# This is the (inclusive) range of surrogate codepoints.
+# These are not valid Rust characters.
+SURROGATE_CODEPOINTS_RANGE = (0xd800, 0xdfff)
+
+UnicodeData = namedtuple(
+    "UnicodeData", (
+        # Conversions:
+        "to_upper", "to_lower", "to_title",
+
+        # Decompositions: canonical decompositions, compatibility decomp
+        "canon_decomp", "compat_decomp",
+
+        # Grouped: general categories and combining characters
+        "general_categories", "combines",
+    )
+)
+
+UnicodeVersion = namedtuple(
+    "UnicodeVersion", ("major", "minor", "micro", "as_str")
+)
+
+
+def fetch_files(version=None):
+    # type: (str) -> UnicodeVersion
+    """
+    Fetch all the Unicode files from unicode.org.
+
+    This will use cached files (stored in `FETCH_DIR`) if they exist,
+    creating them if they don't.  In any case, the Unicode version
+    is always returned.
+
+    :param version: The desired Unicode version, as string.
+        (If None, defaults to latest final release available,
+         querying the unicode.org service).
+    """
+    have_version = check_stored_version(version)
+    if have_version:
+        return have_version
+
+    if version:
+        # Check if the desired version exists on the server.
+        get_fetch_url = lambda name: FETCH_URL_VERSION.format(version=version, filename=name)
+    else:
+        # Extract the latest version.
+        get_fetch_url = lambda name: FETCH_URL_LATEST.format(filename=name)
+
+    readme_url = get_fetch_url(UnicodeFiles.README)
+
+    print("Fetching: {}".format(readme_url))
+    readme_content = subprocess.check_output(("curl", readme_url))
+
+    unicode_version = parse_readme_unicode_version(
+        readme_content.decode("utf8")
+    )
+
+    download_dir = get_unicode_dir(unicode_version)
+    if not os.path.exists(download_dir):
+        # For 2.7 compat, we don't use `exist_ok=True`.
+        os.makedirs(download_dir)
+
+    for filename in ALL_UNICODE_FILES:
+        file_path = get_unicode_file_path(unicode_version, filename)
+
+        if os.path.exists(file_path):
+            # Assume file on the server didn't change if it's been saved before.
+            continue
+
+        if filename == UnicodeFiles.README:
+            with open(file_path, "wb") as fd:
+                fd.write(readme_content)
+        else:
+            url = get_fetch_url(filename)
+            print("Fetching: {}".format(url))
+            subprocess.check_call(("curl", "-o", file_path, url))
+
+    return unicode_version
+
+
+def check_stored_version(version):
+    # type: (Optional[str]) -> Optional[UnicodeVersion]
+    """
+    Given desired Unicode version, return the version
+    if stored files are all present, and `None` otherwise.
+    """
+    if not version:
+        # If no desired version specified, we should check what's the latest
+        # version, skipping stored version checks.
+        return None
+
+    fetch_dir = os.path.join(FETCH_DIR, version)
 
-def fetch(f):
-    path = fdir + os.path.basename(f)
-    if not os.path.exists(path):
-        os.system("curl -o {0}{1} ftp://ftp.unicode.org/Public/UNIDATA/{1}".format(fdir, f))
+    for filename in ALL_UNICODE_FILES:
+        file_path = os.path.join(fetch_dir, filename)
+
+        if not os.path.exists(file_path):
+            return None
+
+    with open(os.path.join(fetch_dir, UnicodeFiles.README)) as fd:
+        return parse_readme_unicode_version(fd.read())
+
+
+def parse_readme_unicode_version(readme_content):
+    # type: (str) -> UnicodeVersion
+    """
+    Parse the Unicode version contained in their `ReadMe.txt` file.
+    """
+    # "Raw string" is necessary for \d not being treated as escape char
+    # (for the sake of compat with future Python versions).
+    # See: https://docs.python.org/3.6/whatsnew/3.6.html#deprecated-python-behavior
+    pattern = r"for Version (\d+)\.(\d+)\.(\d+) of the Unicode"
+    groups = re.search(pattern, readme_content).groups()
+
+    return UnicodeVersion(*map(int, groups), as_str=".".join(groups))
+
+
+def get_unicode_dir(unicode_version):
+    # type: (UnicodeVersion) -> str
+    """
+    Indicate in which parent dir the Unicode data files should be stored.
+
+    This returns a full, absolute path.
+    """
+    return os.path.join(FETCH_DIR, unicode_version.as_str)
+
+
+def get_unicode_file_path(unicode_version, filename):
+    # type: (UnicodeVersion, str) -> str
+    """
+    Indicate where the Unicode data file should be stored.
+    """
+    return os.path.join(get_unicode_dir(unicode_version), filename)
 
-    if not os.path.exists(path):
-        sys.stderr.write("cannot load %s" % f)
-        exit(1)
 
 def is_surrogate(n):
-    return surrogate_codepoints[0] <= n <= surrogate_codepoints[1]
-
-def load_unicode_data(f):
-    fetch(f)
-    gencats = {}
-    to_lower = {}
-    to_upper = {}
-    to_title = {}
-    combines = {}
-    canon_decomp = {}
-    compat_decomp = {}
-
-    udict = {}
+    # type: (int) -> bool
+    """
+    Tell if given codepoint is a surrogate (not a valid Rust character).
+    """
+    return SURROGATE_CODEPOINTS_RANGE[0] <= n <= SURROGATE_CODEPOINTS_RANGE[1]
+
+
+def load_unicode_data(file_path):
+    # type: (str) -> UnicodeData
+    """
+    Load main Unicode data.
+    """
+    # Conversions
+    to_lower = {}   # type: Dict[int, Tuple[int, int, int]]
+    to_upper = {}   # type: Dict[int, Tuple[int, int, int]]
+    to_title = {}   # type: Dict[int, Tuple[int, int, int]]
+
+    # Decompositions
+    compat_decomp = {}   # type: Dict[int, List[int]]
+    canon_decomp = {}    # type: Dict[int, List[int]]
+
+    # Combining characters
+    # FIXME: combines are not used
+    combines = defaultdict(set)   # type: Dict[str, Set[int]]
+
+    # Categories
+    general_categories = defaultdict(set)   # type: Dict[str, Set[int]]
+    category_assigned_codepoints = set()    # type: Set[int]
+
+    all_codepoints = {}
+
     range_start = -1
-    for line in fileinput.input(fdir + f):
-        data = line.split(';')
+
+    for line in fileinput.input(file_path):
+        data = line.split(";")
         if len(data) != 15:
             continue
-        cp = int(data[0], 16)
-        if is_surrogate(cp):
+        codepoint = int(data[0], 16)
+        if is_surrogate(codepoint):
             continue
         if range_start >= 0:
-            for i in range(range_start, cp):
-                udict[i] = data
+            for i in range(range_start, codepoint):
+                all_codepoints[i] = data
             range_start = -1
         if data[1].endswith(", First>"):
-            range_start = cp
+            range_start = codepoint
             continue
-        udict[cp] = data
+        all_codepoints[codepoint] = data
 
-    for code in udict:
+    for code, data in all_codepoints.items():
         (code_org, name, gencat, combine, bidi,
          decomp, deci, digit, num, mirror,
-         old, iso, upcase, lowcase, titlecase) = udict[code]
+         old, iso, upcase, lowcase, titlecase) = data
+
+        # Generate char to char direct common and simple conversions:
 
-        # generate char to char direct common and simple conversions
-        # uppercase to lowercase
+        # Uppercase to lowercase
         if lowcase != "" and code_org != lowcase:
             to_lower[code] = (int(lowcase, 16), 0, 0)
 
-        # lowercase to uppercase
+        # Lowercase to uppercase
         if upcase != "" and code_org != upcase:
             to_upper[code] = (int(upcase, 16), 0, 0)
 
-        # title case
+        # Title case
         if titlecase.strip() != "" and code_org != titlecase:
             to_title[code] = (int(titlecase, 16), 0, 0)
 
-        # store decomposition, if given
-        if decomp != "":
-            if decomp.startswith('<'):
-                seq = []
-                for i in decomp.split()[1:]:
-                    seq.append(int(i, 16))
-                compat_decomp[code] = seq
+        # Store decomposition, if given
+        if decomp:
+            decompositions = decomp.split()[1:]
+            decomp_code_points = [int(i, 16) for i in decompositions]
+
+            if decomp.startswith("<"):
+                # Compatibility decomposition
+                compat_decomp[code] = decomp_code_points
             else:
-                seq = []
-                for i in decomp.split():
-                    seq.append(int(i, 16))
-                canon_decomp[code] = seq
-
-        # place letter in categories as appropriate
-        for cat in [gencat, "Assigned"] + expanded_categories.get(gencat, []):
-            if cat not in gencats:
-                gencats[cat] = []
-            gencats[cat].append(code)
-
-        # record combining class, if any
+                # Canonical decomposition
+                canon_decomp[code] = decomp_code_points
+
+        # Place letter in categories as appropriate.
+        for cat in itertools.chain((gencat, ), EXPANDED_CATEGORIES.get(gencat, [])):
+            general_categories[cat].add(code)
+            category_assigned_codepoints.add(code)
+
+        # Record combining class, if any.
         if combine != "0":
-            if combine not in combines:
-                combines[combine] = []
-            combines[combine].append(code)
-
-    # generate Not_Assigned from Assigned
-    gencats["Cn"] = gen_unassigned(gencats["Assigned"])
-    # Assigned is not a real category
-    del(gencats["Assigned"])
+            combines[combine].add(code)
+
+    # Generate Not_Assigned from Assigned.
+    general_categories["Cn"] = get_unassigned_codepoints(category_assigned_codepoints)
+
     # Other contains Not_Assigned
-    gencats["C"].extend(gencats["Cn"])
-    gencats = group_cats(gencats)
-    combines = to_combines(group_cats(combines))
+    general_categories["C"].update(general_categories["Cn"])
+
+    grouped_categories = group_categories(general_categories)
 
-    return (canon_decomp, compat_decomp, gencats, combines, to_upper, to_lower, to_title)
+    # FIXME: combines are not used
+    return UnicodeData(
+        to_lower=to_lower, to_upper=to_upper, to_title=to_title,
+        compat_decomp=compat_decomp, canon_decomp=canon_decomp,
+        general_categories=grouped_categories, combines=combines,
+    )
 
-def load_special_casing(f, to_upper, to_lower, to_title):
-    fetch(f)
-    for line in fileinput.input(fdir + f):
-        data = line.split('#')[0].split(';')
+
+def load_special_casing(file_path, unicode_data):
+    # type: (str, UnicodeData) -> None
+    """
+    Load special casing data and enrich given Unicode data.
+    """
+    for line in fileinput.input(file_path):
+        data = line.split("#")[0].split(";")
         if len(data) == 5:
             code, lower, title, upper, _comment = data
         elif len(data) == 6:
@@ -155,243 +358,399 @@ def load_special_casing(f, to_upper, to_lower, to_title):
         title = title.strip()
         upper = upper.strip()
         key = int(code, 16)
-        for (map_, values) in [(to_lower, lower), (to_upper, upper), (to_title, title)]:
+        for (map_, values) in ((unicode_data.to_lower, lower),
+                               (unicode_data.to_upper, upper),
+                               (unicode_data.to_title, title)):
             if values != code:
-                values = [int(i, 16) for i in values.split()]
-                for _ in range(len(values), 3):
-                    values.append(0)
-                assert len(values) == 3
-                map_[key] = values
-
-def group_cats(cats):
-    cats_out = {}
-    for cat in cats:
-        cats_out[cat] = group_cat(cats[cat])
-    return cats_out
-
-def group_cat(cat):
-    cat_out = []
-    letters = sorted(set(cat))
-    cur_start = letters.pop(0)
-    cur_end = cur_start
-    for letter in letters:
-        assert letter > cur_end, \
-            "cur_end: %s, letter: %s" % (hex(cur_end), hex(letter))
-        if letter == cur_end + 1:
-            cur_end = letter
-        else:
-            cat_out.append((cur_start, cur_end))
-            cur_start = cur_end = letter
-    cat_out.append((cur_start, cur_end))
-    return cat_out
-
-def ungroup_cat(cat):
-    cat_out = []
-    for (lo, hi) in cat:
-        while lo <= hi:
-            cat_out.append(lo)
-            lo += 1
-    return cat_out
-
-def gen_unassigned(assigned):
-    assigned = set(assigned)
-    return ([i for i in range(0, 0xd800) if i not in assigned] +
-            [i for i in range(0xe000, 0x110000) if i not in assigned])
-
-def to_combines(combs):
-    combs_out = []
-    for comb in combs:
-        for (lo, hi) in combs[comb]:
-            combs_out.append((lo, hi, comb))
-    combs_out.sort(key=lambda comb: comb[0])
-    return combs_out
-
-def format_table_content(f, content, indent):
-    line = " "*indent
+                split = values.split()
+
+                codepoints = list(itertools.chain(
+                    (int(i, 16) for i in split),
+                    (0 for _ in range(len(split), 3))
+                ))
+
+                assert len(codepoints) == 3
+                map_[key] = codepoints
+
+
+def group_categories(mapping):
+    # type: (Dict[Any, Iterable[int]]) -> Dict[str, List[Tuple[int, int]]]
+    """
+    Group codepoints mapped in "categories".
+    """
+    return {category: group_codepoints(codepoints)
+            for category, codepoints in mapping.items()}
+
+
+def group_codepoints(codepoints):
+    # type: (Iterable[int]) -> List[Tuple[int, int]]
+    """
+    Group integral values into continuous, disjoint value ranges.
+
+    Performs value deduplication.
+
+    :return: sorted list of pairs denoting start and end of codepoint
+        group values, both ends inclusive.
+
+    >>> group_codepoints([1, 2, 10, 11, 12, 3, 4])
+    [(1, 4), (10, 12)]
+    >>> group_codepoints([1])
+    [(1, 1)]
+    >>> group_codepoints([1, 5, 6])
+    [(1, 1), (5, 6)]
+    >>> group_codepoints([])
+    []
+    """
+    sorted_codes = sorted(set(codepoints))
+    result = []     # type: List[Tuple[int, int]]
+
+    if not sorted_codes:
+        return result
+
+    next_codes = sorted_codes[1:]
+    start_code = sorted_codes[0]
+
+    for code, next_code in zip_longest(sorted_codes, next_codes, fillvalue=None):
+        if next_code is None or next_code - code != 1:
+            result.append((start_code, code))
+            start_code = next_code
+
+    return result
+
+
+def ungroup_codepoints(codepoint_pairs):
+    # type: (Iterable[Tuple[int, int]]) -> List[int]
+    """
+    The inverse of group_codepoints -- produce a flat list of values
+    from value range pairs.
+
+    >>> ungroup_codepoints([(1, 4), (10, 12)])
+    [1, 2, 3, 4, 10, 11, 12]
+    >>> ungroup_codepoints([(1, 1), (5, 6)])
+    [1, 5, 6]
+    >>> ungroup_codepoints(group_codepoints([1, 2, 7, 8]))
+    [1, 2, 7, 8]
+    >>> ungroup_codepoints([])
+    []
+    """
+    return list(itertools.chain.from_iterable(
+        range(lo, hi + 1) for lo, hi in codepoint_pairs
+    ))
+
+
+def get_unassigned_codepoints(assigned_codepoints):
+    # type: (Set[int]) -> Set[int]
+    """
+    Given a set of "assigned" codepoints, return a set
+    of these that are not in assigned and not surrogate.
+    """
+    return {i for i in range(0, 0x110000)
+            if i not in assigned_codepoints and not is_surrogate(i)}
+
+
+def generate_table_lines(items, indent, wrap=98):
+    # type: (Iterable[str], int, int) -> Iterator[str]
+    """
+    Given table items, generate wrapped lines of text with comma-separated items.
+
+    This is a generator function.
+
+    :param wrap: soft wrap limit (characters per line), integer.
+    """
+    line = " " * indent
     first = True
-    for chunk in content.split(","):
-        if len(line) + len(chunk) < 98:
+    for item in items:
+        if len(line) + len(item) < wrap:
             if first:
-                line += chunk
+                line += item
             else:
-                line += ", " + chunk
+                line += ", " + item
             first = False
         else:
-            f.write(line + ",\n")
-            line = " "*indent + chunk
-    f.write(line)
-
-def load_properties(f, interestingprops):
-    fetch(f)
-    props = {}
-    re1 = re.compile("^ *([0-9A-F]+) *; *(\w+)")
-    re2 = re.compile("^ *([0-9A-F]+)\.\.([0-9A-F]+) *; *(\w+)")
-
-    for line in fileinput.input(fdir + os.path.basename(f)):
-        prop = None
-        d_lo = 0
-        d_hi = 0
-        m = re1.match(line)
-        if m:
-            d_lo = m.group(1)
-            d_hi = m.group(1)
-            prop = m.group(2)
-        else:
-            m = re2.match(line)
-            if m:
-                d_lo = m.group(1)
-                d_hi = m.group(2)
-                prop = m.group(3)
+            yield line + ",\n"
+            line = " " * indent + item
+
+    yield line
+
+
+def load_properties(file_path, interesting_props):
+    # type: (str, Iterable[str]) -> Dict[str, List[Tuple[int, int]]]
+    """
+    Load properties data and return in grouped form.
+    """
+    props = defaultdict(list)   # type: Dict[str, List[Tuple[int, int]]]
+    # "Raw string" is necessary for `\.` and `\w` not to be treated as escape chars
+    # (for the sake of compat with future Python versions).
+    # See: https://docs.python.org/3.6/whatsnew/3.6.html#deprecated-python-behavior
+    re1 = re.compile(r"^ *([0-9A-F]+) *; *(\w+)")
+    re2 = re.compile(r"^ *([0-9A-F]+)\.\.([0-9A-F]+) *; *(\w+)")
+
+    for line in fileinput.input(file_path):
+        match = re1.match(line) or re2.match(line)
+        if match:
+            groups = match.groups()
+
+            if len(groups) == 2:
+                # `re1` matched (2 groups).
+                d_lo, prop = groups
+                d_hi = d_lo
             else:
-                continue
-        if interestingprops and prop not in interestingprops:
+                d_lo, d_hi, prop = groups
+        else:
+            continue
+
+        if interesting_props and prop not in interesting_props:
             continue
-        d_lo = int(d_lo, 16)
-        d_hi = int(d_hi, 16)
-        if prop not in props:
-            props[prop] = []
-        props[prop].append((d_lo, d_hi))
 
-    # optimize if possible
+        lo_value = int(d_lo, 16)
+        hi_value = int(d_hi, 16)
+
+        props[prop].append((lo_value, hi_value))
+
+    # Optimize if possible.
     for prop in props:
-        props[prop] = group_cat(ungroup_cat(props[prop]))
+        props[prop] = group_codepoints(ungroup_codepoints(props[prop]))
 
     return props
 
-def escape_char(c):
-    return "'\\u{%x}'" % c if c != 0 else "'\\0'"
 
-def emit_table(f, name, t_data, t_type = "&[(char, char)]", is_pub=True,
-        pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1]))):
+def escape_char(c):
+    # type: (int) -> str
+    r"""
+    Escape a codepoint for use as Rust char literal.
+
+    Outputs are OK to use as Rust source code as char literals
+    and they also include necessary quotes.
+
+    >>> escape_char(97)
+    "'\\u{61}'"
+    >>> escape_char(0)
+    "'\\0'"
+    """
+    return r"'\u{%x}'" % c if c != 0 else r"'\0'"
+
+
+def format_char_pair(pair):
+    # type: (Tuple[int, int]) -> str
+    """
+    Format a pair of two Rust chars.
+    """
+    return "(%s,%s)" % (escape_char(pair[0]), escape_char(pair[1]))
+
+
+def generate_table(
+    name,   # type: str
+    items,  # type: List[Tuple[int, int]]
+    decl_type="&[(char, char)]",    # type: str
+    is_pub=True,                    # type: bool
+    format_item=format_char_pair,   # type: Callable[[Tuple[int, int]], str]
+):
+    # type: (...) -> Iterator[str]
+    """
+    Generate a nicely formatted Rust constant "table" array.
+
+    This generates actual Rust code.
+    """
     pub_string = ""
     if is_pub:
         pub_string = "pub "
-    f.write("    %sconst %s: %s = &[\n" % (pub_string, name, t_type))
-    data = ""
+
+    yield "    %sconst %s: %s = &[\n" % (pub_string, name, decl_type)
+
+    data = []
     first = True
-    for dat in t_data:
+    for item in items:
         if not first:
-            data += ","
+            data.append(",")
         first = False
-        data += pfun(dat)
-    format_table_content(f, data, 8)
-    f.write("\n    ];\n\n")
+        data.extend(format_item(item))
 
-def compute_trie(rawdata, chunksize):
+    for table_line in generate_table_lines("".join(data).split(","), 8):
+        yield table_line
+
+    yield "\n    ];\n\n"
+
+
+def compute_trie(raw_data, chunk_size):
+    # type: (List[int], int) -> Tuple[List[int], List[int]]
+    """
+    Compute postfix-compressed trie.
+
+    See: bool_trie.rs for more details.
+
+    >>> compute_trie([1, 2, 3, 1, 2, 3, 4, 5, 6], 3)
+    ([0, 0, 1], [1, 2, 3, 4, 5, 6])
+    >>> compute_trie([1, 2, 3, 1, 2, 4, 4, 5, 6], 3)
+    ([0, 1, 2], [1, 2, 3, 1, 2, 4, 4, 5, 6])
+    """
     root = []
-    childmap = {}
+    childmap = {}       # type: Dict[Tuple[int, ...], int]
     child_data = []
-    for i in range(len(rawdata) // chunksize):
-        data = rawdata[i * chunksize: (i + 1) * chunksize]
-        child = '|'.join(map(str, data))
+
+    assert len(raw_data) % chunk_size == 0, "Chunks must be equally sized"
+
+    for i in range(len(raw_data) // chunk_size):
+        data = raw_data[i * chunk_size : (i + 1) * chunk_size]
+
+        # Postfix compression of child nodes (data chunks)
+        # (identical child nodes are shared).
+
+        # Make a tuple out of the list so it's hashable.
+        child = tuple(data)
         if child not in childmap:
             childmap[child] = len(childmap)
             child_data.extend(data)
+
         root.append(childmap[child])
-    return (root, child_data)
 
-def emit_bool_trie(f, name, t_data, is_pub=True):
-    CHUNK = 64
+    return root, child_data
+
+
+def generate_bool_trie(name, codepoint_ranges, is_pub=False):
+    # type: (str, List[Tuple[int, int]], bool) -> Iterator[str]
+    """
+    Generate Rust code for BoolTrie struct.
+
+    This yields string fragments that should be joined to produce
+    the final string.
+
+    See: `bool_trie.rs`.
+    """
+    chunk_size = 64
     rawdata = [False] * 0x110000
-    for (lo, hi) in t_data:
+    for (lo, hi) in codepoint_ranges:
         for cp in range(lo, hi + 1):
             rawdata[cp] = True
 
-    # convert to bitmap chunks of 64 bits each
+    # Convert to bitmap chunks of `chunk_size` bits each.
     chunks = []
-    for i in range(0x110000 // CHUNK):
+    for i in range(0x110000 // chunk_size):
         chunk = 0
-        for j in range(64):
-            if rawdata[i * 64 + j]:
+        for j in range(chunk_size):
+            if rawdata[i * chunk_size + j]:
                 chunk |= 1 << j
         chunks.append(chunk)
 
     pub_string = ""
     if is_pub:
         pub_string = "pub "
-    f.write("    %sconst %s: &super::BoolTrie = &super::BoolTrie {\n" % (pub_string, name))
-    f.write("        r1: [\n")
-    data = ','.join('0x%016x' % chunk for chunk in chunks[0:0x800 // CHUNK])
-    format_table_content(f, data, 12)
-    f.write("\n        ],\n")
+    yield "    %sconst %s: &super::BoolTrie = &super::BoolTrie {\n" % (pub_string, name)
+    yield "        r1: [\n"
+    data = ("0x%016x" % chunk for chunk in chunks[:0x800 // chunk_size])
+    for fragment in generate_table_lines(data, 12):
+        yield fragment
+    yield "\n        ],\n"
 
     # 0x800..0x10000 trie
-    (r2, r3) = compute_trie(chunks[0x800 // CHUNK : 0x10000 // CHUNK], 64 // CHUNK)
-    f.write("        r2: [\n")
-    data = ','.join(str(node) for node in r2)
-    format_table_content(f, data, 12)
-    f.write("\n        ],\n")
-    f.write("        r3: &[\n")
-    data = ','.join('0x%016x' % chunk for chunk in r3)
-    format_table_content(f, data, 12)
-    f.write("\n        ],\n")
+    (r2, r3) = compute_trie(chunks[0x800 // chunk_size : 0x10000 // chunk_size], 64 // chunk_size)
+    yield "        r2: [\n"
+    data = map(str, r2)
+    for fragment in generate_table_lines(data, 12):
+        yield fragment
+    yield "\n        ],\n"
+
+    yield "        r3: &[\n"
+    data = ("0x%016x" % node for node in r3)
+    for fragment in generate_table_lines(data, 12):
+        yield fragment
+    yield "\n        ],\n"
 
     # 0x10000..0x110000 trie
-    (mid, r6) = compute_trie(chunks[0x10000 // CHUNK : 0x110000 // CHUNK], 64 // CHUNK)
+    (mid, r6) = compute_trie(chunks[0x10000 // chunk_size : 0x110000 // chunk_size],
+                             64 // chunk_size)
     (r4, r5) = compute_trie(mid, 64)
-    f.write("        r4: [\n")
-    data = ','.join(str(node) for node in r4)
-    format_table_content(f, data, 12)
-    f.write("\n        ],\n")
-    f.write("        r5: &[\n")
-    data = ','.join(str(node) for node in r5)
-    format_table_content(f, data, 12)
-    f.write("\n        ],\n")
-    f.write("        r6: &[\n")
-    data = ','.join('0x%016x' % chunk for chunk in r6)
-    format_table_content(f, data, 12)
-    f.write("\n        ],\n")
-
-    f.write("    };\n\n")
-
-def emit_small_bool_trie(f, name, t_data, is_pub=True):
-    last_chunk = max(hi // 64 for (lo, hi) in t_data)
+
+    yield "        r4: [\n"
+    data = map(str, r4)
+    for fragment in generate_table_lines(data, 12):
+        yield fragment
+    yield "\n        ],\n"
+
+    yield "        r5: &[\n"
+    data = map(str, r5)
+    for fragment in generate_table_lines(data, 12):
+        yield fragment
+    yield "\n        ],\n"
+
+    yield "        r6: &[\n"
+    data = ("0x%016x" % node for node in r6)
+    for fragment in generate_table_lines(data, 12):
+        yield fragment
+    yield "\n        ],\n"
+
+    yield "    };\n\n"
+
+
+def generate_small_bool_trie(name, codepoint_ranges, is_pub=False):
+    # type: (str, List[Tuple[int, int]], bool) -> Iterator[str]
+    """
+    Generate Rust code for `SmallBoolTrie` struct.
+
+    See: `bool_trie.rs`.
+    """
+    last_chunk = max(hi // 64 for (lo, hi) in codepoint_ranges)
     n_chunks = last_chunk + 1
     chunks = [0] * n_chunks
-    for (lo, hi) in t_data:
+    for (lo, hi) in codepoint_ranges:
         for cp in range(lo, hi + 1):
-            if cp // 64 >= len(chunks):
-                print(cp, cp // 64, len(chunks), lo, hi)
+            assert cp // 64 < len(chunks)
             chunks[cp // 64] |= 1 << (cp & 63)
 
     pub_string = ""
     if is_pub:
         pub_string = "pub "
-    f.write("    %sconst %s: &super::SmallBoolTrie = &super::SmallBoolTrie {\n"
-            % (pub_string, name))
+
+    yield ("    %sconst %s: &super::SmallBoolTrie = &super::SmallBoolTrie {\n"
+           % (pub_string, name))
 
     (r1, r2) = compute_trie(chunks, 1)
 
-    f.write("        r1: &[\n")
-    data = ','.join(str(node) for node in r1)
-    format_table_content(f, data, 12)
-    f.write("\n        ],\n")
-
-    f.write("        r2: &[\n")
-    data = ','.join('0x%016x' % node for node in r2)
-    format_table_content(f, data, 12)
-    f.write("\n        ],\n")
-
-    f.write("    };\n\n")
-
-def emit_property_module(f, mod, tbl, emit):
-    f.write("pub mod %s {\n" % mod)
-    for cat in sorted(emit):
-        if cat in ["Cc", "White_Space", "Pattern_White_Space"]:
-            emit_small_bool_trie(f, "%s_table" % cat, tbl[cat])
-            f.write("    pub fn %s(c: char) -> bool {\n" % cat)
-            f.write("        %s_table.lookup(c)\n" % cat)
-            f.write("    }\n\n")
+    yield "        r1: &[\n"
+    data = (str(node) for node in r1)
+    for fragment in generate_table_lines(data, 12):
+        yield fragment
+    yield "\n        ],\n"
+
+    yield "        r2: &[\n"
+    data = ("0x%016x" % node for node in r2)
+    for fragment in generate_table_lines(data, 12):
+        yield fragment
+    yield "\n        ],\n"
+
+    yield "    };\n\n"
+
+
+def generate_property_module(mod, grouped_categories, category_subset):
+    # type: (str, Dict[str, List[Tuple[int, int]]], Iterable[str]) -> Iterator[str]
+    """
+    Generate Rust code for module defining properties.
+    """
+
+    yield "pub(crate) mod %s {\n" % mod
+    for cat in sorted(category_subset):
+        if cat in ("Cc", "White_Space", "Pattern_White_Space"):
+            generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat])
         else:
-            emit_bool_trie(f, "%s_table" % cat, tbl[cat])
-            f.write("    pub fn %s(c: char) -> bool {\n" % cat)
-            f.write("        %s_table.lookup(c)\n" % cat)
-            f.write("    }\n\n")
-    f.write("}\n\n")
-
-def emit_conversions_module(f, to_upper, to_lower, to_title):
-    f.write("pub mod conversions {")
-    f.write("""
+            generator = generate_bool_trie("%s_table" % cat, grouped_categories[cat])
+
+        for fragment in generator:
+            yield fragment
+
+        yield "    pub fn %s(c: char) -> bool {\n" % cat
+        yield "        %s_table.lookup(c)\n" % cat
+        yield "    }\n\n"
+
+    yield "}\n\n"
+
+
+def generate_conversions_module(unicode_data):
+    # type: (UnicodeData) -> Iterator[str]
+    """
+    Generate Rust code for module defining conversions.
+    """
+
+    yield "pub(crate) mod conversions {"
+    yield """
     pub fn to_lower(c: char) -> [char; 3] {
         match bsearch_case_table(c, to_lowercase_table) {
             None        => [c, '\\0', '\\0'],
@@ -408,80 +767,109 @@ def emit_conversions_module(f, to_upper, to_lower, to_title):
 
     fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option<usize> {
         table.binary_search_by(|&(key, _)| key.cmp(&c)).ok()
-    }
+    }\n\n"""
+
+    decl_type = "&[(char, [char; 3])]"
+    format_conversion = lambda x: "({},[{},{},{}])".format(*(
+        escape_char(c) for c in (x[0], x[1][0], x[1][1], x[1][2])
+    ))
+
+    for fragment in generate_table(
+        name="to_lowercase_table",
+        items=sorted(unicode_data.to_lower.items(), key=lambda x: x[0]),
+        decl_type=decl_type,
+        is_pub=False,
+        format_item=format_conversion
+    ):
+        yield fragment
+
+    for fragment in generate_table(
+        name="to_uppercase_table",
+        items=sorted(unicode_data.to_upper.items(), key=lambda x: x[0]),
+        decl_type=decl_type,
+        is_pub=False,
+        format_item=format_conversion
+    ):
+        yield fragment
+
+    yield "}\n"
+
+
+def parse_args():
+    # type: () -> argparse.Namespace
+    """
+    Parse command line arguments.
+    """
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument("-v", "--version", default=None, type=str,
+                        help="Unicode version to use (if not specified,"
+                             " defaults to latest release).")
+
+    return parser.parse_args()
+
+
+def main():
+    # type: () -> None
+    """
+    Script entry point.
+    """
+    args = parse_args()
+
+    unicode_version = fetch_files(args.version)
+    print("Using Unicode version: {}".format(unicode_version.as_str))
+
+    # All the writing happens entirely in memory, we only write to file
+    # once we have generated the file content (it's not very large, <1 MB).
+    buf = StringIO()
+    buf.write(PREAMBLE)
+
+    unicode_version_notice = textwrap.dedent("""
+    /// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of
+    /// `char` and `str` methods are based on.
+    #[unstable(feature = "unicode_version", issue = "49726")]
+    pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {{
+        major: {version.major},
+        minor: {version.minor},
+        micro: {version.micro},
+        _priv: (),
+    }};
+    """).format(version=unicode_version)
+    buf.write(unicode_version_notice)
+
+    get_path = lambda f: get_unicode_file_path(unicode_version, f)
+
+    unicode_data = load_unicode_data(get_path(UnicodeFiles.UNICODE_DATA))
+    load_special_casing(get_path(UnicodeFiles.SPECIAL_CASING), unicode_data)
+
+    want_derived = {"XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase",
+                    "Cased", "Case_Ignorable", "Grapheme_Extend"}
+    derived = load_properties(get_path(UnicodeFiles.DERIVED_CORE_PROPERTIES), want_derived)
+
+    props = load_properties(get_path(UnicodeFiles.PROPS),
+                            {"White_Space", "Join_Control", "Noncharacter_Code_Point",
+                             "Pattern_White_Space"})
+
+    # Category tables
+    for (name, categories, category_subset) in (
+            ("general_category", unicode_data.general_categories, ["N", "Cc"]),
+            ("derived_property", derived, want_derived),
+            ("property", props, ["White_Space", "Pattern_White_Space"])
+    ):
+        for fragment in generate_property_module(name, categories, category_subset):
+            buf.write(fragment)
+
+    for fragment in generate_conversions_module(unicode_data):
+        buf.write(fragment)
+
+    tables_rs_path = os.path.join(THIS_DIR, "tables.rs")
+
+    # Actually write out the file content.
+    # Will overwrite the file if it exists.
+    with open(tables_rs_path, "w") as fd:
+        fd.write(buf.getvalue())
+
+    print("Regenerated tables.rs.")
 
-""")
-    t_type = "&[(char, [char; 3])]"
-    pfun = lambda x: "(%s,[%s,%s,%s])" % (
-        escape_char(x[0]), escape_char(x[1][0]), escape_char(x[1][1]), escape_char(x[1][2]))
-    emit_table(f, "to_lowercase_table",
-        sorted(to_lower.items(), key=operator.itemgetter(0)),
-        is_pub=False, t_type = t_type, pfun=pfun)
-    emit_table(f, "to_uppercase_table",
-        sorted(to_upper.items(), key=operator.itemgetter(0)),
-        is_pub=False, t_type = t_type, pfun=pfun)
-    f.write("}\n\n")
-
-def emit_norm_module(f, canon, compat, combine, norm_props):
-    canon_keys = sorted(canon.keys())
-
-    compat_keys = sorted(compat.keys())
-
-    canon_comp = {}
-    comp_exclusions = norm_props["Full_Composition_Exclusion"]
-    for char in canon_keys:
-        if any(lo <= char <= hi for lo, hi in comp_exclusions):
-            continue
-        decomp = canon[char]
-        if len(decomp) == 2:
-            if decomp[0] not in canon_comp:
-                canon_comp[decomp[0]] = []
-            canon_comp[decomp[0]].append( (decomp[1], char) )
-    canon_comp_keys = sorted(canon_comp.keys())
 
 if __name__ == "__main__":
-    r = fdir + "tables.rs"
-    if os.path.exists(r):
-        os.remove(r)
-    with open(r, "w") as rf:
-        # write the file's preamble
-        rf.write(preamble)
-
-        # download and parse all the data
-        fetch("ReadMe.txt")
-        with open(fdir + "ReadMe.txt") as readme:
-            pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode"
-            unicode_version = re.search(pattern, readme.read()).groups()
-        rf.write("""
-/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of
-/// `char` and `str` methods are based on.
-#[unstable(feature = "unicode_version", issue = "49726")]
-pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {
-    major: %s,
-    minor: %s,
-    micro: %s,
-    _priv: (),
-};
-""" % unicode_version)
-        (canon_decomp, compat_decomp, gencats, combines,
-                to_upper, to_lower, to_title) = load_unicode_data("UnicodeData.txt")
-        load_special_casing("SpecialCasing.txt", to_upper, to_lower, to_title)
-        want_derived = ["XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase",
-                        "Cased", "Case_Ignorable", "Grapheme_Extend"]
-        derived = load_properties("DerivedCoreProperties.txt", want_derived)
-        scripts = load_properties("Scripts.txt", [])
-        props = load_properties("PropList.txt",
-                ["White_Space", "Join_Control", "Noncharacter_Code_Point", "Pattern_White_Space"])
-        norm_props = load_properties("DerivedNormalizationProps.txt",
-                     ["Full_Composition_Exclusion"])
-
-        # category tables
-        for (name, cat, pfuns) in ("general_category", gencats, ["N", "Cc"]), \
-                                  ("derived_property", derived, want_derived), \
-                                  ("property", props, ["White_Space", "Pattern_White_Space"]):
-            emit_property_module(rf, name, cat, pfuns)
-
-        # normalizations and conversions module
-        emit_norm_module(rf, canon_decomp, compat_decomp, combines, norm_props)
-        emit_conversions_module(rf, to_upper, to_lower, to_title)
-    print("Regenerated tables.rs.")
+    main()