about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorBaoshan <pangbw@gmail.com>2019-08-29 09:29:23 -0700
committerGitHub <noreply@github.com>2019-08-29 09:29:23 -0700
commit043c19c69c0beac3696cb82d44476ba4298a6b07 (patch)
tree1813e5dd1e4efd5806f401968b4ed34b8c9c76ac /src/libcore
parentcae6d66d9989857e321e0963142b08b1517dc723 (diff)
parent76f17219c71973fd4a58f2f8020eec4d8f5dcd11 (diff)
downloadrust-043c19c69c0beac3696cb82d44476ba4298a6b07.tar.gz
rust-043c19c69c0beac3696cb82d44476ba4298a6b07.zip
Merge branch 'master' into bpang-runtest
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/any.rs5
-rw-r--r--src/libcore/ascii.rs9
-rw-r--r--src/libcore/char/methods.rs14
-rw-r--r--src/libcore/clone.rs3
-rw-r--r--src/libcore/cmp.rs12
-rw-r--r--src/libcore/default.rs3
-rw-r--r--src/libcore/fmt/builders.rs13
-rw-r--r--src/libcore/fmt/mod.rs4
-rw-r--r--src/libcore/hash/mod.rs6
-rw-r--r--src/libcore/intrinsics.rs22
-rw-r--r--src/libcore/iter/adapters/chain.rs45
-rw-r--r--src/libcore/iter/adapters/flatten.rs86
-rw-r--r--src/libcore/iter/adapters/mod.rs566
-rw-r--r--src/libcore/iter/adapters/zip.rs8
-rw-r--r--src/libcore/iter/sources.rs10
-rw-r--r--src/libcore/iter/traits/accum.rs8
-rw-r--r--src/libcore/iter/traits/double_ended.rs27
-rw-r--r--src/libcore/iter/traits/iterator.rs249
-rw-r--r--src/libcore/lib.rs4
-rw-r--r--src/libcore/macros.rs74
-rw-r--r--src/libcore/marker.rs3
-rw-r--r--src/libcore/mem/maybe_uninit.rs14
-rw-r--r--src/libcore/mem/mod.rs4
-rw-r--r--src/libcore/num/mod.rs48
-rw-r--r--src/libcore/prelude/v1.rs5
-rw-r--r--src/libcore/ptr/unique.rs8
-rw-r--r--src/libcore/slice/mod.rs16
-rw-r--r--src/libcore/task/poll.rs28
-rw-r--r--src/libcore/tests/iter.rs76
-rw-r--r--src/libcore/tests/slice.rs19
30 files changed, 926 insertions, 463 deletions
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index 078091a9b54..e8a0a88f12a 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -470,10 +470,5 @@ impl TypeId {
 #[stable(feature = "type_name", since = "1.38.0")]
 #[rustc_const_unstable(feature = "const_type_name")]
 pub const fn type_name<T: ?Sized>() -> &'static str {
-    #[cfg(bootstrap)]
-    unsafe {
-        intrinsics::type_name::<T>()
-    }
-    #[cfg(not(bootstrap))]
     intrinsics::type_name::<T>()
 }
diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs
index e6a6fdde540..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],
@@ -130,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/char/methods.rs b/src/libcore/char/methods.rs
index aa834db2b9b..e91bf53c5b4 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -553,12 +553,7 @@ impl char {
     /// `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`.
-    #[cfg_attr(bootstrap,
-               unstable(feature = "rustc_private",
-                        reason = "mainly needed for compiler internals",
-                        issue = "27812"))]
-    #[cfg_attr(not(bootstrap),
-               unstable(feature = "unicode_internals", issue = "0"))]
+    #[unstable(feature = "unicode_internals", issue = "0")]
     pub fn is_xid_start(self) -> bool {
         derived_property::XID_Start(self)
     }
@@ -569,12 +564,7 @@ impl char {
     /// `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.
-    #[cfg_attr(bootstrap,
-               unstable(feature = "rustc_private",
-                        reason = "mainly needed for compiler internals",
-                        issue = "27812"))]
-    #[cfg_attr(not(bootstrap),
-               unstable(feature = "unicode_internals", issue = "0"))]
+    #[unstable(feature = "unicode_internals", issue = "0")]
     #[inline]
     pub fn is_xid_continue(self) -> bool {
         derived_property::XID_Continue(self)
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index 0c99356390b..ec70d396e96 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -134,9 +134,8 @@ pub trait Clone : Sized {
 }
 
 /// Derive macro generating an impl of the trait `Clone`.
-#[cfg(not(bootstrap))]
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[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 */ }
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 38a52d97da2..cb9feb074dd 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -201,9 +201,8 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
 }
 
 /// Derive macro generating an impl of the trait `PartialEq`.
-#[cfg(not(bootstrap))]
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[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 */ }
@@ -265,9 +264,8 @@ pub trait Eq: PartialEq<Self> {
 }
 
 /// Derive macro generating an impl of the trait `Eq`.
-#[cfg(not(bootstrap))]
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[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 */ }
@@ -617,9 +615,8 @@ pub trait Ord: Eq + PartialOrd<Self> {
 }
 
 /// Derive macro generating an impl of the trait `Ord`.
-#[cfg(not(bootstrap))]
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[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 */ }
@@ -867,9 +864,8 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
 }
 
 /// Derive macro generating an impl of the trait `PartialOrd`.
-#[cfg(not(bootstrap))]
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[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 */ }
diff --git a/src/libcore/default.rs b/src/libcore/default.rs
index 8d95e9de158..66acc5165fc 100644
--- a/src/libcore/default.rs
+++ b/src/libcore/default.rs
@@ -116,9 +116,8 @@ pub trait Default: Sized {
 }
 
 /// Derive macro generating an impl of the trait `Default`.
-#[cfg(not(bootstrap))]
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[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 */ }
diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs
index cb4e32622ff..15ce2277fa0 100644
--- a/src/libcore/fmt/builders.rs
+++ b/src/libcore/fmt/builders.rs
@@ -98,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);
@@ -251,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,
@@ -418,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 {
@@ -555,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 {
@@ -697,7 +700,7 @@ pub struct DebugMap<'a, 'b: 'a> {
     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,
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 0ea01d4b84a..bd31d25dd03 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -546,16 +546,14 @@ pub trait Debug {
 }
 
 // Separate module to reexport the macro `Debug` from prelude without the trait `Debug`.
-#[cfg(not(bootstrap))]
 pub(crate) mod macros {
     /// Derive macro generating an impl of the trait `Debug`.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[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 */ }
 }
-#[cfg(not(bootstrap))]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[doc(inline)]
 pub use macros::Debug;
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index c4cbf40a93a..bf3daa32840 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -199,16 +199,14 @@ pub trait Hash {
 }
 
 // Separate module to reexport the macro `Hash` from prelude without the trait `Hash`.
-#[cfg(not(bootstrap))]
 pub(crate) mod macros {
     /// Derive macro generating an impl of the trait `Hash`.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[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 */ }
 }
-#[cfg(not(bootstrap))]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[doc(inline)]
 pub use macros::Hash;
@@ -553,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;
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index ceaa870d2b3..d145f2212f9 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1293,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,
diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs
index 76239ebc0ab..c9612596b1b 100644
--- a/src/libcore/iter/adapters/chain.rs
+++ b/src/libcore/iter/adapters/chain.rs
@@ -173,17 +173,23 @@ impl<A, B> Iterator for Chain<A, B> where
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let (a_lower, a_upper) = self.a.size_hint();
-        let (b_lower, b_upper) = self.b.size_hint();
+        match self.state {
+            ChainState::Both => {
+                let (a_lower, a_upper) = self.a.size_hint();
+                let (b_lower, b_upper) = self.b.size_hint();
 
-        let lower = a_lower.saturating_add(b_lower);
+                let lower = a_lower.saturating_add(b_lower);
 
-        let upper = match (a_upper, b_upper) {
-            (Some(x), Some(y)) => x.checked_add(y),
-            _ => None
-        };
+                let upper = match (a_upper, b_upper) {
+                    (Some(x), Some(y)) => x.checked_add(y),
+                    _ => None
+                };
 
-        (lower, upper)
+                (lower, upper)
+            }
+            ChainState::Front => self.a.size_hint(),
+            ChainState::Back => self.b.size_hint(),
+        }
     }
 }
 
@@ -207,6 +213,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 d8d41a2a31e..a45173f614d 100644
--- a/src/libcore/iter/adapters/flatten.rs
+++ b/src/libcore/iter/adapters/flatten.rs
@@ -72,8 +72,7 @@ impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
 impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
 where
     F: FnMut(I::Item) -> U,
-    U: IntoIterator,
-    U::IntoIter: DoubleEndedIterator,
+    U: IntoIterator<IntoIter: DoubleEndedIterator>,
 {
     #[inline]
     fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
@@ -107,10 +106,7 @@ 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>,
 }
 
@@ -229,7 +225,7 @@ where
                 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()),
             }
         }
@@ -237,8 +233,8 @@ where
 
     #[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)),
@@ -250,20 +246,25 @@ where
     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 {
@@ -275,13 +276,20 @@ where
     }
 
     #[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))
     }
 }
 
@@ -297,7 +305,7 @@ where
                 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),
             }
         }
@@ -307,22 +315,29 @@ where
     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)?;
         }
@@ -332,12 +347,19 @@ where
     }
 
     #[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 b2702902956..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;
 
@@ -143,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
@@ -157,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))
     }
 }
 
@@ -178,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))
     }
 }
 
@@ -248,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
@@ -262,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)
     }
 }
 
@@ -283,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)
     }
 }
 
@@ -387,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")]
@@ -430,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))
         }
     }
 
@@ -594,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;
@@ -608,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))
     }
 }
 
@@ -632,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))
     }
 }
 
@@ -710,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]
@@ -738,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))
     }
 }
 
@@ -773,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))
     }
 }
 
@@ -834,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>,
@@ -842,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]
@@ -852,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))
     }
 }
 
@@ -880,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))
     }
 }
 
@@ -944,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]
@@ -960,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]
@@ -975,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))
     }
 }
 
@@ -1007,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))
     }
 }
 
@@ -1162,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)
     }
 
@@ -1321,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]
@@ -1412,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
+            }
         }
     }
 
@@ -1434,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()
         }
     }
 }
@@ -1534,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)
     }
@@ -1595,19 +1718,26 @@ 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
+    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()
         }
     }
 }
@@ -1682,19 +1812,26 @@ 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()
         }
     }
 }
@@ -1793,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]
@@ -1803,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()
     }
 }
 
@@ -2104,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;
@@ -2120,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))
     }
 }
 
@@ -2147,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))
     }
 }
 
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/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 812463e77f9..818f0330329 100644
--- a/src/libcore/iter/traits/accum.rs
+++ b/src/libcore/iter/traits/accum.rs
@@ -85,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)
             }
         }
     )*)
diff --git a/src/libcore/iter/traits/double_ended.rs b/src/libcore/iter/traits/double_ended.rs
index 2c1aeb5690a..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
@@ -219,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.
@@ -271,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 7e941267ce8..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,7 +267,12 @@ pub trait Iterator {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn last(self) -> Option<Self::Item> where Self: Sized {
-        self.fold(None, |_, x| Some(x))
+        #[inline]
+        fn some<T>(_: Option<T>, x: T) -> Option<T> {
+            Some(x)
+        }
+
+        self.fold(None, some)
     }
 
     /// Returns the `n`th element of the iterator.
@@ -596,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
@@ -1490,21 +1504,30 @@ pub trait Iterator {
     /// 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();
 
-        self.for_each(|x| {
-            if f(&x) {
-                left.extend(Some(x))
-            } else {
-                right.extend(Some(x))
-            }
-        });
+        self.for_each(extend(f, &mut left, &mut right));
 
         (left, right)
     }
@@ -1702,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.
@@ -1777,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.
@@ -1822,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.
@@ -1870,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.
@@ -1924,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
@@ -1951,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.
@@ -2018,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
@@ -2071,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.
@@ -2151,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
@@ -2174,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
@@ -2195,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
@@ -2219,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))
     }
 
 
@@ -2284,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)
     }
@@ -2617,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.
@@ -2639,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;
@@ -2687,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 678ff768792..c168d5c8a2e 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -63,7 +63,7 @@
 #![warn(missing_debug_implementations)]
 #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings
 #![allow(explicit_outlives_requirements)]
-#![cfg_attr(not(bootstrap), allow(incomplete_features))]
+#![allow(incomplete_features)]
 
 #![feature(allow_internal_unstable)]
 #![feature(arbitrary_self_types)]
@@ -129,7 +129,7 @@
 #![feature(structural_match)]
 #![feature(abi_unadjusted)]
 #![feature(adx_target_feature)]
-#![feature(maybe_uninit_slice, maybe_uninit_array)]
+#![feature(maybe_uninit_slice)]
 #![feature(external_doc)]
 #![feature(mem_take)]
 #![feature(associated_type_bounds)]
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index f9dc53874ac..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 {
     () => (
         $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,) => (
         $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!()))
     });
 }
 
@@ -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)+))
                 }
             }
         }
@@ -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)+))
                 }
             }
         }
@@ -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.
@@ -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) { $crate::assert_eq!($($arg)*); })
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_eq!($($arg)*); })
 }
 
 /// Asserts that two expressions are not equal to each other.
@@ -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) { $crate::assert_ne!($($arg)*); })
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
 }
 
 /// Unwraps a result or propagates its error.
@@ -386,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.
@@ -446,7 +446,7 @@ macro_rules! writeln {
         $crate::writeln!($dst)
     );
     ($dst:expr, $($arg:tt)*) => (
-        $dst.write_fmt(format_args_nl!($($arg)*))
+        $dst.write_fmt($crate::format_args_nl!($($arg)*))
     );
 }
 
@@ -515,7 +515,7 @@ macro_rules! unreachable {
         $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)*)
     });
 }
 
@@ -573,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.
@@ -632,41 +632,7 @@ 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)+)));
-}
-
-/// Creates an array of [`MaybeUninit`].
-///
-/// This macro constructs an uninitialized array of the type `[MaybeUninit<K>; N]`.
-/// It exists solely because bootstrap does not yet support const array-init expressions.
-///
-/// [`MaybeUninit`]: mem/union.MaybeUninit.html
-// FIXME: Remove both versions of this macro once bootstrap is 1.38.
-#[macro_export]
-#[unstable(feature = "maybe_uninit_array", issue = "53491")]
-#[cfg(bootstrap)]
-macro_rules! uninit_array {
-    // This `assume_init` is safe because an array of `MaybeUninit` does not
-    // require initialization.
-    ($t:ty; $size:expr) => (unsafe {
-        MaybeUninit::<[MaybeUninit<$t>; $size]>::uninit().assume_init()
-    });
-}
-
-/// Creates an array of [`MaybeUninit`].
-///
-/// This macro constructs an uninitialized array of the type `[MaybeUninit<K>; N]`.
-/// It exists solely because bootstrap does not yet support const array-init expressions.
-///
-/// [`MaybeUninit`]: mem/union.MaybeUninit.html
-// FIXME: Just inline this version of the macro once bootstrap is 1.38.
-#[macro_export]
-#[unstable(feature = "maybe_uninit_array", issue = "53491")]
-#[cfg(not(bootstrap))]
-macro_rules! uninit_array {
-    ($t:ty; $size:expr) => (
-        [MaybeUninit::<$t>::UNINIT; $size]
-    );
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
 }
 
 /// Definitions of built-in macros.
@@ -674,7 +640,6 @@ macro_rules! uninit_array {
 /// 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.
-#[cfg(not(bootstrap))]
 pub(crate) mod builtin {
 
     /// Causes compilation to fail with the given error message when encountered.
@@ -962,13 +927,6 @@ pub(crate) mod builtin {
     #[macro_export]
     macro_rules! column { () => { /* compiler built-in */ } }
 
-    /// Same as `column`, but less likely to be shadowed.
-    #[unstable(feature = "__rust_unstable_column", issue = "0",
-               reason = "internal implementation detail of the `panic` macro")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! __rust_unstable_column { () => { /* compiler built-in */ } }
-
     /// Expands to the file name in which it was invoked.
     ///
     /// With [`line!`] and [`column!`], these macros provide debugging information for
@@ -1305,14 +1263,14 @@ pub(crate) mod builtin {
 
     /// Unstable implementation detail of the `rustc` compiler, do not use.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[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]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[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 78a27361165..89af2528c05 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -289,9 +289,8 @@ pub trait Copy : Clone {
 }
 
 /// Derive macro generating an impl of the trait `Copy`.
-#[cfg(not(bootstrap))]
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[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 */ }
diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs
index 1bbea02e0c7..9e9e901c76d 100644
--- a/src/libcore/mem/maybe_uninit.rs
+++ b/src/libcore/mem/maybe_uninit.rs
@@ -213,7 +213,7 @@ use crate::mem::ManuallyDrop;
 #[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.
-#[cfg_attr(not(bootstrap), lang = "maybe_uninit")]
+#[lang = "maybe_uninit"]
 #[derive(Copy)]
 #[repr(transparent)]
 pub union MaybeUninit<T> {
@@ -312,7 +312,7 @@ impl<T> MaybeUninit<T> {
     /// 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 = "53491")]
+    #[unstable(feature = "maybe_uninit_extra", issue = "63567")]
     #[inline(always)]
     pub fn write(&mut self, val: T) -> &mut T {
         unsafe {
@@ -502,7 +502,7 @@ impl<T> MaybeUninit<T> {
     /// // 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 = "53491")]
+    #[unstable(feature = "maybe_uninit_extra", issue = "63567")]
     #[inline(always)]
     pub unsafe fn read(&self) -> T {
         intrinsics::panic_if_uninhabited::<T>();
@@ -516,7 +516,7 @@ impl<T> MaybeUninit<T> {
     /// 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")]
+    #[unstable(feature = "maybe_uninit_ref", issue = "63568")]
     #[inline(always)]
     pub unsafe fn get_ref(&self) -> &T {
         &*self.value
@@ -532,21 +532,21 @@ impl<T> MaybeUninit<T> {
     // 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")]
+    #[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 = "53491")]
+    #[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 = "53491")]
+    #[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
index 2534400b833..87ec05a243d 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -453,7 +453,7 @@ pub const fn needs_drop<T>() -> bool {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(bootstrap, allow(deprecated_in_future))]
+#[allow(deprecated_in_future)]
 #[allow(deprecated)]
 pub unsafe fn zeroed<T>() -> T {
     intrinsics::panic_if_uninhabited::<T>();
@@ -481,7 +481,7 @@ pub unsafe fn zeroed<T>() -> T {
 #[inline]
 #[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(bootstrap, allow(deprecated_in_future))]
+#[allow(deprecated_in_future)]
 #[allow(deprecated)]
 pub unsafe fn uninitialized<T>() -> T {
     intrinsics::panic_if_uninhabited::<T>();
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 67e30e7ffcb..b46e06f8d8a 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1112,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)
+                }
             }
         }
 
@@ -1135,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)
+                }
             }
         }
 
@@ -1157,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)
+                }
             }
         }
 
@@ -3031,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)
+                }
             }
         }
 
@@ -3053,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)
+                }
             }
         }
 
@@ -3076,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! {
diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs
index 84cf85f339c..7cc279a9ef2 100644
--- a/src/libcore/prelude/v1.rs
+++ b/src/libcore/prelude/v1.rs
@@ -46,20 +46,16 @@ pub use crate::option::Option::{self, Some, None};
 pub use crate::result::Result::{self, Ok, Err};
 
 // Re-exported built-in macros
-#[cfg(not(bootstrap))]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[doc(no_inline)]
 pub use crate::fmt::macros::Debug;
-#[cfg(not(bootstrap))]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[doc(no_inline)]
 pub use crate::hash::macros::Hash;
 
-#[cfg(not(bootstrap))]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[doc(no_inline)]
 pub use crate::{
-    __rust_unstable_column,
     asm,
     assert,
     cfg,
@@ -83,7 +79,6 @@ pub use crate::{
     trace_macros,
 };
 
-#[cfg(not(bootstrap))]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow(deprecated)]
 #[doc(no_inline)]
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
index f0d011fe6b2..3521dd79979 100644
--- a/src/libcore/ptr/unique.rs
+++ b/src/libcore/ptr/unique.rs
@@ -122,6 +122,14 @@ impl<T: ?Sized> Unique<T> {
     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")]
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index ce5af13d4ca..bfbbb15c8d4 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -4637,6 +4637,22 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'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 = start + self.chunk_size;
+            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 = "chunks_exact", since = "1.31.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/tests/iter.rs b/src/libcore/tests/iter.rs
index 3615fab7915..3a4f76852a0 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];
@@ -137,6 +153,54 @@ fn test_iterator_chain_find() {
 }
 
 #[test]
+fn test_iterator_chain_size_hint() {
+    struct Iter {
+        is_empty: bool,
+    }
+
+    impl Iterator for Iter {
+        type Item = ();
+
+        // alternates between `None` and `Some(())`
+        fn next(&mut self) -> Option<Self::Item> {
+            if self.is_empty {
+                self.is_empty = false;
+                None
+            } else {
+                self.is_empty = true;
+                Some(())
+            }
+        }
+
+        fn size_hint(&self) -> (usize, Option<usize>) {
+            if self.is_empty {
+                (0, Some(0))
+            } else {
+                (1, Some(1))
+            }
+        }
+    }
+
+    impl DoubleEndedIterator for Iter {
+        fn next_back(&mut self) -> Option<Self::Item> {
+            self.next()
+        }
+    }
+
+    // this chains an iterator of length 0 with an iterator of length 1,
+    // so after calling `.next()` once, the iterator is empty and the
+    // state is `ChainState::Back`. `.size_hint()` should now disregard
+    // the size hint of the left iterator
+    let mut iter = Iter { is_empty: true }.chain(once(()));
+    assert_eq!(iter.next(), Some(()));
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+
+    let mut iter = once(()).chain(Iter { is_empty: true });
+    assert_eq!(iter.next_back(), Some(()));
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+}
+
+#[test]
 fn test_zip_nth() {
     let xs = [0, 1, 2, 4, 5];
     let ys = [10, 11, 12];
@@ -1136,6 +1200,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]
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index 4790152512a..6609bc3135a 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -375,6 +375,25 @@ fn test_chunks_exact_mut_nth() {
 }
 
 #[test]
+fn test_chunks_exact_mut_nth_back() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let mut c = v.chunks_exact_mut(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[0, 1]);
+    assert_eq!(c.next(), None);
+
+    let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let mut c2 = v2.chunks_exact_mut(3);
+    assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]);
+    assert_eq!(c2.next(), None);
+    assert_eq!(c2.next_back(), None);
+
+    let v3: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let mut c3 = v3.chunks_exact_mut(10);
+    assert_eq!(c3.nth_back(0), None);
+}
+
+#[test]
 fn test_chunks_exact_mut_last() {
     let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
     let c = v.chunks_exact_mut(2);